yubioath-flutter/update_android_strings.py
2023-12-04 16:23:53 +01:00

101 lines
3.1 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (C) 2023 Yubico.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import os
import xml.etree.cElementTree as ET
from os import path as p
def read_arb_file(file_path):
"""Load translations from flutter ARB file."""
with open(file_path, "r", encoding="utf-8") as file:
return json.load(file)
def get_lang_file_dir(lang):
"""Return path of Android resource directory for lang."""
return (
f"android/app/src/main/res/values-{lang}"
if lang != "en"
else "android/app/src/main/res/values"
)
def get_lang_file(lang):
"""Return path of Android string resource file for lang."""
return p.join(get_lang_file_dir(lang), "strings.xml")
def process_android_res(lang, arb, keys_to_translate):
"""Generate or update Android string resource for lang.
Parameters
----------
lang : str
language code
arb : dict
content of flutter ARB file
keys_to_translate : list
string resources which will be generated or updated
"""
res_dir = get_lang_file_dir(lang)
if not p.exists(res_dir):
os.makedirs(res_dir)
res_path = get_lang_file(lang)
res = (
ET.parse(res_path).getroot() if p.exists(res_path) else ET.Element("resources")
)
for key in keys_to_translate:
# only add the string if translation exists in arb
if key in arb.keys() and arb[key] is not None:
existing = res.find(f"./string[@name='{key}']")
if existing is not None:
existing.text = arb[key]
else:
ET.SubElement(res, "string", name=f"{key}").text = arb[key]
tree = ET.ElementTree(res)
ET.indent(tree, " ")
tree.write(res_path, encoding="utf-8", xml_declaration=True)
return True
def get_english_strings():
"""Extract translatable strings from English Android string resource."""
strings_en = "android/app/src/main/res/values/strings.xml"
resources_en = ET.parse(strings_en).getroot()
return [
key.attrib.get("name")
for key in resources_en
if key.attrib.get("translatable") in [None, True]
]
if __name__ == "__main__":
arb_files = "lib/l10n"
english_strings = get_english_strings()
for arb_file in os.listdir(arb_files):
if arb_file.startswith("app_") and arb_file.endswith(".arb"):
lang = arb_file.split("_")[1].split(".")[0]
arb_path = p.join(arb_files, arb_file)
arb = read_arb_file(arb_path)
if process_android_res(lang, arb, english_strings):
print(f"Processed: {get_lang_file(lang)}")