Browse code

Add implementation

Robert Cranston authored on 26/03/2022 11:46:59
Showing 3 changed files

... ...
@@ -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)
0 40
new file mode 100644
... ...
@@ -0,0 +1,7 @@
1
+---
2
+
3
+- name: 'Install Firefox extensions'
4
+  script: 'install {{ item | quote }}'
5
+  register: result
6
+  changed_when: result.stdout != ''
7
+  loop: '{{ firefox_extensions }}'