mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-11-10 18:36:33 +00:00
149 lines
4.5 KiB
Python
Executable file
149 lines
4.5 KiB
Python
Executable file
# -*- coding: utf-8 -*-
|
|
from __future__ import division, absolute_import, print_function, unicode_literals
|
|
|
|
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")
|
|
click_log.basic_config(logger)
|
|
|
|
|
|
def zip_items(file_name, items, base_path=None):
|
|
if base_path is None:
|
|
base_path = os.path.splitext(file_name)[0]
|
|
|
|
elif not base_path:
|
|
base_path = ""
|
|
|
|
with zipfile.ZipFile(file_name, "w", zipfile.ZIP_DEFLATED) as z:
|
|
for item, path, _pattern in items:
|
|
logger.info(path)
|
|
archive_path = os.path.join(base_path, path)
|
|
if path not in ["."]:
|
|
z.write(item, archive_path)
|
|
|
|
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')
|
|
|
|
pyversion = 'py3' if py3 else 'py2'
|
|
|
|
addon = soup.select_one('addon')
|
|
|
|
addon['id'] = config.get('id')
|
|
addon['name'] = config.get('name')
|
|
addon['version'] = "{}+{}".format(config.get('version'), pyversion)
|
|
addon['provider-name'] = config.get('provider')
|
|
|
|
dependencies = config.get('dependencies', {}).get(pyversion, [])
|
|
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)
|
|
|
|
|
|
def match_item(item, include, exclude):
|
|
for pattern in exclude:
|
|
if fnmatch(item, pattern):
|
|
logger.debug('Excluded: {!r} {!r}'.format(pattern, item))
|
|
return False, pattern
|
|
|
|
for pattern in include:
|
|
if fnmatch(item, pattern):
|
|
logger.debug('Included: {!r} {!r}'.format(pattern, item))
|
|
return True, pattern
|
|
|
|
return None, None
|
|
|
|
|
|
def get_items(include, exclude, basepath='.'):
|
|
for base, dirs, files in os.walk(basepath):
|
|
for dir_name in dirs:
|
|
dir_path = os.path.join(base, dir_name)
|
|
normalized_dir_path = os.path.normpath(os.path.relpath(dir_path, basepath))
|
|
match, pattern = match_item(normalized_dir_path, include, exclude)
|
|
if match:
|
|
yield dir_path, normalized_dir_path, pattern
|
|
|
|
for file_name in files:
|
|
file_path = os.path.join(base, file_name)
|
|
normalized_file_path = os.path.normpath(os.path.relpath(file_path, basepath))
|
|
match, pattern = match_item(normalized_file_path, include, exclude)
|
|
if match:
|
|
yield file_path, normalized_file_path, pattern
|
|
|
|
|
|
def build_filename(config, py3):
|
|
# type: (dict, bool) -> str
|
|
return "{}-{}+{}.zip".format(
|
|
config.get('id'),
|
|
config.get('version', '0.0.0'),
|
|
'py3' if py3 else 'py2'
|
|
)
|
|
|
|
|
|
@click.command()
|
|
@click.option('-3/-2', '--py3/--py2', default=True, type=bool, help="Default is Python 3.")
|
|
@click.option('--source', default='.', type=click.Path(exists=True, file_okay=False), help="Path to addon sources (current_dir).")
|
|
@click.option('--output', default=None, type=click.Path(), help="Output file (current_dir/addon-version+py3.zip).")
|
|
@click_log.simple_verbosity_option(logger)
|
|
def main(py3, source, output):
|
|
config = get_config(os.path.join(source, 'release.yaml'))
|
|
config_build = config.get('build', {})
|
|
include = config_build.get('include', [])
|
|
exclude = config_build.get('exclude', [])
|
|
|
|
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'))
|
|
|
|
click.echo(zip_file_name)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|