-
Notifications
You must be signed in to change notification settings - Fork 11
/
firefox-addons.py
executable file
·110 lines (90 loc) · 3.06 KB
/
firefox-addons.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/env python3
# 2017, Georg Sauthoff <[email protected]>, GPLv3+
import argparse
import csv
import glob
import json
import logging
import os
import requests
import sys
def setup_logging():
log_format = '%(levelname)-8s - %(message)s'
logging.basicConfig(format=log_format, level=logging.INFO)
log = logging.getLogger(__name__)
def mk_arg_parser():
p = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description='List installed Firefox addons',
epilog='''Examples:
Generate the list of installed addons:
$ ./firefox-addons.py -o addons.csv
Open all addon pages in a Firefox window (e.g. for bulk installation):
$ cut -f1 -d, addon.csv | tail -n +2 | xargs firefox
2017, Georg Sauthoff <[email protected]>, GPLv3+''')
p.add_argument('--profile',
metavar='DIRECTORY', help='Specify the default directory (default: use the newestet one unter ~/.mozilla/firefox that ends in .default')
p.add_argument('--output', '-o', default='addon.csv',
metavar='CSVFILE', help='information about the installed addons (default: addon.csv)')
return p
def base():
return os.environ['HOME'] + '/.mozilla/firefox'
def default_profile():
b = base()
return max(
( (fn, os.stat(fn).st_mtime)
for fn in glob.glob(b + '/*.default') ),
key=lambda x: x[1])[0]
def parse_args(*a):
arg_parser = mk_arg_parser()
args = arg_parser.parse_args(*a)
if not args.profile:
args.profile = default_profile()
log.info('Using profile: {}'.format(args.profile))
return args
def args_exts(profile):
a = json.load(open(profile + '/addons.json'))
a = a['addons']
a.sort(key=lambda x:x['reviewURL'])
e = json.load(open(profile + '/extensions.json'))
e = e['addons']
e = dict((x['id'], x) for x in e)
return (a, e)
# cf. http://addons-server.readthedocs.io/en/latest/topics/api/addons.html#detail
def details(slug, session):
r = session.get('https://addons.mozilla.org//api/v3/addons/addon/{}/'
.format(slug))
r.raise_for_status()
d = json.loads(r.text)
return d
def run(args):
session = requests.Session()
addons, exts = args_exts(args.profile)
with open(args.output, 'w', newline='') as f:
w = csv.writer(f, lineterminator=os.linesep)
w.writerow(['mozilla_url', 'slug', 'guid', 'name',
'compatible_android', 'url' ])
for a in addons:
if a['id'] not in exts or not exts[a['id']]['active']:
continue
mozilla_url = a['reviewURL']
if mozilla_url.endswith('reviews/'):
mozilla_url = mozilla_url[:-8]
slug = mozilla_url.split('/')[-2]
guid = a['id']
d = details(slug, session)
compatible_android = str(
'android' in d['current_version']['compatibility']).lower()
url = a['homepageURL']
if url:
url = url.replace('?src=api', '')
w.writerow([ mozilla_url, slug, guid, a['name'],
compatible_android, url ])
def imain(*argv):
args = parse_args(*argv)
return run(args)
def main(*argv):
setup_logging()
return imain(*argv)
if __name__ == '__main__':
sys.exit(main())