plugin_repo/generate_pluginmaster.py
2020-12-26 11:14:02 -05:00

90 lines
2.6 KiB
Python

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()