allow to use includes only
[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 for title in obj['titles']:
67 if 'title' in title:
68 name = title['title']
69 output[version]['models'][name] = [target, images]
70 else:
71 name = "{} {} {}".format(title.get('vendor', ''), title['model'], title.get('variant', '')).strip()
72 output[version]['models'][name] = [target, images]
73
74 except json.decoder.JSONDecodeError as e:
75 sys.stderr.write("Skip {}\n {}\n".format(path, e))
76 continue
77 except KeyError as e:
78 sys.stderr.write("Abort on {}\n Missing key {}\n".format(path, e))
79 exit(1)
80
81 # include JSON data from other files
82 for path in args.include:
83 with open(path, "r") as file:
84 try:
85 obj = json.load(file)
86 for release in obj:
87 if release in output:
88 sys.stderr.write("Release entry {} in {} already exists => skip\n".format(release, path))
89 else:
90 output[release] = obj[release]
91 except json.decoder.JSONDecodeError as e:
92 sys.stderr.write("{} {}\n".format(path, e))
93 exit(1)
94
95 if args.formatted:
96 json.dump(output, sys.stdout, sort_keys=True, indent=" ")
97 else:
98 json.dump(output, sys.stdout, sort_keys=True)