starter-kit/bots/po-refresh
2019-08-25 15:21:02 +00:00

165 lines
6.2 KiB
Python
Executable file

#!/usr/bin/env python3
# This file is part of Cockpit.
#
# Copyright (C) 2017 Red Hat, Inc.
#
# Cockpit is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# Cockpit is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
import os
import json
import subprocess
import sys
sys.dont_write_bytecode = True
import task
BOTS = os.path.abspath(os.path.dirname(__file__))
BASE = os.path.normpath(os.path.join(BOTS, ".."))
def run(context, verbose=False, **kwargs):
cwd = BASE
def output(*args):
if verbose:
sys.stderr.write("+ " + " ".join(args) + "\n")
return subprocess.check_output(args, cwd=cwd, universal_newlines=True)
def execute(*args):
if verbose:
sys.stderr.write("+ " + " ".join(args) + "\n")
subprocess.check_call(args, cwd=cwd)
def changed(filename):
lines = output("git", "diff", "--", filename).split("\n")
msgstr = False
for line in lines:
if line.startswith("+msgstr ") and not line.endswith('""'):
if verbose:
sys.stderr.write("{0}: {1}\n".format(filename, line[8:]))
msgstr = True
return msgstr
# Make a tree with source and run "update-po" in it... outputs working directory
line = output("bots/make-source", "update-po")
work = os.path.abspath(line.strip())
# Do the various updates
cmd = [ "make", "upload-pot", "clean-po", "download-po" ]
if verbose:
sys.stderr.write("+ " + " ".join(cmd) + "\n")
subprocess.check_call(cmd, cwd=work)
local_branch = None
user = None
current_manifest = None
current_linguas = []
language_map = {}
# LINGUAS file in use and therefore needs updating
linguas_exists = os.path.isfile("po/LINGUAS")
# Manifest file is use - and for its updating we also need language map
manifest_exists = os.path.isfile("pkg/shell/manifest.json.in") and os.path.isfile("po/language_map.txt")
# Get locale from language-map file. Fail with keyError when not found
def get_locale(file_name):
language = os.path.splitext(os.path.basename(file_name))[0]
if manifest_exists:
return language_map[language]
return [language]
def add_and_commit_lang(name, language, action):
git_cmd = ["git", "add", "--"]
if linguas_exists:
with open("po/LINGUAS", "w", encoding='utf-8') as lngs:
print("\n".join(current_linguas), file=lngs)
git_cmd.append("po/LINGUAS")
if manifest_exists:
with open("pkg/shell/manifest.json.in", "w", encoding='utf-8') as mnfst:
text = json.dumps(current_manifest, ensure_ascii=False, indent=4)
print(text, file=mnfst)
git_cmd.append("pkg/shell/manifest.json.in")
execute(*git_cmd, name)
return task.branch(context, "po: {0} '{1}' language".format(action, language),
pathspec=None, branch=local_branch, push=False, **kwargs)
# Build language map a read manifest
if manifest_exists:
with open("po/language_map.txt", "r") as lm:
for line in lm:
line = line.strip()
if not line:
continue
items = line.split(":")
language_map[items[0]] = items
# Read manifest
with open("pkg/shell/manifest.json.in", "r", encoding='utf-8') as mnfst:
current_manifest = json.load(mnfst)
# Read linguas
if linguas_exists:
with open("po/LINGUAS", "r", encoding='utf-8') as lngs:
current_linguas = lngs.read().strip().split()
# Remove languages that fall under 50% translated
files = output("git", "ls-files", "--deleted", "po/")
for name in files.splitlines():
if name.endswith(".po"):
locale = get_locale(name)
if current_manifest:
current_manifest["locales"].pop(locale[2])
if current_linguas:
current_linguas.remove(locale[0])
(user, local_branch) = add_and_commit_lang(name, locale[0], "Drop").split(":")
# Add languages that got over 50% translated
files = output("git", "ls-files", "--others", "--exclude-standard", "po/")
for name in files.splitlines():
if name.endswith(".po"):
locale = get_locale(name)
if current_manifest:
current_manifest["locales"][locale[2]] = locale[1]
current_manifest["locales"] = dict(sorted(current_manifest["locales"].items()))
if current_linguas:
current_linguas.append(locale[0])
current_linguas.sort()
(user, local_branch) = add_and_commit_lang(name, locale[0], "Add").split(":")
# Here we have logic to only include files that actually
# changed translations, and reset all the remaining ones
files = output("git", "ls-files", "--modified", "po/")
for name in files.splitlines():
if name.endswith(".po"):
if changed(name):
execute("git", "add", "--", name)
else:
execute("git", "checkout", "--", name)
# Create a pull request from these changes
branch = task.branch(context, "po: Update from Fedora Zanata", pathspec="po/",
branch=local_branch, **kwargs)
if branch:
task.pull(branch, **kwargs)
elif local_branch:
if kwargs["issue"]:
clean = "https://github.com/{0}".format(task.find_our_fork(user))
task.comment_done(kwargs["issue"], "po-refresh", clean, local_branch, context)
task.push_branch(user, local_branch)
task.pull("{0}:{1}".format(user, local_branch), **kwargs)
if __name__ == '__main__':
task.main(function=run, title="Update translations from Fedora Zanata")