forked from armory3d/armortools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathextract_locales.py
executable file
·99 lines (81 loc) · 3.35 KB
/
extract_locales.py
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
#!/usr/bin/env python3
# Extracts localizable strings from a set of source files and writes them to JSON files.
# This script can create new translations or update existing ones.
# Usage: ./extract_locales.py <locale code>
import fnmatch
import json
import os
import sys
from typing import Any, Dict, IO, List
from typing_extensions import Final
unique_str: List[str] = []
def process_file(f: IO[Any], fname: str, template_data: Dict[str, str]) -> None:
line = f.readline()
while line:
patterns = ['tr("']
idx = 0
pos = 0
while pos >= 0:
pos = line.find(patterns[idx], pos)
if pos == -1:
if idx < len(patterns) - 1:
idx += 1
pos = 0
continue
pos += len(patterns[idx])
msg = ""
while pos < len(line) and (line[pos] != '"' or line[pos - 1] == "\\"):
msg += line[pos]
pos += 1
# Only add each unique string once.
if msg not in unique_str:
# Empty keys are considered untranslated by the i18n library.
# Fix newlines so they're not escaped anymore. Otherwise,
# they won't match the source strings.
template_data[msg.replace("\\n", "\n")] = ""
unique_str.append(msg)
line = f.readline()
def main() -> None:
if len(sys.argv) != 2:
sys.exit(f"Usage: {sys.argv[0]} <locale code>")
# Change to the directory where the script is located,
# so that the script can be run from any location.
os.chdir(os.path.dirname(os.path.realpath(__file__)))
output_path: Final = f"Assets/locale/{sys.argv[1]}.json"
if not os.path.exists("Sources"):
sys.exit(
"ERROR: Couldn't find the Sources folder in the folder where this script is located."
)
matches: List[str] = []
for root, dirnames, filenames in os.walk("Sources"):
dirnames[:] = [d for d in dirnames]
for filename in fnmatch.filter(filenames, "*.hx"):
matches.append(os.path.join(root, filename))
matches.sort()
template_data: Dict[str, str] = {}
for filename in matches:
with open(filename, "r") as f:
# Read source files for localizable strings.
process_file(f, filename, template_data)
if os.path.exists(output_path):
print(f'Updating the translation at "{output_path}"...')
with open(output_path, "r") as f:
existing_data = json.loads(f.read())
# Remove obsolete translations (i.e. translations that are no longer
# present in the generated data).
existing_data_no_obsolete = {
key: value
for key, value in existing_data.items()
if key in template_data
}
# Merge existing data with the generated template data (so we keep
# existing translations).
template_data = {**template_data, **existing_data_no_obsolete}
with open(output_path, "w") as f:
json.dump(template_data, f, ensure_ascii=False, indent=4)
else:
print(f'Creating new translation template at "{output_path}"...')
with open(output_path, "w") as f:
json.dump(template_data, f, ensure_ascii=False, indent=4)
if __name__ == "__main__":
main()