Browse code

Add implementation

Robert Cranston authored on 27/03/2022 20:08:32
Showing 2 changed files

... ...
@@ -2,8 +2,17 @@
2 2
 
3 3
 Dump commented `user.js` from [`firefox-profilemaker`][].
4 4
 
5
+This tool downloads files directly from the GitHub repository, parses them, and
6
+prints the **default** config, with grouping and comments. Note that, to reduce
7
+clutter, the "Addons" and "Enterprise Policies" categories are ignored.
8
+
9
+[ffprofile.com][] (operated by the authors of [`firefox-profilemaker`][])
10
+provides a more flexible web-based interface, but does not include grouping or
11
+comments in the final output.
12
+
5 13
 [`firefox-profilemaker-dump`]: https://git.rcrnstn.net/rcrnstn/firefox-profilemaker-dump
6 14
 [`firefox-profilemaker`]: https://github.com/allo-/firefox-profilemaker
15
+[ffprofile.com]: https://ffprofile.com
7 16
 
8 17
 ## License
9 18
 
10 19
new file mode 100755
... ...
@@ -0,0 +1,76 @@
1
+#!/usr/bin/env python3
2
+
3
+
4
+import os
5
+import urllib.request
6
+import json
7
+import html.parser
8
+import textwrap
9
+
10
+
11
+BASE_URL     = 'https://raw.githubusercontent.com/allo-/firefox-profilemaker'
12
+BRANCH_URL   = f'{BASE_URL}/master'
13
+PROFILES_URL = f'{BRANCH_URL}/profiles'
14
+SETTINGS_URL = f'{BRANCH_URL}/settings'
15
+PROFILE_URL  = f'{PROFILES_URL}/01_default.json'
16
+IGNORE       = ['Addons', 'Enterprise Policies']
17
+COMMENT      = '// '
18
+
19
+
20
+def get(url):
21
+    with urllib.request.urlopen(url) as response:
22
+        return json.loads(response.read())
23
+
24
+
25
+def parse(input, wrap=False):
26
+    output = ''
27
+    def parser_handle_data(data):
28
+        nonlocal output
29
+        output += data
30
+    parser = html.parser.HTMLParser()
31
+    parser.handle_data = parser_handle_data
32
+    parser.feed(input)
33
+    if wrap:
34
+        output = textwrap.fill(
35
+            output,
36
+            width=79-len(COMMENT),
37
+            subsequent_indent=COMMENT,
38
+        )
39
+    return output
40
+
41
+
42
+paragraphs = []
43
+name = os.path.basename(BASE_URL)
44
+paragraphs.append(f'/// {name}')
45
+for category, settings_files in get(f'{PROFILE_URL}')[1].items():
46
+    if category in IGNORE:
47
+        continue
48
+    paragraphs.append(f'//// {category}')
49
+    for settings_file in settings_files:
50
+        for settings in get(f'{SETTINGS_URL}/{settings_file}'):
51
+            lines = []
52
+            label     = settings.get('label')
53
+            help_text = settings.get('help_text')
54
+            choices   = settings.get('choices')
55
+            initial   = settings.get('initial')
56
+            setting   = settings.get('setting')
57
+            config    = settings.get('config')
58
+            comment = '' if initial or choices else COMMENT
59
+            if label:
60
+                label = parse(label)
61
+                lines.append(f'///// {label}')
62
+            if help_text:
63
+                help_text = parse(help_text, True)
64
+                lines.append(f'// {help_text}')
65
+            if choices:
66
+                config = config[initial]
67
+                choice = parse(choices[initial], True)
68
+                lines.append(f'// {choice}')
69
+            if setting:
70
+                config = {setting: initial}
71
+            if config:
72
+                for key, value in config.items():
73
+                    key, value = map(json.dumps, [key, value])
74
+                    lines.append(f'{comment}user_pref({key}, {value});')
75
+            paragraphs.append('\n'.join(lines))
76
+print('\n\n'.join(paragraphs))