Revision control

Copy as Markdown

Other Tools

#!/usr/bin/python3 -u
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
"""
Build the Flatpak .desktop file. Needs to run in the Python virtualenv
due to dependencies.
python3 /scripts/build_desktop_file.py -o "$WORKSPACE/org.mozilla.Thunderbird.desktop" \
-t "/scripts/org.mozilla.Thunderbird.desktop.jinja2" \
-l "$WORKSPACE/l10n-central" \
-L "$WORKSPACE/shipped-locales" \
-f "mail/branding/thunderbird/brand.ftl" \
-f "mail/messenger/flatpak.ftl"
"""
import argparse
import json
import os
import urllib.request
import zipfile
from pathlib import Path
from typing import List, Union
import jinja2
from fluent.runtime.fallback import FluentLocalization, FluentResourceLoader
COMM_L10N_ZIP_PREFIX = "comm-l10n-{rev}"
class FluentTranslator:
"""
FluentTranslator is an enhanced FluentLocalization
"""
def __init__(self, l10n_base: Path, locales: List[str], resource_ids: List[str]):
self._locales = locales
self._localizations = self._populate(l10n_base, resource_ids)
@property
def locales(self):
return sorted([l for l in self._locales if l != "en-US"])
def _populate(self, l10n_path, resource_ids):
loader = FluentResourceLoader(str(l10n_path / "{locale}"))
rv = {}
for locale in self._locales:
rv[locale] = FluentLocalization([locale], resource_ids, loader)
return rv
def get_message(self, locale, message_id) -> Union[str, None]:
rv = self._localizations[locale].format_value(message_id)
if rv == message_id:
return None
return rv
def get_multi_translate(l10n_strings: FluentTranslator):
def translate_multi(key: str, fluent_id: str):
for locale in l10n_strings.locales:
translated = l10n_strings.get_message(locale, fluent_id)
if translated is not None:
yield f"{key}[{locale}]={translated}"
return translate_multi
def build_template(
output: Path,
template: Path,
l10n_base: Path,
locales: List[str],
fluent_resources: List[str],
is_beta: bool,
):
wmclass = "thunderbird"
if is_beta:
wmclass = wmclass + "-beta"
locales_plus = locales + ["en-US"]
l10n_strings = FluentTranslator(l10n_base.resolve(), locales_plus, fluent_resources)
with open(template) as fp:
jinja_template = jinja2.Template(fp.read())
translate_multi = get_multi_translate(l10n_strings)
result = jinja_template.render(
strings=l10n_strings, translate=translate_multi, wmclass=wmclass
)
with open(output, "w") as fp:
fp.write(result)
def get_extract_members(
zip_file: zipfile.ZipFile, file_pats: List[str], prefix: str
) -> List[zipfile.ZipInfo]:
for m in zip_file.infolist():
for pat in file_pats:
if m.filename.endswith(pat):
m.filename = os.path.relpath(m.filename, prefix)
print(f"Found {m.filename} in strings repo.")
yield m
def get_strings(l10n_base, rev, fluent_files):
url = COMM_L10N_ZIP.format(rev=rev)
temp_file, headers = urllib.request.urlretrieve(url)
with zipfile.ZipFile(temp_file, "r") as strings_zip:
to_extract = get_extract_members(
strings_zip, fluent_files, COMM_L10N_ZIP_PREFIX.format(rev=rev)
)
strings_zip.extractall(path=l10n_base, members=to_extract)
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-o", dest="output", type=Path, required=True, help="Output file")
parser.add_argument(
"-t", dest="template", type=Path, required=True, help="Jinja2 template file"
)
parser.add_argument(
"-l", dest="l10n_base", type=Path, required=True, help="l10n-central root path"
)
parser.add_argument(
"-L", dest="locales_file", type=Path, required=True, help="List of supported locales"
)
parser.add_argument(
"-f", dest="fluent_files", type=str, required=True, action="extend", nargs="+"
)
parser.add_argument(
"--beta",
dest="is_beta",
action="store_true",
default=False,
help="Mark this build a beta version",
)
args = parser.parse_args()
with open(args.locales_file) as fp:
locale_data = json.load(fp)
locales = [l for l in locale_data.keys() if l != "ja-JP-mac"]
comm_l10n_rev = locale_data.get("en-GB", {}).get("revision")
get_strings(args.l10n_base, comm_l10n_rev, args.fluent_files)
build_template(
args.output, args.template, args.l10n_base, locales, args.fluent_files, args.is_beta
)
if __name__ == "__main__":
main()