diff --git a/.config/generate_xml.py b/.config/generate_xml.py deleted file mode 100644 index a854960..0000000 --- a/.config/generate_xml.py +++ /dev/null @@ -1,70 +0,0 @@ -import xml.etree.ElementTree as ET -import sys -import os -from datetime import datetime - -import yaml - - -def indent(elem, level=0): - ''' - Nicely formats output xml with newlines and spaces - https://stackoverflow.com/a/33956544 - ''' - i = "\n" + level*" " - if len(elem): - if not elem.text or not elem.text.strip(): - elem.text = i + " " - if not elem.tail or not elem.tail.strip(): - elem.tail = i - for elem in elem: - indent(elem, level+1) - if not elem.tail or not elem.tail.strip(): - elem.tail = i - else: - if level and (not elem.tail or not elem.tail.strip()): - elem.tail = i - - -try: - py_version = sys.argv[1] -except IndexError: - print('No version specified') - sys.exit(1) - -dir_path = os.path.dirname(os.path.realpath(__file__)) - -# Load template file -with open('{dir_path}/template.xml'.format(**locals()), 'r') as f: - tree = ET.parse(f) - root = tree.getroot() - -# Load version dependencies -with open('{dir_path}/{py_version}.yaml'.format(**locals()), 'r') as f: - deps = yaml.safe_load(f) - -# Load version and changelog -with open('jellyfin-kodi/release.yaml', 'r') as f: - data = yaml.safe_load(f) - -# Populate xml template -for dep in deps: - ET.SubElement(root.find('requires'), 'import', attrib=dep) - -# Update version string -addon_version = data.get('version') -root.attrib['version'] = '{addon_version}+{py_version}'.format(**locals()) - -# Changelog -date = datetime.today().strftime('%Y-%m-%d') -changelog = data.get('changelog') -for section in root.findall('extension'): - news = section.findall('news') - if news: - news[0].text = 'v{addon_version} ({date}):\n{changelog}'.format(**locals()) - -# Format xml tree -indent(root) - -# Write addon.xml -tree.write('jellyfin-kodi/addon.xml', encoding='utf-8', xml_declaration=True) diff --git a/build.py b/build.py index 403034f..d564576 100755 --- a/build.py +++ b/build.py @@ -1,28 +1,28 @@ #!/usr/bin/env python import argparse -from datetime import datetime import os -from pathlib import Path import xml.etree.ElementTree as ET import zipfile +from datetime import datetime +from pathlib import Path import yaml -def indent(elem, level=0): - ''' +def indent(elem: ET.Element, level: int = 0) -> None: + """ Nicely formats output xml with newlines and spaces https://stackoverflow.com/a/33956544 - ''' - i = "\n" + level*" " + """ + i = "\n" + level * " " if len(elem): if not elem.text or not elem.text.strip(): elem.text = i + " " if not elem.tail or not elem.tail.strip(): elem.tail = i for elem in elem: - indent(elem, level+1) + indent(elem, level + 1) if not elem.tail or not elem.tail.strip(): elem.tail = i else: @@ -30,10 +30,10 @@ def indent(elem, level=0): elem.tail = i -def create_addon_xml(config, source, py_version): - ''' +def create_addon_xml(config: dict, source: str, py_version: str) -> None: + """ Create addon.xml from template file - ''' + """ # Load template file with open('{}/.config/template.xml'.format(source), 'r') as f: tree = ET.parse(f) @@ -63,21 +63,54 @@ def create_addon_xml(config, source, py_version): tree.write('{}/addon.xml'.format(source), encoding='utf-8', xml_declaration=True) -def zip_files(py_version, source, target): - ''' +def zip_files(py_version: str, source: str, target: str, dev: bool) -> None: + """ Create installable addon zip archive - ''' + """ archive_name = 'plugin.video.jellycon+{}.zip'.format(py_version) with zipfile.ZipFile('{}/{}'.format(target, archive_name), 'w') as z: for root, dirs, files in os.walk(args.source): - for filename in files: - if 'plugin.video.jellycon' not in filename and 'pyo' not in filename: - file_path = os.path.join(root, filename) + for filename in filter(file_filter, files): + file_path = os.path.join(root, filename) + if dev or folder_filter(file_path): relative_path = os.path.join('plugin.video.jellycon', os.path.relpath(file_path, source)) z.write(file_path, relative_path) +def file_filter(file_name: str) -> bool: + """ + True if file_name is meant to be included + """ + return ( + not (file_name.startswith('plugin.video.jellycon') and file_name.endswith('.zip')) + and not file_name.endswith('.pyo') + and not file_name.endswith('.pyc') + and not file_name.endswith('.pyd') + ) + + +def folder_filter(folder_name: str) -> bool: + """ + True if folder_name is meant to be included + """ + filters = [ + '.ci', + '.git', + '.github', + '.config', + '.mypy_cache', + '.pytest_cache', + '__pycache__', + ] + for f in filters: + if f in folder_name.split(os.path.sep): + return False + + return True + + + if __name__ == '__main__': parser = argparse.ArgumentParser(description='Build flags:') parser.add_argument( @@ -96,13 +129,16 @@ if __name__ == '__main__': type=Path, default=Path(__file__).absolute().parent) + parser.add_argument('--dev', dest='dev', action='store_true') + parser.set_defaults(dev=False) + args = parser.parse_args() # Load config file config_path = os.path.join(args.source, 'release.yaml') with open(config_path, 'r') as fh: - config = yaml.safe_load(fh) + release_config = yaml.safe_load(fh) - create_addon_xml(config, args.source, args.version) + create_addon_xml(release_config, args.source, args.version) - zip_files(args.version, args.source, args.target) + zip_files(args.version, args.source, args.target, args.dev)