-
-
Notifications
You must be signed in to change notification settings - Fork 50
Expand file tree
/
Copy pathtranslate.py
More file actions
111 lines (90 loc) · 3.42 KB
/
translate.py
File metadata and controls
111 lines (90 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import glob
import os.path
import sys
import typing
import deepl
import lxml.etree
from deepl import DeepLException
from lxml import etree as ET
def get_language_from_directory(directory_name: str) -> str:
return os.path.split(directory_name)[-1].replace("values-", "")
def map_language(l: str) -> str:
if l == "pt-rBR":
return "pt-BR"
return l if l != "zh-rCN" else "zh-hans"
def escape(str_xml: str):
str_xml = str_xml.replace("&", "&")
str_xml = str_xml.replace("<", "<")
str_xml = str_xml.replace(">", ">")
str_xml = str_xml.replace('"', """)
str_xml = str_xml.replace("'", "'")
return str_xml
# Open English strings.xml file
tree = ET.parse("app/src/main/res/values/strings.xml")
resources = tree.getroot()
strings = resources.findall("string")
english_strings: typing.Dict[str, str] = {}
translated_strings = {}
language_tree: typing.Dict[str, lxml.etree.ElementTree] = {}
translate_list: typing.List[typing.Tuple[str, str]] = []
for string_name in strings:
if string_name.attrib.get("translatable") == "false":
continue
english_strings[string_name.attrib["name"]] = string_name.text
if len(sys.argv) > 2:
translate_args = sys.argv[2:]
else:
translate_args = []
# Search for strings in other languages and build the list of strings to be translated
for directory in glob.glob("app/src/main/res/*"):
if directory == "app/src/main/res/values" or not os.path.exists(
directory + "/strings.xml"
):
continue
language = get_language_from_directory(directory)
# Skip Norwegian until it is fully translated
if language == "nb-rNO":
continue
language_tree[language] = ET.parse(directory + "/strings.xml")
resources = language_tree[language].getroot()
language_strings = []
for string_name in resources.findall("string"):
language_strings.append(string_name.attrib["name"])
for english_string_name in english_strings.keys():
if (
english_string_name not in language_strings
or not language_strings[language_strings.index(english_string_name)]
or english_string_name in translate_args
):
translate_list.append((english_string_name, language))
auth_key = sys.argv[1]
# Translate
new_elements = {}
translator = deepl.Translator(auth_key)
for string_name, language in translate_list:
print("Translating " + string_name + " to " + language)
try:
translated_string = translator.translate_text(
english_strings[string_name],
target_lang=map_language(language),
preserve_formatting=True,
)
except DeepLException:
print("Translation failed")
continue
new_elements[language] = language_tree[language].find(
'string[@name="' + string_name + '"]'
)
if new_elements[language] is None:
new_elements[language] = ET.SubElement(
language_tree[language].getroot(), "string", name=string_name
)
new_elements[language].text = escape(translated_string.text)
# Collect all languages where a translation string was found
languages = set([tl[1] for tl in translate_list]) # NOSONAR
# Update the existing strings.xml files
for language in languages:
with open(f"app/src/main/res/values-{language}/strings.xml", "wb") as f:
language_tree[language].write(
f, encoding="utf-8", xml_declaration=True, pretty_print=True
)