use double quote for python code
[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="+",
11 help="Input folder that is traversed for OpenWrt JSON device files.")
12 parser.add_argument("--download-url", action="store", default="",
13 help="Link to get the image from. May contain {target}, {version} and {commit}")
14 parser.add_argument("--formatted", action="store_true",
15 help="Output formatted JSON data.")
16 parser.add_argument("--change-prefix",
17 help="Change the openwrt- file name prefix.")
18
19 args = parser.parse_args()
20
21 SUPPORTED_METADATA_VERSION = 1
22
23 def change_prefix(images, old_prefix, new_prefix):
24 for image in images:
25 if image["name"].startswith(old_prefix):
26 image["name"] = new_prefix + image["name"][len(old_prefix):]
27
28 # OpenWrt JSON device files
29 paths = []
30
31 # json output data
32 output = {}
33
34 for path in args.input_path:
35 if os.path.isdir(path):
36 for file in Path(path).rglob("*.json"):
37 paths.append(file)
38 else:
39 if not path.endswith(".json"):
40 sys.stderr.write(f"Folder does not exists: {path}\n")
41 exit(1)
42 paths.append(path)
43
44 def get_title_name(title):
45 if "title" in title:
46 return title["title"]
47 else:
48 return "{} {} {}".format(title.get("vendor", ""), title["model"], title.get("variant", "")).strip()
49
50 def add_profile(id, target, profile, code=None):
51 images = []
52 for image in profile["images"]:
53 images.append({"name": image["name"], "type": image["type"]})
54
55 if target is None:
56 target = profile["target"]
57
58 if args.change_prefix:
59 change_prefix(images, "openwrt-", args.change_prefix)
60
61 for title in profile["titles"]:
62 name = get_title_name(title)
63
64 if len(name) == 0:
65 sys.stderr.write(f"Empty title. Skip title in {path}\n")
66 continue
67
68 output["models"][name] = {"id": id, "target": target, "images": images}
69
70 if code is not None:
71 output["models"][name]["code"] = code
72
73 for path in paths:
74 with open(path, "r") as file:
75 obj = json.load(file)
76
77 if obj["metadata_version"] != SUPPORTED_METADATA_VERSION:
78 sys.stderr.write(f"{path} has unsupported metadata version: {obj["metadata_version"]} => skip\n")
79 continue
80
81 code = obj.get("version_code", obj.get("version_commit"))
82
83 if not "version_code" in output:
84 output = {
85 "version_code": code,
86 "download_url": args.download_url,
87 "models" : {}
88 }
89
90 # if we have mixed codes/commits, store in device object
91 if output["version_code"] == code:
92 code = None;
93
94 try:
95 if "profiles" in obj:
96 for id in obj["profiles"]:
97 add_profile(id, obj.get("target"), obj["profiles"][id], code)
98 else:
99 add_profile(obj["id"], obj["target"], obj, code)
100 except json.decoder.JSONDecodeError as e:
101 sys.stderr.write(f"Skip {path}\n {e}\n")
102 except KeyError as e:
103 sys.stderr.write(f"Abort on {path}\n Missing key {e}\n")
104 exit(1)
105
106 if args.formatted:
107 json.dump(output, sys.stdout, indent=" ", sort_keys=True)
108 else:
109 json.dump(output, sys.stdout, sort_keys=True)