From a426a1251a2d69da5e62358451376835ff4de08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Odd=20Str=C3=A5b=C3=B8?= Date: Sat, 3 Oct 2020 13:21:01 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A7=20Generate=20xml=20in=20build.py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .config/generate_xml.py | 70 ---------------------------- .config/py2.yaml | 14 ------ .config/py3.yaml | 12 ----- build.py | 45 ++++++++++++++++++ release.yaml | 35 +++++++++++++- requirements-dev.txt | 1 + .config/template.xml => template.xml | 10 ++-- 7 files changed, 84 insertions(+), 103 deletions(-) delete mode 100644 .config/generate_xml.py delete mode 100644 .config/py2.yaml delete mode 100644 .config/py3.yaml rename .config/template.xml => template.xml (90%) diff --git a/.config/generate_xml.py b/.config/generate_xml.py deleted file mode 100644 index da4ae367..00000000 --- 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(f'{dir_path}/template.xml', 'r') as f: - tree = ET.parse(f) - root = tree.getroot() - -# Load version dependencies -with open(f'{dir_path}/{py_version}.yaml', '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'] = f'{addon_version}+{py_version}' - -# 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 = f'v{addon_version} ({date}):\n{changelog}' - -# Format xml tree -indent(root) - -# Write addon.xml -tree.write('jellyfin-kodi/addon.xml', encoding='utf-8', xml_declaration=True) diff --git a/.config/py2.yaml b/.config/py2.yaml deleted file mode 100644 index f673c810..00000000 --- a/.config/py2.yaml +++ /dev/null @@ -1,14 +0,0 @@ -- addon: 'xbmc.python' - version: '2.25.0' -- addon: 'script.module.requests' - version: '2.22.0' -- addon: 'script.module.dateutil' - version: '2.8.1' -- addon: 'script.module.six' - version: '1.13.0' -- addon: 'script.module.kodi-six' - version: '0.0.7' -- addon: 'script.module.addon.signals' - version: '0.0.5' -- addon: 'script.module.futures' - version: '2.2.0' diff --git a/.config/py3.yaml b/.config/py3.yaml deleted file mode 100644 index 83d2d87f..00000000 --- a/.config/py3.yaml +++ /dev/null @@ -1,12 +0,0 @@ -- addon: 'xbmc.python' - version: '3.0.0' -- addon: 'script.module.requests' - version: '2.22.0+matrix.1' -- addon: 'script.module.dateutil' - version: '2.8.1+matrix.1' -- addon: 'script.module.six' - version: '1.14.0+matrix.2' -- addon: 'script.module.kodi-six' - version: '0.1.3+1' -- addon: 'script.module.addon.signals' - version: '0.0.5+matrix.1' diff --git a/build.py b/build.py index 92d9d3c6..860759fc 100755 --- a/build.py +++ b/build.py @@ -5,10 +5,12 @@ import os import zipfile from fnmatch import fnmatchcase as fnmatch import logging +from datetime import datetime import yaml import click import click_log +from bs4 import BeautifulSoup, Tag logger = logging.getLogger("build") @@ -32,6 +34,42 @@ def zip_items(file_name, items, base_path=None): return file_name +def format_changelog(version, changelog): + return 'v{addon_version} ({date}):\n{changelog}'.format( + addon_version=version, + date=datetime.today().strftime('%Y-%m-%d'), + changelog=changelog + ) + + +def create_addon_xml(config, py3=True, template='template.xml', output='addon.xml'): + with open(template) as fh: + soup = BeautifulSoup(fh, features='xml') + + addon = soup.select_one('addon') + + addon['id'] = config.get('id') + addon['name'] = config.get('name') + addon['version'] = config.get('version') + addon['provider-name'] = config.get('provider') + + dependencies = config.get('dependencies', {}).get('py3' if py3 else 'py2') + xml_deps = addon.select_one('requires') # type: Tag + + for dep in dependencies: + tag = soup.new_tag('import', attrs=dep) + xml_deps.append(tag) + + xml_news = addon.select_one("extension[point='xbmc.addon.metadata'] > news") # type: Tag + xml_news.string = format_changelog(config.get('version'), config.get('changelog')) + + soup.smooth() + + with open(output, 'w', encoding='utf-8') as fh: + logging.debug(soup) + fh.write(soup.prettify()) + + def get_config(filename='release.yaml'): with open(filename, 'r') as fh: return yaml.safe_load(fh) @@ -91,6 +129,13 @@ def main(py3, source, output): if output is None: output = build_filename(config, py3) + create_addon_xml( + config, + py3=py3, + template=os.path.join(source, 'template.xml'), + output=os.path.join(source, 'addon.xml') + ) + items = get_items(include, exclude, source) zip_file_name = zip_items(output, items, base_path=config.get('id')) diff --git a/release.yaml b/release.yaml index c17492f8..08c231f7 100644 --- a/release.yaml +++ b/release.yaml @@ -1,5 +1,7 @@ id: 'plugin.video.jellyfin' +name: 'Jellyfin' version: '0.6.2' +provider: 'Jellyfin Contributors' changelog: | - #373 Use correct filename for kodirepo command - #382 Handle empty XMLs in profile video @@ -18,7 +20,8 @@ build: - context_play.py - addon.xml - - .config/* + - release.yaml + - template.xml - tests/* - build.py - requirements-dev.txt @@ -34,3 +37,33 @@ build: - .gitignore - '*.py[ocd]' - '*/__pycache__' + +dependencies: + py2: + - addon: 'xbmc.python' + version: '2.25.0' + - addon: 'script.module.requests' + version: '2.22.0' + - addon: 'script.module.dateutil' + version: '2.8.1' + - addon: 'script.module.six' + version: '1.13.0' + - addon: 'script.module.kodi-six' + version: '0.0.7' + - addon: 'script.module.addon.signals' + version: '0.0.5' + - addon: 'script.module.futures' + version: '2.2.0' + py3: + - addon: 'xbmc.python' + version: '3.0.0' + - addon: 'script.module.requests' + version: '2.22.0+matrix.1' + - addon: 'script.module.dateutil' + version: '2.8.1+matrix.1' + - addon: 'script.module.six' + version: '1.14.0+matrix.2' + - addon: 'script.module.kodi-six' + version: '0.1.3+1' + - addon: 'script.module.addon.signals' + version: '0.0.5+matrix.1' diff --git a/requirements-dev.txt b/requirements-dev.txt index b8764897..8a446e91 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -15,3 +15,4 @@ flake8-import-order >= 0.18 PyYAML >= 5.3 click click-log +beautifulsoup4[lxml] >= 4.9.1, <5 diff --git a/.config/template.xml b/template.xml similarity index 90% rename from .config/template.xml rename to template.xml index ee6bb514..074622fe 100644 --- a/.config/template.xml +++ b/template.xml @@ -5,12 +5,10 @@ provider-name="Jellyfin Contributors, angelblue05"> - - video audio image - - + + video audio image + @@ -30,7 +28,7 @@ https://forum.jellyfin.org https://jellyfin.org/ https://github.com/jellyfin/jellyfin-kodi - + Sync your Jellyfin library with Kodi Welcome to Jellyfin for Kodi! A whole new way to manage and view your media library. The Jellyfin addon for Kodi combines the best of Kodi - ultra smooth navigation, beautiful UIs and playback of any file under the sun, and Jellyfin - the most powerful fully open source multi-client media metadata indexer and server. Jellyfin for Kodi is the absolute best way to enjoy the incredible Kodi playback engine combined with the power of Jellyfin's centralized database. Features: * Direct integration with the Kodi library for native Kodi speed * Instant synchronization with the Jellyfin server * Full support for Movie, TV and Music collections * Jellyfin Server direct stream and transcoding support - use Kodi when you are away from home!