mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-11-10 18:36:33 +00:00
🔧 Generate xml in build.py
This commit is contained in:
parent
cbdc9aba09
commit
a426a1251a
7 changed files with 84 additions and 103 deletions
|
|
@ -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)
|
|
||||||
|
|
@ -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'
|
|
||||||
|
|
@ -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'
|
|
||||||
45
build.py
45
build.py
|
|
@ -5,10 +5,12 @@ import os
|
||||||
import zipfile
|
import zipfile
|
||||||
from fnmatch import fnmatchcase as fnmatch
|
from fnmatch import fnmatchcase as fnmatch
|
||||||
import logging
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
import click
|
import click
|
||||||
import click_log
|
import click_log
|
||||||
|
from bs4 import BeautifulSoup, Tag
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger("build")
|
logger = logging.getLogger("build")
|
||||||
|
|
@ -32,6 +34,42 @@ def zip_items(file_name, items, base_path=None):
|
||||||
return file_name
|
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'):
|
def get_config(filename='release.yaml'):
|
||||||
with open(filename, 'r') as fh:
|
with open(filename, 'r') as fh:
|
||||||
return yaml.safe_load(fh)
|
return yaml.safe_load(fh)
|
||||||
|
|
@ -91,6 +129,13 @@ def main(py3, source, output):
|
||||||
if output is None:
|
if output is None:
|
||||||
output = build_filename(config, py3)
|
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)
|
items = get_items(include, exclude, source)
|
||||||
|
|
||||||
zip_file_name = zip_items(output, items, base_path=config.get('id'))
|
zip_file_name = zip_items(output, items, base_path=config.get('id'))
|
||||||
|
|
|
||||||
35
release.yaml
35
release.yaml
|
|
@ -1,5 +1,7 @@
|
||||||
id: 'plugin.video.jellyfin'
|
id: 'plugin.video.jellyfin'
|
||||||
|
name: 'Jellyfin'
|
||||||
version: '0.6.2'
|
version: '0.6.2'
|
||||||
|
provider: 'Jellyfin Contributors'
|
||||||
changelog: |
|
changelog: |
|
||||||
- #373 Use correct filename for kodirepo command
|
- #373 Use correct filename for kodirepo command
|
||||||
- #382 Handle empty XMLs in profile video
|
- #382 Handle empty XMLs in profile video
|
||||||
|
|
@ -18,7 +20,8 @@ build:
|
||||||
- context_play.py
|
- context_play.py
|
||||||
- addon.xml
|
- addon.xml
|
||||||
|
|
||||||
- .config/*
|
- release.yaml
|
||||||
|
- template.xml
|
||||||
- tests/*
|
- tests/*
|
||||||
- build.py
|
- build.py
|
||||||
- requirements-dev.txt
|
- requirements-dev.txt
|
||||||
|
|
@ -34,3 +37,33 @@ build:
|
||||||
- .gitignore
|
- .gitignore
|
||||||
- '*.py[ocd]'
|
- '*.py[ocd]'
|
||||||
- '*/__pycache__'
|
- '*/__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'
|
||||||
|
|
|
||||||
|
|
@ -15,3 +15,4 @@ flake8-import-order >= 0.18
|
||||||
PyYAML >= 5.3
|
PyYAML >= 5.3
|
||||||
click
|
click
|
||||||
click-log
|
click-log
|
||||||
|
beautifulsoup4[lxml] >= 4.9.1, <5
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,10 @@
|
||||||
provider-name="Jellyfin Contributors, angelblue05">
|
provider-name="Jellyfin Contributors, angelblue05">
|
||||||
<requires>
|
<requires>
|
||||||
</requires>
|
</requires>
|
||||||
<extension point="xbmc.python.pluginsource"
|
<extension point="xbmc.python.pluginsource" library="default.py">
|
||||||
library="default.py">
|
<provides>video audio image</provides>
|
||||||
<provides>video audio image</provides>
|
|
||||||
</extension>
|
|
||||||
<extension point="xbmc.service" library="service.py" start="login">
|
|
||||||
</extension>
|
</extension>
|
||||||
|
<extension point="xbmc.service" library="service.py" />
|
||||||
<extension point="kodi.context.item">
|
<extension point="kodi.context.item">
|
||||||
<menu id="kodi.core.main">
|
<menu id="kodi.core.main">
|
||||||
<item library="context.py">
|
<item library="context.py">
|
||||||
|
|
@ -30,7 +28,7 @@
|
||||||
<forum>https://forum.jellyfin.org</forum>
|
<forum>https://forum.jellyfin.org</forum>
|
||||||
<website>https://jellyfin.org/</website>
|
<website>https://jellyfin.org/</website>
|
||||||
<source>https://github.com/jellyfin/jellyfin-kodi</source>
|
<source>https://github.com/jellyfin/jellyfin-kodi</source>
|
||||||
<summary lang="en"></summary>
|
<summary lang="en">Sync your Jellyfin library with Kodi</summary>
|
||||||
<description lang="en">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!</description>
|
<description lang="en">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!</description>
|
||||||
<news>
|
<news>
|
||||||
</news>
|
</news>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue