Skip to content

Commit 3007096

Browse files
authored
asset translation status
1 parent c1870b3 commit 3007096

File tree

4 files changed

+371
-112
lines changed

4 files changed

+371
-112
lines changed

.github/update.py

+65-13
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,57 @@
11
import urllib.request
22
import re
3+
import json_repair
34
import os
45
import json5
56
import xml.etree.ElementTree as ET
67
from mdutils.mdutils import MdUtils
78
import pandas as pd
89

10+
# https://stackoverflow.com/a/18381470 (Onur Yıldırım, CC BY-SA 4.0)
11+
def remove_comments(string):
12+
pattern = r"(\".*?\"|\'.*?\')|(/\*.*?\*/|//[^\r\n]*$)"
13+
# first group captures quoted strings (double or single)
14+
# second group captures comments (//single-line or /* multi-line */)
15+
regex = re.compile(pattern, re.MULTILINE|re.DOTALL)
16+
def _replacer(match):
17+
# if the 2nd group (capturing comments) is not None,
18+
# it means we have captured a non-quoted (real) comment string.
19+
if match.group(2) is not None:
20+
return "" # so we will return empty to remove the comment
21+
else: # otherwise, we will return the 1st group
22+
return match.group(1) # captured quoted-string
23+
return regex.sub(_replacer, string)
24+
25+
def load_vcmi_json(string):
26+
try:
27+
obj = json5.loads(string)
28+
except:
29+
tmp = remove_comments(string.decode())
30+
obj = json_repair.loads(tmp)
31+
32+
return obj
33+
934
def get_languages():
1035
with urllib.request.urlopen('https://raw.githubusercontent.com/vcmi/vcmi/develop/lib/Languages.h') as f:
1136
src = f.read().decode('utf-8')
1237
languages = [x for x in re.findall(r"{ ?\"([\w]*)?\" ?,", src, re.IGNORECASE) if "other" not in x]
1338
return languages
1439

1540
def get_base_mod():
16-
return json5.loads(urllib.request.urlopen('https://raw.githubusercontent.com/vcmi/vcmi/develop/Mods/vcmi/mod.json').read())
41+
return load_vcmi_json(urllib.request.urlopen('https://raw.githubusercontent.com/vcmi/vcmi/develop/Mods/vcmi/mod.json').read())
1742

1843
def base_mod_existing(languages):
1944
vcmi_base_mod = get_base_mod()
2045
return {value:(value in vcmi_base_mod) for value in languages}
2146

2247
def base_mod_ratio(languages):
2348
base_mod = get_base_mod()
24-
translation_english = json5.loads(urllib.request.urlopen('https://raw.githubusercontent.com/vcmi/vcmi/develop/Mods/vcmi/' + base_mod["translations"][0]).read())
49+
translation_english = load_vcmi_json(urllib.request.urlopen('https://raw.githubusercontent.com/vcmi/vcmi/develop/Mods/vcmi/' + base_mod["translations"][0]).read())
2550

2651
data = {}
2752

2853
for language in [key for key, value in base_mod_existing(languages).items() if value == True]:
29-
translation = json5.loads(urllib.request.urlopen('https://raw.githubusercontent.com/vcmi/vcmi/develop/Mods/vcmi/' + next(value for key, value in base_mod.items() if key == language)["translations"][0]).read())
54+
translation = load_vcmi_json(urllib.request.urlopen('https://raw.githubusercontent.com/vcmi/vcmi/develop/Mods/vcmi/' + next(value for key, value in base_mod.items() if key == language)["translations"][0]).read())
3055
count_equal = 0
3156
count_difference = 0
3257
count_only_english = 0
@@ -43,9 +68,9 @@ def base_mod_ratio(languages):
4368
return data
4469

4570
def get_mod_repo():
46-
settings_schema = json5.loads(urllib.request.urlopen("https://raw.githubusercontent.com/vcmi/vcmi/develop/config/schemas/settings.json").read())
71+
settings_schema = load_vcmi_json(urllib.request.urlopen("https://raw.githubusercontent.com/vcmi/vcmi/develop/config/schemas/settings.json").read())
4772
vcmi_mod_url = settings_schema["properties"]["launcher"]["properties"]["defaultRepositoryURL"]["default"]
48-
vcmi_mods = json5.loads(urllib.request.urlopen(vcmi_mod_url).read())
73+
vcmi_mods = load_vcmi_json(urllib.request.urlopen(vcmi_mod_url).read())
4974
return vcmi_mods
5075

5176
def get_translation_mods():
@@ -55,7 +80,7 @@ def get_translation_mods():
5580

5681
for key, value in vcmi_mods.items():
5782
url = value["mod"].replace(" ", "%20")
58-
mod = json5.loads(urllib.request.urlopen(url).read())
83+
mod = load_vcmi_json(urllib.request.urlopen(url).read())
5984
if "language" in mod:
6085
vcmi_translation_mods[mod["language"]] = (url, mod)
6186

@@ -72,10 +97,34 @@ def get_translation_mods_translation():
7297
tmp_str = urllib.request.urlopen(base_url + item).read()
7398
except:
7499
tmp_str = urllib.request.urlopen((base_url + item).replace("content", "Content").replace("config", "Config")).read()
75-
tmp |= json5.loads(tmp_str)
100+
tmp |= load_vcmi_json(tmp_str)
76101
data[key] = tmp
77102
return data
78103

