yet another format change
[web/firmware-selector-openwrt-org.git] / misc / collect.py
1 #!/usr/bin/env python3
2
3 from pathlib import Path
4 import argparse
5 import json
6 import sys
7 import os
8
9 parser = argparse.ArgumentParser()
10 parser.add_argument("input_path", nargs='?', help="Input folder that is traversed for OpenWrt JSON device files.")
11 parser.add_argument('--link',
12 action="store", dest="link", default="",
13 help="Link to get the image from. May contain %%file, %%target, %%release and %%commit")
14 parser.add_argument('--include', nargs='+', default=[],
15 action="store", dest="include", help="Include releases from other JSON files.")
16 parser.add_argument('--formatted',
17 action="store_true", dest="formatted", help="Output formatted JSON data.")
18
19 args = parser.parse_args()
20
21 SUPPORTED_METADATA_VERSION = 1
22
23
24 # OpenWrt JSON device files
25 paths = []
26
27 if args.input_path:
28 if not os.path.isdir(args.input_path):
29 sys.stderr.write("Folder does not exists: {}\n".format(args.input_path))
30 exit(1)
31
32 for path in Path(args.input_path).rglob('*.json'):
33 paths.append(path)
34
35 # json output data
36 output = {}
37 for path in paths:
38 with open(path, "r") as file:
39 try:
40 obj = json.load(file)
41
42 if obj['metadata_version'] != SUPPORTED_METADATA_VERSION:
43 sys.stderr.write('{} has unsupported metadata version: {} => skip\n'.format(path, obj['metadata_version']))
44 continue
45
46 version = obj['version_number']
47 commit = obj['version_commit']
48
49 if not version in output:
50 output[version] = {
51 'commit': commit,
52 'link': args.link,
53 'models' : {}
54 }
55
56 # only support a version_number with images of a single version_commit
57 if output[version]['commit'] != commit:
58 sys.stderr.write('mixed revisions for a release ({} and {}) => abort\n'.format(output[version]['commit'], commit))
59 exit(1)
60
61 images = []
62 for image in obj['images']:
63 images.append(image['name'])
64
65 target = obj['target'].strip('/') # small fixed for stray /
66 id = obj['id']
67 for title in obj['titles']:
68 if 'title' in title:
69 name = title['title']
70 output[version]['models'][name] = {'id': id, 'target': target, 'images': images}
71 else:
72 name = "{} {} {}".format(title.get('vendor', ''), title['model'], title.get('variant', '')).strip()
73 output[version]['models'][name] = {'id': id, 'target': target, 'images': images}
74
75 except json.decoder.JSONDecodeError as e:
76 sys.stderr.write("Skip {}\n {}\n".format(path, e))
77 continue
78 except KeyError as e:
79 sys.stderr.write("Abort on {}\n Missing key {}\n".format(path, e))
80 exit(1)
81
82 # include JSON data from other files
83 for path in args.include:
84 with open(path, "r") as file:
85 try:
86 obj = json.load(file)
87 for release in obj:
88 if release in output:
89 sys.stderr.write("Release entry {} in {} already exists => skip\n".format(release, path))
90 else:
91 output[release] = obj[release]
92 except json.decoder.JSONDecodeError as e:
93 sys.stderr.write("{} {}\n".format(path, e))
94 exit(1)
95
96 if args.formatted:
97 json.dump(output, sys.stdout, sort_keys=True, indent=" ")
98 else:
99 json.dump(output, sys.stdout, sort_keys=True)