184 lines
6.2 KiB
Python
184 lines
6.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Genera qml/js/i18n.js e qml/js/catalog.js dai sorgenti Flutter di Henflow.
|
|
|
|
- i18n.js: le 4 mappe di traduzione (it/en/fr/de, 111 chiavi) estratte
|
|
verbatim da lib/app_language.dart + la funzione t(key, arg, lang).
|
|
- catalog.js: le 7 razze di lib/models/breed_catalog.dart con il path delle
|
|
foto installate nel datadir dell'app.
|
|
|
|
I file generati sono ES5 (motore QML di Qt 5.6) con guard module.exports.
|
|
"""
|
|
import json
|
|
import os
|
|
import re
|
|
|
|
SRC = "/home/kaneda/workspace/henflow-flutter"
|
|
DST = "/home/kaneda/workspace/harbour-henflow/qml/js"
|
|
|
|
LANGS = ["it", "en", "fr", "de"]
|
|
|
|
|
|
def dart_unescape(s):
|
|
out = []
|
|
i = 0
|
|
while i < len(s):
|
|
c = s[i]
|
|
if c == "\\" and i + 1 < len(s):
|
|
n = s[i + 1]
|
|
out.append({"n": "\n", "t": "\t", "r": "\r", "'": "'", '"': '"', "\\": "\\"}.get(n, n))
|
|
i += 2
|
|
else:
|
|
out.append(c)
|
|
i += 1
|
|
return "".join(out)
|
|
|
|
|
|
def extract_strings():
|
|
# NB: la tabella VIVA e' quella inline in main.dart (126 chiavi).
|
|
# app_language.dart e' una copia vecchia (111 chiavi, usata solo da
|
|
# lib/dialogs/confirm_dialogs.dart) con gli a capo scritti '\\n' invece
|
|
# che '\n': estrarla produrrebbe testi con un backslash visibile.
|
|
text = open(os.path.join(SRC, "lib/main.dart"), encoding="utf-8").read()
|
|
data = {}
|
|
for lang in LANGS:
|
|
m = re.search(r"AppLanguage\.%s:\s*\{(.*?)\n \}," % lang, text, re.S)
|
|
if not m:
|
|
raise SystemExit("blocco %s non trovato" % lang)
|
|
pairs = re.findall(r"'([a-z0-9_]+)':\s*'((?:[^'\\]|\\.)*)'", m.group(1))
|
|
data[lang] = {k: dart_unescape(v) for k, v in pairs}
|
|
print("%s: %d chiavi" % (lang, len(data[lang])))
|
|
|
|
# L'app non ha fallback: t() su chiave assente restituisce la CHIAVE
|
|
# (in francese la razza "generic" usciva come "name_generic"). Nel porting
|
|
# i buchi si colmano con l'inglese e si segnalano qui.
|
|
keys = set(data["en"])
|
|
for lang in LANGS:
|
|
if lang == "en":
|
|
continue
|
|
missing = sorted(keys - set(data[lang]))
|
|
extra = sorted(set(data[lang]) - keys)
|
|
if extra:
|
|
raise SystemExit("%s: chiavi non presenti in inglese: %s" % (lang, extra))
|
|
for k in missing:
|
|
data[lang][k] = data["en"][k]
|
|
if missing:
|
|
print(" %s: colmate dall'inglese %d chiavi: %s" % (lang, len(missing), missing))
|
|
return data, len(keys)
|
|
|
|
|
|
def extract_catalog():
|
|
text = open(os.path.join(SRC, "lib/models/breed_catalog.dart"), encoding="utf-8").read()
|
|
items = []
|
|
for block in re.findall(r"BreedCatalogItem\((.*?)\)\s*,?\s*(?=BreedCatalogItem|\];)", text, re.S):
|
|
def field(name):
|
|
m = re.search(r"%s:\s*'([^']*)'" % name, block)
|
|
return m.group(1) if m else None
|
|
def number(name):
|
|
m = re.search(r"%s:\s*([0-9.]+)" % name, block)
|
|
return float(m.group(1)) if m else None
|
|
asset = field("assetPath")
|
|
items.append({
|
|
"id": field("id"),
|
|
"name": field("name"),
|
|
"description": field("description"),
|
|
"eggColor": field("eggColor"),
|
|
"eggsPerHenPerDay": number("eggsPerHenPerDay"),
|
|
"asset": "/usr/share/harbour-henflow/" + asset.replace("assets/", ""),
|
|
})
|
|
return items
|
|
|
|
|
|
def js_value(v, indent=4):
|
|
return json.dumps(v, ensure_ascii=False, indent=indent)
|
|
|
|
|
|
def main():
|
|
data, nkeys = extract_strings()
|
|
os.makedirs(DST, exist_ok=True)
|
|
|
|
header = """// GENERATO da tools/gen_from_flutter.py — non modificare a mano.
|
|
// Traduzioni estratte verbatim da lib/app_language.dart dell'app Flutter
|
|
// (%d chiavi x %d lingue). ES5: il motore QML di Qt 5.6 non supporta
|
|
// let/const, arrow function, template literal.
|
|
|
|
var HF_STRINGS = %s;
|
|
|
|
// t(chiave, argomento, lingua): come il TranslationService dell'app,
|
|
// riempie il primo '{}' (o i successivi, con un array). Fallback: inglese,
|
|
// poi la chiave stessa.
|
|
function t(key, arg, lang) {
|
|
var table = HF_STRINGS[lang] || HF_STRINGS.en;
|
|
var text = table[key];
|
|
if (text === undefined) text = HF_STRINGS.en[key];
|
|
if (text === undefined) return key;
|
|
if (arg !== undefined && arg !== null) {
|
|
if (Object.prototype.toString.call(arg) === "[object Array]") {
|
|
for (var i = 0; i < arg.length; i++) {
|
|
text = text.replace("{}", String(arg[i]));
|
|
}
|
|
} else {
|
|
text = text.replace("{}", String(arg));
|
|
}
|
|
}
|
|
return text;
|
|
}
|
|
|
|
function availableLanguages() {
|
|
var out = [];
|
|
for (var k in HF_STRINGS) {
|
|
if (HF_STRINGS.hasOwnProperty(k)) out.push(k);
|
|
}
|
|
return out.sort();
|
|
}
|
|
|
|
// Lingua effettiva: 'system' segue la lingua del telefono (nome tipo "it_IT"),
|
|
// altrimenti si usa il codice scelto. Fallback: inglese.
|
|
function langFor(setting, systemName) {
|
|
if (setting && setting !== "system") {
|
|
return HF_STRINGS[setting] ? setting : "en";
|
|
}
|
|
var code = String(systemName || "").slice(0, 2).toLowerCase();
|
|
return HF_STRINGS[code] ? code : "en";
|
|
}
|
|
|
|
if (typeof module !== "undefined" && module.exports) {
|
|
module.exports = {
|
|
HF_STRINGS: HF_STRINGS,
|
|
t: t,
|
|
availableLanguages: availableLanguages,
|
|
langFor: langFor
|
|
};
|
|
}
|
|
""" % (nkeys, len(LANGS), js_value(data))
|
|
|
|
open(os.path.join(DST, "i18n.js"), "w", encoding="utf-8").write(header)
|
|
|
|
catalog = extract_catalog()
|
|
cat_js = """// GENERATO da tools/gen_from_flutter.py — non modificare a mano.
|
|
// Catalogo razze da lib/models/breed_catalog.dart: nome e descrizione sono
|
|
// chiavi di traduzione, le foto stanno nel datadir dell'app.
|
|
|
|
var HF_BREEDS = %s;
|
|
|
|
function breedFromId(id) {
|
|
for (var i = 0; i < HF_BREEDS.length; i++) {
|
|
if (HF_BREEDS[i].id === id) return HF_BREEDS[i];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
if (typeof module !== "undefined" && module.exports) {
|
|
module.exports = { HF_BREEDS: HF_BREEDS, breedFromId: breedFromId };
|
|
}
|
|
""" % json.dumps(catalog, ensure_ascii=False, indent=4)
|
|
open(os.path.join(DST, "catalog.js"), "w", encoding="utf-8").write(cat_js)
|
|
|
|
print("scritti: i18n.js (%d chiavi x %d lingue), catalog.js (%d razze)"
|
|
% (nkeys, len(LANGS), len(catalog)))
|
|
for c in catalog:
|
|
print(" ", c["id"], "->", c["asset"])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|