... | ... |
@@ -2,11 +2,51 @@ |
2 | 2 |
|
3 | 3 |
An [Ansible][] [role][] for installing [Firefox][] [extension][]s. |
4 | 4 |
|
5 |
+Takes a list of extension [slug][]s (the part after |
|
6 |
+`https://addons.mozilla.org/en-US/firefox/addon/`) and downloads and places the |
|
7 |
+extensions in the `extensions` directory in the default profile (a subdirectory |
|
8 |
+of `$HOME/.mozilla/firefox/`). |
|
9 |
+ |
|
10 |
+Note that, unless `extensions.autoDisableScopes` is set to an appropriate value |
|
11 |
+in `user.js`, extensions have to be enabled manually (e.g. from "Extensions" in |
|
12 |
+`about:addons`). |
|
13 |
+ |
|
5 | 14 |
[`ansible-role-firefox-extensions`]: https://git.rcrnstn.net/rcrnstn/ansible-role-firefox-extensions |
6 | 15 |
[Ansible]: https://docs.ansible.com/ansible |
7 | 16 |
[role]: https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html |
8 | 17 |
[Firefox]: https://en.wikipedia.org/wiki/Firefox |
9 | 18 |
[extension]: https://en.wikipedia.org/wiki/Firefox#Browser_extensions |
19 |
+[slug]: https://en.wikipedia.org/wiki/Clean_URL#Slug |
|
20 |
+ |
|
21 |
+## Usage |
|
22 |
+ |
|
23 |
+Example [`requirements.yml`][]: |
|
24 |
+ |
|
25 |
+```yaml |
|
26 |
+--- |
|
27 |
+ |
|
28 |
+roles: |
|
29 |
+ - name: 'firefox-extensions' |
|
30 |
+ src: 'https://git.rcrnstn.net/rcrnstn/ansible-firefox-extensions' |
|
31 |
+ scm: 'git' |
|
32 |
+``` |
|
33 |
+ |
|
34 |
+Example [playbook][]: |
|
35 |
+ |
|
36 |
+```yaml |
|
37 |
+--- |
|
38 |
+ |
|
39 |
+- hosts: 'all' |
|
40 |
+ roles: |
|
41 |
+ - role: 'firefox-extensions' |
|
42 |
+ firefox_extensions: |
|
43 |
+ - 'ublock-origin' |
|
44 |
+ - 'old-reddit-redirect' |
|
45 |
+ - 'tridactyl-vim' |
|
46 |
+``` |
|
47 |
+ |
|
48 |
+[`requirements.yml`]: https://docs.ansible.com/ansible/latest/galaxy/user_guide.html#installing-multiple-roles-from-a-file |
|
49 |
+[playbook]: https://docs.ansible.com/ansible/latest/user_guide/playbooks.html |
|
10 | 50 |
|
11 | 51 |
## License |
12 | 52 |
|
13 | 53 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,39 @@ |
1 |
+#!/usr/bin/env python3 |
|
2 |
+ |
|
3 |
+ |
|
4 |
+import os |
|
5 |
+import sys |
|
6 |
+import configparser |
|
7 |
+import urllib.request |
|
8 |
+import json |
|
9 |
+ |
|
10 |
+ |
|
11 |
+FIREFOX_PATH = os.path.expanduser('~/.mozilla/firefox') |
|
12 |
+PROFILES_PATH = os.path.join(FIREFOX_PATH, 'profiles.ini') |
|
13 |
+API_BASE_URL = 'https://services.addons.mozilla.org/api/v4/addons/addon' |
|
14 |
+ |
|
15 |
+ |
|
16 |
+extension = sys.argv[1] |
|
17 |
+ |
|
18 |
+ |
|
19 |
+profiles = configparser.ConfigParser() |
|
20 |
+profiles.optionxform = str |
|
21 |
+profiles.read(PROFILES_PATH) |
|
22 |
+for section in profiles.sections(): |
|
23 |
+ if section.startswith('Profile'): |
|
24 |
+ profile = dict(profiles.items(section)) |
|
25 |
+ if int(profile['Default']): |
|
26 |
+ profile_path = profile['Path'] |
|
27 |
+ if int(profile.get('IsRelative', '0')): |
|
28 |
+ profile_path = os.path.join(FIREFOX_PATH, profile_path) |
|
29 |
+ |
|
30 |
+ |
|
31 |
+with urllib.request.urlopen(f'{API_BASE_URL}/{extension}') as response: |
|
32 |
+ info = json.loads(response.read()) |
|
33 |
+guid = info['guid'] |
|
34 |
+url = info['current_version']['files'][0]['url'] |
|
35 |
+path = os.path.join(profile_path, 'extensions', f'{guid}.xpi') |
|
36 |
+os.makedirs(os.path.dirname(path), exist_ok=True) |
|
37 |
+if not os.path.exists(path): |
|
38 |
+ urllib.request.urlretrieve(url, path) |
|
39 |
+ print(extension) |