plugin_repo/generate_pluginmaster.py

109 lines
3.0 KiB
Python

import yaml
import json
import os
from time import time
from sys import argv
from os.path import getmtime
from zipfile import ZipFile, ZIP_DEFLATED
DEFAULTS = {
'IsHide': False,
'IsTestingExclusive': False,
'ApplicableVersion': 'any',
}
DUPLICATES = {
'DownloadLinkInstall': ['DownloadLinkTesting', 'DownloadLinkUpdate'],
}
TRIMMED_KEYS = [
'Author',
'Name',
'Description',
'InternalName',
'AssemblyVersion',
'RepoUrl',
'ApplicableVersion',
'Tags',
'DalamudApiLevel',
'Punchline',
'IconUrl',
'ImageUrls',
]
def main():
plugins_dir = argv[1] if len(argv) > 1 else 'plugins'
master_name = 'pluginmaster.json' if plugins_dir == 'plugins' else f'{plugins_dir}.json'
info = {
'plugins_dir': plugins_dir,
'master_name': master_name,
}
# extract the manifests from inside the zip files
master = extract_manifests(info)
# trim the manifests
master = [trim_manifest(manifest) for manifest in master]
# convert the list of manifests into a master list
add_extra_fields(info, master)
# write the master
write_master(info, master)
# update the LastUpdated field in master
last_updated(info)
def extract_manifests(info):
manifests = []
for dirpath, dirnames, filenames in os.walk(f'./{info["plugins_dir"]}'):
if len(filenames) == 0 or 'latest.zip' not in filenames:
continue
plugin_name = dirpath.split('/')[-1]
latest_zip = f'{dirpath}/latest.zip'
with ZipFile(latest_zip) as z:
manifest = json.loads(z.read(f'{plugin_name}.json').decode('utf-8'))
manifests.append(manifest)
return manifests
def add_extra_fields(info, manifests):
for manifest in manifests:
# generate the download link from the internal assembly name
manifest['DownloadLinkInstall'] = f'https://git.sr.ht/~jkcclemens/plugin_repo/blob/main/{info["plugins_dir"]}/{manifest["InternalName"]}/latest.zip'
# add default values if missing
for k, v in DEFAULTS.items():
if k not in manifest:
manifest[k] = v
# duplicate keys as specified in DUPLICATES
for source, keys in DUPLICATES.items():
for k in keys:
if k not in manifest:
manifest[k] = manifest[source]
def write_master(info, master):
# write as pretty json
with open(info['master_name'], 'w') as f:
json.dump(master, f, indent=4)
def trim_manifest(plugin):
return {k: plugin[k] for k in TRIMMED_KEYS if k in plugin}
def last_updated(info):
with open(info['master_name']) as f:
master = json.load(f)
for plugin in master:
latest = f'{info["plugins_dir"]}/{plugin["InternalName"]}/latest.zip'
modified = int(getmtime(latest))
if 'LastUpdated' not in plugin or modified != int(plugin['LastUpdated']):
plugin['LastUpdated'] = str(modified)
with open(info['master_name'], 'w') as f:
json.dump(master, f, indent=4)
if __name__ == '__main__':
main()