plugin_repo/generate_pluginmaster.py

111 lines
3.2 KiB
Python
Raw Normal View History

2020-12-26 15:11:32 +00:00
import yaml
import json
from time import time
from sys import argv
from os.path import getmtime
from zipfile import ZipFile, ZIP_DEFLATED
from lib.uzip import UpdateableZipFile
2020-12-26 15:11:32 +00:00
DEFAULTS = {
'IsHide': False,
'IsTestingExclusive': False,
'ApplicableVersion': 'any',
}
DUPLICATES = {
'DownloadLinkInstall': ['DownloadLinkTesting', 'DownloadLinkUpdate'],
}
TRIMMED_KEYS = [
'Author',
'Name',
'Description',
'InternalName',
'AssemblyVersion',
'RepoUrl',
'ApplicableVersion',
'Tags',
'DalamudApiLevel',
]
2020-12-26 15:11:32 +00:00
def main():
# convert and write the master
master = convert_master()
# insert manifests if necessary
for plugin in master:
insert_zip(plugin)
# update the LastUpdated field in master
last_updated()
def convert_master():
2020-12-26 15:11:32 +00:00
# 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'
2020-12-26 16:14:02 +00:00
# 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))
2020-12-26 16:14:02 +00:00
# trim the entry from master down to what a plugin manifest includes
trimmed = trim_manifest(plugin)
2020-12-26 16:14:02 +00:00
# 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:
2020-12-26 16:14:02 +00:00
manifest = json.dumps(trimmed, indent=4)
z.writestr(manifest_name, manifest)
2020-12-26 15:11:32 +00:00
def snake_to_pascal(name):
return ''.join(part.title() for part in name.split('_'))
def last_updated():
with open('pluginmaster.json') as f:
master = json.load(f)
for plugin in master:
latest = f'plugins/{plugin["InternalName"]}/latest.zip'
modified = int(getmtime(latest))
if 'LastUpdated' not in plugin or modified != int(plugin['LastUpdated']):
plugin['LastUpdated'] = str(modified)
with open('pluginmaster.json', 'w') as f:
json.dump(master, f, indent=4)
2020-12-26 15:11:32 +00:00
if __name__ == '__main__':
main()