141 lines
3.9 KiB
Python
141 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Rebuild data/app_ui_strings.json from coach-visible Android code only."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
APP_JAVA = ROOT / "Questionnaire-App" / "app" / "src" / "main"
|
|
LM_FILE = APP_JAVA / "java" / "com" / "dano" / "test1" / "utils" / "LanguageManager.kt"
|
|
OUT = Path(__file__).resolve().parents[1] / "data" / "app_ui_strings.json"
|
|
|
|
DEV_KT = {
|
|
"DevSettingsActivity.kt",
|
|
"DatabaseButtonHandler.kt",
|
|
"SaveButtonHandler.kt",
|
|
"HeaderOrderRepository.kt",
|
|
"ExcelExportService.kt",
|
|
}
|
|
|
|
DEV_ONLY_KEYS = {
|
|
"database",
|
|
"database_clients_title",
|
|
"download_header",
|
|
"export_success_downloads",
|
|
"export_failed",
|
|
"headers",
|
|
"view_missing",
|
|
"no_header_template_found",
|
|
"saved_pdf_csv",
|
|
"no_pdf_viewer",
|
|
"save_error",
|
|
"no_clients_available",
|
|
"questionnaire_id",
|
|
"questionnaires",
|
|
"status",
|
|
"data",
|
|
"data_final_warning",
|
|
"open_client_via_load",
|
|
"ask_before_upload",
|
|
"You have completed questionnaires that have not been uploaded yet.",
|
|
"You have completed questionnaires that have not been uploaded yet. Tap to open the app and upload.",
|
|
}
|
|
|
|
EXTRA_COACH_KEYS = {
|
|
"save",
|
|
"please_client_code",
|
|
"choose_more_elements",
|
|
"previous",
|
|
"client",
|
|
"question",
|
|
"answer",
|
|
"no_questionnaires",
|
|
"no_questions_available",
|
|
"error",
|
|
"client_code",
|
|
"cancel",
|
|
"ok",
|
|
"not_done",
|
|
"none",
|
|
}
|
|
|
|
|
|
def parse_german_defaults(text: str) -> dict[str, str]:
|
|
out: dict[str, str] = {}
|
|
in_german = False
|
|
for line in text.splitlines():
|
|
if '"GERMAN" to mapOf(' in line:
|
|
in_german = True
|
|
continue
|
|
if not in_german:
|
|
continue
|
|
m = re.match(r'\s*"([^"]+)"\s+to\s+"(.*)",?\s*$', line)
|
|
if m:
|
|
key = m.group(1)
|
|
val = m.group(2).replace("\\n", "\n").replace('\\"', '"')
|
|
out[key] = val
|
|
elif line.strip().startswith("),") or ('"ENGLISH"' in line and "mapOf" in line):
|
|
break
|
|
return out
|
|
|
|
|
|
def extract_keys(text: str) -> set[str]:
|
|
keys: set[str] = set()
|
|
patterns = [
|
|
r'LanguageManager\.getText(?:Formatted)?\(\s*[^,]+,\s*"([^"]+)"',
|
|
r'LanguageManager\.getText(?:Formatted)?\(\s*"([^"]+)"\s*,\s*"([^"]+)"',
|
|
r'\bt\(\s*"([^"]+)"\s*\)',
|
|
r'\bt\(\s*lang\s*,\s*"([^"]+)"',
|
|
]
|
|
for pat in patterns:
|
|
for m in re.finditer(pat, text):
|
|
keys.add(m.group(m.lastindex))
|
|
return keys
|
|
|
|
|
|
def main() -> None:
|
|
de_defaults = parse_german_defaults(LM_FILE.read_text(encoding="utf-8"))
|
|
old = json.loads(OUT.read_text(encoding="utf-8")) if OUT.exists() else {}
|
|
old_def = old.get("germanDefaults", {})
|
|
|
|
coach: set[str] = set(EXTRA_COACH_KEYS)
|
|
dev: set[str] = set()
|
|
|
|
for kt in (APP_JAVA / "java").rglob("*.kt"):
|
|
keys = extract_keys(kt.read_text(encoding="utf-8", errors="ignore"))
|
|
if kt.name in DEV_KT:
|
|
dev |= keys
|
|
else:
|
|
coach |= keys
|
|
|
|
for xml in (APP_JAVA / "res" / "layout").rglob("*.xml"):
|
|
for m in re.finditer(r'android:tag="([^"]+)"', xml.read_text(encoding="utf-8", errors="ignore")):
|
|
coach.add(m.group(1))
|
|
|
|
for month in (
|
|
"january", "february", "march", "april", "may", "june",
|
|
"july", "august", "september", "october", "november", "december",
|
|
):
|
|
coach.add(month)
|
|
|
|
keys = sorted(coach - dev - DEV_ONLY_KEYS)
|
|
german_defaults = {
|
|
k: de_defaults.get(k) or old_def.get(k) or k for k in keys
|
|
}
|
|
|
|
payload = {
|
|
"version": 2,
|
|
"description": "Coach-visible app UI strings only (excludes dev settings / database tools).",
|
|
"keys": keys,
|
|
"germanDefaults": german_defaults,
|
|
}
|
|
OUT.write_text(json.dumps(payload, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
print(f"Wrote {len(keys)} keys to {OUT}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|