From 5cb788e8f8931492a17e1b1400d9c20029dd695a Mon Sep 17 00:00:00 2001 From: Nicola Benaglia Date: Sat, 7 Jun 2025 17:09:55 +0200 Subject: [PATCH] Update script: now choose file and targer language --- scripts/i18n_translate_json.py | 90 +++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 35 deletions(-) diff --git a/scripts/i18n_translate_json.py b/scripts/i18n_translate_json.py index 98fd101..e0f8cb5 100644 --- a/scripts/i18n_translate_json.py +++ b/scripts/i18n_translate_json.py @@ -1,61 +1,81 @@ import os import json +import time from deep_translator import GoogleTranslator -from concurrent.futures import ThreadPoolExecutor, as_completed # === CONFIGURATION === -base_folder = "../src/i18n/locales" +base_folder = "./src/i18n/locales" source_lang = "en" -target_langs = ["de", "es", "fr", "it", "ja", "ru", "zh_CN"] filenames = ["auth.json", "core.json", "group.json", "question.json", "tutorial.json"] -max_workers = 12 # Adjust based on your CPU -# === TRANSLATION FUNCTION === -def translate_json(obj, target_lang): - if isinstance(obj, dict): - return {k: translate_json(v, target_lang) for k, v in obj.items()} - elif isinstance(obj, list): - return [translate_json(item, target_lang) for item in obj] - elif isinstance(obj, str): - if "{{" in obj or "}}" in obj or "<" in obj: - return obj # Skip templating/markup + +# === SAFE TRANSLATION === +def safe_translate(translator, text, retries=3): + for attempt in range(retries): try: - return GoogleTranslator(source='en', target=target_lang).translate(text=obj) + return translator.translate(text=text) except Exception as e: - print(f"[{target_lang}] Error: {e}") + if attempt < retries - 1: + time.sleep(2) + else: + print(f"[{translator.target}] Failed to translate '{text}': {e}") + return text + + +# === TRANSLATION LOGIC === +def translate_json(obj, translator): + if isinstance(obj, dict): + return {k: translate_json(v, translator) for k, v in obj.items()} + elif isinstance(obj, list): + return [translate_json(item, translator) for item in obj] + elif isinstance(obj, str): + if not obj.strip() or "{{" in obj or "}}" in obj or "<" in obj: return obj + return safe_translate(translator, obj) return obj -# === WORKER FUNCTION === -def translate_file_for_lang(filename, data, lang): - print(f"🔁 Translating {filename} → {lang}") - translated = translate_json(data, lang) - target_dir = os.path.join(base_folder, lang) + +# === FILE TRANSLATION === +def translate_file(filename, target_lang): + source_path = os.path.join(base_folder, source_lang, filename) + if not os.path.isfile(source_path): + print(f"❌ File not found: {source_path}") + return + + with open(source_path, "r", encoding="utf-8") as f: + data = json.load(f) + + print(f"🔁 Translating {filename} → {target_lang}") + translator = GoogleTranslator(source=source_lang, target=target_lang) + translated = translate_json(data, translator) + + target_dir = os.path.join(base_folder, target_lang) os.makedirs(target_dir, exist_ok=True) target_path = os.path.join(target_dir, filename) + with open(target_path, "w", encoding="utf-8") as f: json.dump(translated, f, ensure_ascii=False, indent=2) - print(f"✅ Saved {target_path}") - return target_path + + print(f"✅ Saved: {target_path}") + # === MAIN FUNCTION === def main(): - tasks = [] - with ThreadPoolExecutor(max_workers=max_workers) as executor: - for filename in filenames: - source_path = os.path.join(base_folder, source_lang, filename) - if not os.path.isfile(source_path): - print(f"⚠️ Missing file: {source_path}") - continue + print("Available files:") + for name in filenames: + print(f" - {name}") + filename = input("Enter the filename to translate: ").strip() + if filename not in filenames: + print(f"❌ Invalid filename: {filename}") + return - with open(source_path, "r", encoding="utf-8") as f: - data = json.load(f) + target_lang = input("Enter the target language code (e.g., de, fr, ja): ").strip() + if not target_lang: + print("❌ No target language provided.") + return - for lang in target_langs: - tasks.append(executor.submit(translate_file_for_lang, filename, data, lang)) + translate_file(filename, target_lang) - for future in as_completed(tasks): - _ = future.result() if __name__ == "__main__": main()