-
Notifications
You must be signed in to change notification settings - Fork 36
/
language_dump.py
executable file
·135 lines (116 loc) · 5.98 KB
/
language_dump.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/usr/bin/env python3
"""
Dump translations for OpenRCT2's JSON objects given a language and a file
"""
import argparse
import glob
import json
import os
import sys
# from pprint import pprint
from languages import SUPPORTED_LANGUAGES
def dir_path(string):
""" Checks for a valid dir_path """
if os.path.isdir(string):
return string
raise NotADirectoryError(string)
def get_arg_parser():
""" Command line arguments """
parser = argparse.ArgumentParser(description='Dump translations for OpenRCT2\'s JSON objects.',\
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-o', '--objects', default="objects", help='JSON objects directory')
parser.add_argument('-f', '--fallback', default="en-GB",\
help='Fallback language to check against', choices=SUPPORTED_LANGUAGES)
target_group = parser.add_mutually_exclusive_group(required=True)
target_group.add_argument('-t', '--target_dir', help='Directory to dump translation files',\
type=dir_path)
target_group.add_argument('-d', '--dumpfile', help='Translation file to export to')
language_group = parser.add_mutually_exclusive_group(required=True)
language_group.add_argument('-l', '--language', choices=SUPPORTED_LANGUAGES,\
help='Language that should be extracted, e.g. ja-JP')
language_group.add_argument('-a', '--all-languages', action='store_true')
parser.add_argument('-v', '--verbose', action='store_true', default=False,\
help='Maximize information printed on screen')
parser.add_argument('-m', '--missing', action='store_true', default=False,\
help='Only dump keys with missing translation')
return parser
def parse_required_switch_pairs(args):
""" Make sure only valid switch pairs are used """
single_language = args.language and args.dumpfile
all_languages = args.all_languages and args.target_dir
if not single_language and not all_languages:
print(f"Invalid switch pair. Use '-l <lang> -d <file>' or '-a -t <target_dir>")
sys.exit()
def add_key_value(strings_by_object, obj_id, key, value):
""" Add key-value pair to id entry in dict, initializing id if not valid """
if not obj_id in strings_by_object:
strings_by_object[obj_id] = {}
strings_by_object[obj_id][key] = value
def extract_translations(language_to_extract, args, filename, strings_by_object):
""" Read JSON file and extracts translations for a given language """
fallback_language = args.fallback
verbose = args.verbose
reference_str_count = 0
translated_str_count = 0
with open(filename, encoding="utf8") as file:
data = json.load(file)
if not 'strings' in data:
print(f"No strings in {data['id']}, skipping")
return (translated_str_count, reference_str_count)
for string_key in data['strings']:
if fallback_language in data['strings'][string_key]:
fallback_translation = data['strings'][string_key][fallback_language]
else:
fallback_translation = ""
if language_to_extract in data['strings'][string_key]:
if verbose:
print(f"Found existing translation for {data['id']}")
current_translation = data['strings'][string_key][language_to_extract]
ref_key = f'reference-{string_key}'
if not args.missing:
add_key_value(strings_by_object, data['id'], ref_key, fallback_translation)
add_key_value(strings_by_object, data['id'], string_key, current_translation)
reference_str_count += 1
translated_str_count += 1
elif fallback_language in data['strings'][string_key]:
if verbose:
print(f"No existing translation for {data['id']} yet,"
f" using {fallback_language}")
ref_key = f'reference-{string_key}'
add_key_value(strings_by_object, data['id'], ref_key, fallback_translation)
add_key_value(strings_by_object, data['id'], string_key, fallback_translation)
reference_str_count += 1
else:
if verbose:
print(f"No existing translation for {data['id']} yet,"
f" but no {fallback_language} string either -- skipping")
return (translated_str_count, reference_str_count)
def dump_translation(language_to_extract, args, dump_file_name):
""" Dump a language translation for OpenRCT2's JSON objects """
strings_by_object = {}
reference_str_count = 0
translated_str_count = 0
for filename in glob.iglob(args.objects + '/**/*.json', recursive=True):
obj_translations, ref_obj_translation =\
extract_translations(language_to_extract, args, filename, strings_by_object)
reference_str_count += ref_obj_translation
translated_str_count += obj_translations
translation_progress = round(100 * translated_str_count / reference_str_count, 2)
print(f'{language_to_extract}: {translation_progress}% completeness')
# Sort output by object ids (dict keys)
strings_by_object = dict(sorted(strings_by_object.items()))
out = open(dump_file_name, "w", encoding="utf8")
json.dump(strings_by_object, out, indent=4, ensure_ascii=False, separators=(',', ': '))
out.write("\n")
out.close()
def dump_translations():
""" Dump translations for OpenRCT2's JSON objects """
parser = get_arg_parser()
args = parser.parse_args()
parse_required_switch_pairs(args)
languages_to_extract = SUPPORTED_LANGUAGES if args.all_languages else [args.language]
for lang in languages_to_extract:
dump_file_name = f'{args.target_dir}/{lang}.json' if args.all_languages else args.dumpfile
dump_translation(lang, args, dump_file_name)
if __name__ == "__main__":
dump_translations()