From 16bb1ceab33917df83382893724f7ed14047097b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Arnauts?= Date: Wed, 2 Feb 2022 17:49:48 +0100 Subject: [PATCH] Modify repository so HEAD contains the Matrix version (#100) --- .env.example | 8 + .gitattributes | 1 + .github/workflows/addon-check.yml | 7 +- .github/workflows/ci.yml | 6 +- .github/workflows/release.yml | 64 +---- .gitignore | 2 + Makefile | 45 +--- addon.xml | 2 +- resources/lib/modules/iptvmanager.py | 2 +- resources/lib/viervijfzes/aws/cognito_sync.py | 1 + resources/lib/viervijfzes/content.py | 2 +- resources/lib/viervijfzes/search.py | 2 +- scripts/build.py | 89 +++++++ .../check_for_unused_translations.py | 0 scripts/publish.py | 225 ++++++++++++++++++ scripts/update_translations.py | 40 ++++ 16 files changed, 397 insertions(+), 99 deletions(-) create mode 100755 scripts/build.py rename {tests => scripts}/check_for_unused_translations.py (100%) create mode 100755 scripts/publish.py create mode 100755 scripts/update_translations.py diff --git a/.env.example b/.env.example index 2ab758e..1ec142b 100644 --- a/.env.example +++ b/.env.example @@ -4,3 +4,11 @@ ADDON_PASSWORD= KODI_HOME=tests/home KODI_INTERACTIVE=0 KODI_STUB_VERBOSE=1 +KODI_STUB_RPC_RESPONSES=tests/rpc + +#HTTP_PROXY= +#HTTPS_PROXY= + +GH_USERNAME= +GH_TOKEN= +EMAIL= \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index 9897fc2..b989aec 100644 --- a/.gitattributes +++ b/.gitattributes @@ -6,3 +6,4 @@ tests/ export-ignore .pylintrc export-ignore Makefile export-ignore requirements.txt export-ignore +scripts/ export-ignore diff --git a/.github/workflows/addon-check.yml b/.github/workflows/addon-check.yml index aa15f01..1531b3a 100644 --- a/.github/workflows/addon-check.yml +++ b/.github/workflows/addon-check.yml @@ -11,10 +11,6 @@ jobs: kodi-addon-checker: name: Addon checker runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - kodi-version: [ leia, matrix ] steps: - name: Check out ${{ github.sha }} from repository ${{ github.repository }} uses: actions/checkout@v2 @@ -22,6 +18,5 @@ jobs: - name: Run kodi-addon-checker uses: xbmc/action-kodi-addon-checker@v1.2 with: - kodi-version: ${{ matrix.kodi-version }} - rewrite-for-matrix: ${{ matrix.kodi-version == 'matrix' }} + kodi-version: matrix addon-id: ${{ github.event.repository.name }} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0218c1..3d0c3ca 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,10 +3,10 @@ on: # Run action when pushed to master, or for commits in a pull request. push: branches: - - master + - master pull_request: branches: - - master + - master jobs: tests: name: Add-on testing @@ -54,7 +54,7 @@ jobs: KODI_INTERACTIVE: 0 KODI_STUB_RPC_RESPONSES: ${{ github.workspace }}/tests/rpc HTTP_PROXY: ${{ secrets.HTTP_PROXY }} - run: pytest -v --cov=./ --cov-report=xml tests + run: pytest -x -v --cov=./ --cov-report=xml tests - name: Upload code coverage to CodeCov uses: codecov/codecov-action@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c3085af..7548edc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,22 +6,13 @@ on: jobs: build: name: Release plugin.video.viervijfzes - if: startsWith(github.ref, 'refs/tags/') # prevent from running if it's not a tag runs-on: ubuntu-latest steps: - - name: Checkout code + - name: Check out ${{ github.sha }} from repository ${{ github.repository }} uses: actions/checkout@v2 - - name: Build zip files - id: build - run: | - sudo apt-get install libxml2-utils - make multizip release=1 - echo ::set-output name=leia-filename::$(cd ..;ls plugin.video.viervijfzes*.zip | grep -v '+matrix.' | head -1) - echo ::set-output name=matrix-filename::$(cd ..;ls plugin.video.viervijfzes*+matrix.*.zip | head -1) - - - name: Get body - id: get-body + - name: Get changelog + id: get-changelog run: | description=$(sed '1,6d;/^## /,$d' CHANGELOG.md) echo $description @@ -30,47 +21,14 @@ jobs: description="${description//$'\r'/'%0D'}" echo ::set-output name=body::$description - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + - name: Generate distribution zips + run: scripts/build.py + + - name: Create Release on Github + uses: softprops/action-gh-release@v1 with: - tag_name: ${{ github.ref }} - release_name: ${{ github.ref }} - body: ${{ steps.get-body.outputs.body }} + body: ${{ steps.get-changelog.outputs.body }} draft: false prerelease: false - - - name: Upload Leia zip - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_name: ${{ steps.build.outputs.leia-filename }} - asset_path: ../${{ steps.build.outputs.leia-filename }} - asset_content_type: application/zip - - - name: Upload Matrix zip - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_name: ${{ steps.build.outputs.matrix-filename }} - asset_path: ../${{ steps.build.outputs.matrix-filename }} - asset_content_type: application/zip - - - name: Generate distribution zip and submit to official kodi repository - id: kodi-addon-submitter - uses: xbmc/action-kodi-addon-submitter@v1.2 - with: - kodi-repository: repo-plugins - addon-id: plugin.video.viervijfzes - kodi-version: leia - kodi-matrix: true - env: - GH_USERNAME: ${{ secrets.GH_USERNAME }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} - EMAIL: ${{ secrets.EMAIL }} + files: "dist/*.zip" + token: ${{ secrets.GH_TOKEN }} diff --git a/.gitignore b/.gitignore index bad9394..e94e306 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ tests/home/userdata/addon_data Pipfile Pipfile.lock + +dist/ diff --git a/Makefile b/Makefile index 8f0d3e5..becb558 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,12 @@ export KODI_HOME := $(CURDIR)/tests/home export KODI_INTERACTIVE := 0 PYTHON := python -KODI_PYTHON_ABIS := 3.0.0 2.26.0 - -# Collect information to build as sensible package name -name = $(shell xmllint --xpath 'string(/addon/@id)' addon.xml) -version = $(shell xmllint --xpath 'string(/addon/@version)' addon.xml) -git_branch = $(shell git rev-parse --abbrev-ref HEAD) -git_hash = $(shell git rev-parse --short HEAD) - -ifdef release - zip_name = $(name)-$(version).zip -else - zip_name = $(name)-$(version)-$(git_branch)-$(git_hash).zip -endif -zip_dir = $(name)/ languages = $(filter-out en_gb, $(patsubst resources/language/resource.language.%, %, $(wildcard resources/language/*))) all: check test build zip: build +multizip: build check: check-pylint check-translations @@ -30,15 +17,15 @@ check-pylint: check-translations: @printf ">>> Running translation checks\n" @$(foreach lang,$(languages), \ - msgcmp resources/language/resource.language.$(lang)/strings.po resources/language/resource.language.en_gb/strings.po; \ + msgcmp --use-untranslated resources/language/resource.language.$(lang)/strings.po resources/language/resource.language.en_gb/strings.po; \ ) - @tests/check_for_unused_translations.py + @scripts/check_for_unused_translations.py -check-addon: clean build +check-addon: build @printf ">>> Running addon checks\n" $(eval TMPDIR := $(shell mktemp -d)) - @unzip ../${zip_name} -d ${TMPDIR} - cd ${TMPDIR} && kodi-addon-checker --branch=leia + @unzip dist/plugin.video.viervijfzes-*+matrix.1.zip -d ${TMPDIR} + cd ${TMPDIR} && kodi-addon-checker --branch=matrix @rm -rf ${TMPDIR} codefix: @@ -56,17 +43,16 @@ clean: @find . -name '__pycache__' -type d -delete @rm -rf .pytest_cache/ tests/cdm tests/userdata/temp @rm -f *.log .coverage + @rm -rf dist/ build: clean - @printf ">>> Building package\n" - @rm -f ../$(zip_name) - @git archive --format zip --worktree-attributes -v -o ../$(zip_name) --prefix $(zip_dir) $(or $(shell git stash create), HEAD) - @printf ">>> Successfully wrote package as: ../$(zip_name)\n" + @printf ">>> Building add-on\n" + @scripts/build.py + @ls -lah dist/*.zip -# You first need to run sudo gem install github_changelog_generator for this release: ifneq ($(release),) - @github_changelog_generator -u add-ons -p $(name) --no-issues --exclude-labels duplicate,question,invalid,wontfix release --future-release v$(release); + docker run -it --rm --env CHANGELOG_GITHUB_TOKEN=$(GH_TOKEN) -v "$(shell pwd)":/usr/local/src/your-app githubchangeloggenerator/github-changelog-generator -u add-ons -p plugin.video.viervijfzes --no-issues --exclude-labels duplicate,question,invalid,wontfix,release,testing --future-release v$(release) @printf "cd /addon/@version\nset $$release\nsave\nbye\n" | xmllint --shell addon.xml; \ date=$(shell date '+%Y-%m-%d'); \ @@ -80,11 +66,4 @@ else @printf "Usage: make release release=1.0.0\n" endif -multizip: clean - @-$(foreach abi,$(KODI_PYTHON_ABIS), \ - printf "cd /addon/requires/import[@addon='xbmc.python']/@version\nset $(abi)\nsave\nbye\n" | xmllint --shell addon.xml; \ - matrix=$(findstring $(abi), $(word 1,$(KODI_PYTHON_ABIS))); \ - if [ $$matrix ]; then version=$(version)+matrix.1; else version=$(version); fi; \ - printf "cd /addon/@version\nset $$version\nsave\nbye\n" | xmllint --shell addon.xml; \ - make build; \ - ) +.PHONY: check codefix test clean build release diff --git a/addon.xml b/addon.xml index 543d179..9010b47 100644 --- a/addon.xml +++ b/addon.xml @@ -1,7 +1,7 @@ - + diff --git a/resources/lib/modules/iptvmanager.py b/resources/lib/modules/iptvmanager.py index 5ed7ffb..a5e7f54 100644 --- a/resources/lib/modules/iptvmanager.py +++ b/resources/lib/modules/iptvmanager.py @@ -4,7 +4,7 @@ from __future__ import absolute_import, division, unicode_literals import logging -from datetime import timedelta, datetime +from datetime import datetime, timedelta from resources.lib import kodiutils from resources.lib.viervijfzes import CHANNELS diff --git a/resources/lib/viervijfzes/aws/cognito_sync.py b/resources/lib/viervijfzes/aws/cognito_sync.py index b39d20f..df1be82 100644 --- a/resources/lib/viervijfzes/aws/cognito_sync.py +++ b/resources/lib/viervijfzes/aws/cognito_sync.py @@ -15,6 +15,7 @@ try: # Python 3 from urllib.parse import quote, urlparse except ImportError: # Python 2 from urllib import quote + from urlparse import urlparse _LOGGER = logging.getLogger(__name__) diff --git a/resources/lib/viervijfzes/content.py b/resources/lib/viervijfzes/content.py index 34dc9ce..e4e12be 100644 --- a/resources/lib/viervijfzes/content.py +++ b/resources/lib/viervijfzes/content.py @@ -13,7 +13,7 @@ from datetime import datetime import requests -from resources.lib.kodiutils import html_to_kodi, STREAM_DASH, STREAM_HLS +from resources.lib.kodiutils import STREAM_DASH, STREAM_HLS, html_to_kodi from resources.lib.viervijfzes import ResolvedStream try: # Python 3 diff --git a/resources/lib/viervijfzes/search.py b/resources/lib/viervijfzes/search.py index 7a26237..15f401a 100644 --- a/resources/lib/viervijfzes/search.py +++ b/resources/lib/viervijfzes/search.py @@ -9,7 +9,7 @@ import logging import requests from resources.lib import kodiutils -from resources.lib.viervijfzes.content import Program, ContentApi, CACHE_ONLY +from resources.lib.viervijfzes.content import CACHE_ONLY, ContentApi, Program _LOGGER = logging.getLogger(__name__) diff --git a/scripts/build.py b/scripts/build.py new file mode 100755 index 0000000..a465f7a --- /dev/null +++ b/scripts/build.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" Build ZIP files for all brands. """ +from __future__ import absolute_import, division, unicode_literals + +import os +import shutil +import sys +import xml.etree.ElementTree as ET + +BRANDS_DIR = 'brands' +DIST_DIR = 'dist' + + +def get_files(): + """ Get a list of files that we should package. """ + # Start with all non-hidden files + files = [f for f in os.listdir() if not f.startswith('.')] + + # Exclude files from .gitattributes + with open('.gitattributes', 'r') as f: + for line in f.read().splitlines(): + filename, mode = line.split(' ') + filename = filename.strip('/') + if mode == 'export-ignore' and filename in files: + files.remove(filename) + + # Exclude files from .gitignore. I know, this won't do matching + with open('.gitignore', 'r') as f: + for filename in f.read().splitlines(): + filename = filename.strip('/') + if filename in files: + files.remove(filename) + + return files + + +def modify_xml(file, version, news, python=None): + """ Modify an addon.xml. """ + with open(file, 'r+') as f: + tree = ET.fromstring(f.read()) + + # Update values + tree.set('version', version) + tree.find("./extension[@point='xbmc.addon.metadata']/news").text = news + if python: + tree.find("./requires/import[@addon='xbmc.python']").set('version', python) + + # Save file + f.seek(0) + f.truncate() + f.write('\n' + + ET.tostring(tree, encoding='UTF-8').decode()) + + +if __name__ == '__main__': + # Read base addon.xml info + with open('addon.xml', 'r') as f: + tree = ET.fromstring(f.read()) + addon_info = { + 'id': tree.get('id'), + 'version': tree.get('version'), + 'news': tree.find("./extension[@point='xbmc.addon.metadata']/news").text + } + + # Make sure dist folder exists + if not os.path.isdir(DIST_DIR): + os.mkdir(DIST_DIR) + + # Build addon + brand = addon_info['id'] + dest = os.path.join(DIST_DIR, brand) + if not os.path.isdir(dest): + os.mkdir(dest) + + # Copy files from add-on source + for f in get_files(): + if os.path.isfile(f): + shutil.copy(f, dest) + else: + shutil.copytree(f, os.path.join(dest, f), dirs_exist_ok=True) + + # Update addon.xml for matrix and create zip + modify_xml(os.path.join(dest, 'addon.xml'), addon_info['version'] + '+matrix.1', addon_info['news']) + shutil.make_archive(os.path.join(DIST_DIR, "%s-%s+matrix.1" % (brand, addon_info['version'])), 'zip', DIST_DIR, brand) + + # Modify addon.xml for leia and create zip + modify_xml(os.path.join(dest, 'addon.xml'), addon_info['version'], addon_info['news'], '2.26.0') + shutil.make_archive(os.path.join(DIST_DIR, "%s-%s" % (brand, addon_info['version'])), 'zip', DIST_DIR, brand) diff --git a/tests/check_for_unused_translations.py b/scripts/check_for_unused_translations.py similarity index 100% rename from tests/check_for_unused_translations.py rename to scripts/check_for_unused_translations.py diff --git a/scripts/publish.py b/scripts/publish.py new file mode 100755 index 0000000..f408e0c --- /dev/null +++ b/scripts/publish.py @@ -0,0 +1,225 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" Publish a ZIP file to the Kodi repository. """ + +# Based on code from https://github.com/xbmc/kodi-addon-submitter + +from __future__ import absolute_import, division, unicode_literals + +import logging +import os +import shutil +import subprocess +import sys +import time +import xml.etree.ElementTree as ET +from pprint import pformat +from tempfile import TemporaryDirectory +from zipfile import ZipFile + +import requests + +_LOGGER = logging.getLogger(__name__) + +GH_REPO = 'repo-plugins' +GH_USERNAME = os.getenv('GH_USERNAME') +GH_TOKEN = os.getenv('GH_TOKEN') +GH_EMAIL = os.getenv('EMAIL') + + +def get_addon_info(xml: str): + """ Parse the passed addon.xml file and extract some information. """ + tree = ET.fromstring(xml) + return { + 'id': tree.get('id'), + 'name': tree.get('name'), + 'version': tree.get('version'), + 'description': tree.find("./extension[@point='xbmc.addon.metadata']/description").text, + 'news': tree.find("./extension[@point='xbmc.addon.metadata']/news").text, + 'python': tree.find("./requires/import[@addon='xbmc.python']").get('version'), + 'source': tree.find("./extension[@point='xbmc.addon.metadata']/source").text, + } + + +def user_fork_exists(repo, gh_username, gh_token): + """ Check if the user has a fork of the repository on Github. """ + resp = requests.get( + 'https://api.github.com/repos/{}/{}'.format( + gh_username, + repo + ), + headers={'Accept': 'application/vnd.github.v3+json'}, + params={ + 'type': 'all' + }, + auth=(gh_username, gh_token) + ) + resp_json = resp.json() + return resp.ok and resp_json.get('fork') + + +def create_personal_fork(repo, gh_username, gh_token): + """Create a personal fork for the official repo on GitHub. """ + resp = requests.post( + 'https://api.github.com/repos/xbmc/{}/forks'.format( + repo + ), + headers={'Accept': 'application/vnd.github.v3+json'}, + auth=(gh_username, gh_token) + ) + if resp.ok: + elapsed_time = 0 + while elapsed_time < 5 * 60: + if not user_fork_exists(repo, gh_username, gh_token): + time.sleep(20) + elapsed_time += 20 + else: + return + raise Exception("Timeout waiting for fork creation exceeded") + raise Exception('GitHub API error: {}\n{}'.format(resp.status_code, resp.text)) + + +def shell(*args): + """ Execute a shell command. """ + subprocess.run(args, check=True) + + +def create_addon_branch(repo, branch, source, addon_info, gh_username, gh_token, gh_email): + """ Create and addon branch in your fork of the respective addon repo. """ + cur_dir = os.getcwd() + os.chdir('dist') + + local_branch_name = '{}@{}'.format(addon_info['id'], branch) + + if os.path.isdir(repo): + # We already have a checked out repo locally, update this with upstream code + os.chdir(repo) + shell('git', 'reset', '--hard') # Remove all local changes + shell('git', 'remote', 'set-branches', '--add', 'upstream', branch) # Make sure the upstream branch exists + shell('git', 'fetch', '-f', 'upstream', branch) # Fetch upstream + else: + # Clone the upstream repo + shell('git', 'clone', '--branch', branch, '--origin', 'upstream', '--single-branch', 'git://github.com/xbmc/{}.git'.format(repo)) + os.chdir(repo) + + # Create local branch + shell('git', 'checkout', '-B', local_branch_name, 'upstream/{}'.format(branch)) + + # Remove current code + if os.path.isdir(addon_info['id']): + shutil.rmtree(addon_info['id'], ignore_errors=False) + + # Add new code + shutil.copytree(source, addon_info['id']) + shell('git', 'add', '--', addon_info['id']) + shell('git', 'status') + + # Create a commit with the new code + shell('git', 'config', 'user.name', gh_username) + shell('git', 'config', 'user.email', gh_email) + shell('git', 'commit', '-m', '[{}] {}'.format(addon_info['id'], addon_info['version'])) + + # Push branch to fork + shell('git', 'push', '-f', 'https://{}:{}@github.com/{}/{}.git'.format(gh_username, gh_token, gh_username, repo), local_branch_name) + + # Restore working directory + os.chdir(cur_dir) + + +def create_pull_request(repo, branch, addon_info, gh_username, gh_token): + """ Create a pull request in the official repo on GitHub. """ + + local_branch_name = '{}@{}'.format(addon_info['id'], branch) + + # Check if pull request already exists. + resp = requests.get( + 'https://api.github.com/repos/xbmc/{}/pulls'.format(repo), + params={ + 'head': '{}:{}'.format(gh_username, local_branch_name), + 'base': branch, + }, + headers={'Accept': 'application/vnd.github.v3+json'}, + auth=(gh_username, gh_token) + ) + + if resp.status_code == 200 and not resp.json(): + # Create a new Pull Request + template = """### Description + +- **General** + - Add-on name: {name} + - Add-on ID: {id} + - Version number: {version} + - Kodi/repository version: {kodi_repo_branch} + +- **Code location** + - URL: {source} + +{description} + +### What's new + +{news} + +### Checklist: +- [X] My code follows the [add-on rules](http://kodi.wiki/view/Add-on_rules) and [piracy stance](http://kodi.wiki/view/Official:Forum_rules#Piracy_Policy) of this project. +- [X] I have read the [CONTRIBUTING](https://github.com/xbmc/repo-plugins/blob/master/CONTRIBUTING.md) document +- [X] Each add-on submission should be a single commit with using the following style: [plugin.video.foo] v1.0.0 +""" + pr_body = template.format( + name=addon_info['name'], + id=addon_info['id'], + version=addon_info['version'], + kodi_repo_branch=branch, + source=addon_info['source'], + description=addon_info['description'], + news=addon_info['news'] + ) + resp = requests.post( + 'https://api.github.com/repos/xbmc/{}/pulls'.format(repo), + json={ + 'title': '[{}] {}'.format(local_branch_name, addon_info['version']), + 'head': '{}:{}'.format(gh_username, local_branch_name), + 'base': branch, + 'body': pr_body, + 'maintainer_can_modify': True, + }, + headers={'Accept': 'application/vnd.github.v3+json'}, + auth=(gh_username, gh_token) + ) + if resp.status_code != 201: + raise Exception('GitHub API error: {}\n{}'.format(resp.status_code, pformat(resp.json()))) + + elif resp.status_code == 200 and resp.json(): + _LOGGER.info('Pull request in {} for {}:{} already exists.'.format(branch, gh_username, local_branch_name)) + + else: + raise Exception('Unexpected GitHub error: {}\n{}'.format(resp.status_code, pformat(resp.json()))) + + +if __name__ == '__main__': + filenames = sys.argv[1:] + + for filename in filenames: + # Fork the repo if the user does not have a personal repo fork + if not user_fork_exists(GH_REPO, GH_USERNAME, GH_TOKEN): + create_personal_fork(GH_REPO, GH_USERNAME, GH_TOKEN) + + with TemporaryDirectory() as extract_dir: + with ZipFile(filename) as z: + # Look for addon.xml in zip and load the details + xmlfile = next(f.filename for f in z.filelist if f.filename.endswith('addon.xml')) + addon_info = get_addon_info(z.read(xmlfile).decode('utf-8')) + if addon_info['python'] != '3.0.0': + branch = 'leia' + else: + branch = 'matrix' + + # Extract the ZIP file to the extract_dir + z.extractall(extract_dir) + + # Checkout the fork locally and create a branch with our new code from the extract_dir + create_addon_branch(GH_REPO, branch, os.path.join(extract_dir, addon_info['id']), addon_info, GH_USERNAME, GH_TOKEN, GH_EMAIL) + + # Create pull request + create_pull_request(GH_REPO, branch, addon_info, GH_USERNAME, GH_TOKEN) diff --git a/scripts/update_translations.py b/scripts/update_translations.py new file mode 100755 index 0000000..60a9cce --- /dev/null +++ b/scripts/update_translations.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# pylint: disable=missing-docstring,no-self-use,wrong-import-order,wrong-import-position,invalid-name + +import sys +from glob import glob + +import polib + +original_file = 'resources/language/resource.language.en_gb/strings.po' +original = polib.pofile(original_file, wrapwidth=0) + +for translated_file in glob('resources/language/resource.language.*/strings.po'): + # Skip original file + if translated_file == original_file: + continue + print('Updating %s...' % translated_file) + + # Load po-files + translated = polib.pofile(translated_file, wrapwidth=0) + + for entry in original: + # Find a translation + translation = translated.find(entry.msgctxt, 'msgctxt') + + if translation and entry.msgid == translation.msgid: + entry.msgstr = translation.msgstr + + original.metadata = translated.metadata + + if sys.platform.startswith('win'): + # On Windows save the file keeping the Linux return character + with open(translated_file, 'wb') as _file: + content = str(original).encode('utf-8') + content = content.replace(b'\r\n', b'\n') + _file.write(content) + else: + # Save it now over the translation + original.save(translated_file)