import yaml import json from zipfile import ZipFile, ZIP_DEFLATED from lib.uzip import UpdateableZipFile DEFAULTS = { 'IsHide': False, 'IsTestingExclusive': False, 'ApplicableVersion': 'any', } DUPLICATES = { 'DownloadLinkInstall': ['DownloadLinkTesting', 'DownloadLinkUpdate'], } TRIMMED_KEYS = [ 'Author', 'Name', 'Description', 'InternalName', 'AssemblyVersion', 'RepoUrl', 'ApplicableVersion', 'Tags', 'DalamudApiLevel', ] def main(): # convert and write the master master = convert_master() for plugin in master: insert_zip(plugin) def convert_master(): # load in the source with open('pluginmaster.yaml') as f: snake_master = yaml.load(f, Loader=yaml.SafeLoader) # convert all keys to pascal case master = [ { snake_to_pascal(k): v for k, v in item.items() } for item in snake_master ] # generate the download link from the internal assembly name for item in master: item['DownloadLinkInstall'] = f'https://git.sr.ht/~jkcclemens/plugin_repo/blob/master/plugins/{item["InternalName"]}/latest.zip' # add default values if missing for k, v in DEFAULTS.items(): for item in master: if k not in item: item[k] = v # duplicate keys as specified in DUPLICATES for item in master: for source, keys in DUPLICATES.items(): for k in keys: if k not in item: item[k] = item[source] # write as pretty json with open('pluginmaster.json', 'w') as f: json.dump(master, f, indent=4) # return the master return master def trim_manifest(plugin): return {k: plugin[k] for k in TRIMMED_KEYS if k in plugin} def insert_zip(plugin): name = plugin['InternalName'] zip_path = f'plugins/{name}/latest.zip' manifest_name = f'{name}.json' # load the manifest that's already in the zip, if any existing = None with ZipFile(zip_path) as z: if manifest_name in z.namelist(): existing = json.load(z.open(manifest_name)) # trim the entry from master down to what a plugin manifest includes trimmed = trim_manifest(plugin) # write the trimmed manifest into the zip if they're not the same if existing != trimmed: with UpdateableZipFile(zip_path, mode='a', compression=ZIP_DEFLATED) as z: manifest = json.dumps(trimmed, indent=4) z.writestr(manifest_name, manifest) def snake_to_pascal(name): return ''.join(part.title() for part in name.split('_')) if __name__ == '__main__': main()