104+
def get_translation_mods_translation_assets():
105+
translation_mods = get_translation_mods()
106+
data = {}
107+
for key, value in translation_mods.items():
108+
repo = re.search(r"vcmi-mods\/(.*?)\/", value[0]).group(1)
109+
branch = re.search(repo + r"\/([^\/]*?)\/", value[0]).group(1)
110+
files_api = "https://api.github.com/repos/vcmi-mods/" + repo + "/git/trees/" + branch + "?recursive=1"
111+
files = [x["path"].lower() for x in json5.loads(urllib.request.urlopen(files_api).read())["tree"]]
112+
files_filtered = [x for x in files if "mods/" not in x]
113+
114+
files_to_translate = json5.load(open("files_to_translated.json", "r"))
115+
files_ct = {}
116+
files_found = {}
117+
for file in files_to_translate:
118+
type = re.search(r"content\/(.*?)\/", file).group(1)
119+
if type not in files_ct: files_ct[type] = 0
120+
if type not in files_found: files_found[type] = 0
121+
files_ct[type] += 1
122+
files_found[type] += 1 if any([file in x for x in files_filtered]) else 0
123+
files_ratio = {k: files_found[k]/v for k, v in files_ct.items()}
124+
125+
data[key] = files_ratio
126+
return data
127+
79128
def translation_mod_ratio(translation_mods_translation):
80129
translation_english = translation_mods_translation["english"]
81130

@@ -129,7 +178,7 @@ def get_mod_translations(languages):
129178
data = {}
130179
for key, value in vcmi_mods.items():
131180
url = value["mod"].replace(" ", "%20")
132-
mod = json5.loads(urllib.request.urlopen(url).read())
181+
mod = load_vcmi_json(urllib.request.urlopen(url).read())
133182
if "language" not in mod:
134183
found_languages = []
135184
for language in languages:
@@ -153,30 +202,33 @@ def format_value(percent):
153202
return "$\\color{green}{\\textsf{" + str(round(percent * 100, 1)) + " \\%" + "}}$"
154203

155204
md.new_header(level=1, title="VCMI translations")
156-
md.new_line("This tables shows the current translation progress of VCMI. Contains only the state of the translation strings, not for the assets.")
205+
md.new_line("This tables shows the current translation progress of VCMI. See [here](https://github.com/vcmi/vcmi/blob/develop/docs/modders/Translations.md) how to translate VCMI. See assets for translation [here](files_to_translated.json) (not every language need each asset).")
157206

158207
md.new_header(level=2, title="Main translation")
159208
tmp = base_mod_ratio(languages_translate)
160-
df = pd.DataFrame({"Area": "Main-Repo"} | {x:([format_value(tmp[x]["ratio"])] if x in tmp else [format_value(0)]) for x in languages_translate})
209+
df = pd.DataFrame({"Area": "[Main-Repo](https://github.com/vcmi/vcmi)"} | {x:([format_value(tmp[x]["ratio"])] if x in tmp else [format_value(0)]) for x in languages_translate})
161210
tmp = translation_mod_ratio(get_translation_mods_translation())
162211
for area in list(tmp.values())[0].keys():
163-
df = pd.concat([df, pd.DataFrame({"Area": "Mod-Repo" + (' main' if area == None else ' ' + area)} | {x:([format_value(tmp[x][area]["ratio"])] if x in tmp else [format_value(0)]) for x in languages_translate})], ignore_index=True)
212+
df = pd.concat([df, pd.DataFrame({"Area": "[Mod-Repo](https://github.com/vcmi-mods)" + (' game' if area == None else ' ' + area)} | {x:([format_value(tmp[x][area]["ratio"])] if x in tmp else [format_value(0)]) for x in languages_translate})], ignore_index=True)
213+
tmp = get_translation_mods_translation_assets()
214+
for area in list(tmp.values())[0].keys():
215+
df = pd.concat([df, pd.DataFrame({"Area": "[Mod-Repo](https://github.com/vcmi-mods)" + (' Assets: ' + area)} | {x:([format_value(tmp[x][area])] if x in tmp else [format_value(0)]) for x in languages_translate})], ignore_index=True)
164216
df = df.T.reset_index().T
165217
md.new_table(columns=df.shape[1], rows=df.shape[0], text=df.to_numpy().flatten(), text_align='center')
166218

167219
md.new_header(level=2, title="QT tools translation")
168220
tmp = get_qt_translations(languages_translate)
169221
df = pd.DataFrame(columns=["Tool"] + languages_translate)
170222
for tool in list(tmp.values())[0].keys():
171-
df = pd.concat([df, pd.DataFrame({"Tool": tool} | {x:[format_value(tmp[x][tool]["ratio"])] if x in tmp else [format_value(0)] for x in languages_translate})], ignore_index=True)
223+
df = pd.concat([df, pd.DataFrame({"Tool": "[" + tool + "](https://github.com/vcmi/vcmi/tree/develop/" + tool + "/translation)"} | {x:[format_value(tmp[x][tool]["ratio"])] if x in tmp else [format_value(0)] for x in languages_translate})], ignore_index=True)
172224
df = df.T.reset_index().T
173225
md.new_table(columns=df.shape[1], rows=df.shape[0], text=df.to_numpy().flatten(), text_align='center')
174226

175227
md.new_header(level=2, title="Mod translations")
176228
tmp = get_mod_translations(languages_translate)
177229
df = pd.DataFrame(columns=["Mod"] + languages_translate)
178230
for mod in tmp:
179-
df = pd.concat([df, pd.DataFrame({"Mod": mod} | {x:["x" if x in tmp[mod] else ""] for x in languages_translate})], ignore_index=True)
231+
df = pd.concat([df, pd.DataFrame({"Mod": "[" + mod + "](https://github.com/vcmi-mods/" + mod.replace(" ", "-") + ")"} | {x:["x" if x in tmp[mod] else ""] for x in languages_translate})], ignore_index=True)
180232
df = df.T.reset_index().T
181233
md.new_table(columns=df.shape[1], rows=df.shape[0], text=df.to_numpy().flatten(), text_align='center')
182234

0 commit comments

Comments
 (0)