|
| 1 | +""" |
| 2 | +Update empty translations. |
| 3 | +
|
| 4 | +To run this script: |
| 5 | +* pip install polib deepl |
| 6 | +* DEEPL_API_TOKEN=.... python update_translations.py |
| 7 | +
|
| 8 | +This will process all .po files in this directory, translating any |
| 9 | +untranslated strings, marking them as "fuzzy" translations. |
| 10 | +""" |
| 11 | +import polib |
| 12 | +import deepl |
| 13 | +import os |
| 14 | +import re |
| 15 | +from pathlib import Path |
| 16 | + |
| 17 | + |
| 18 | +def translate(text, lang, api_token): |
| 19 | + # Define a dictionary to hold the mappings of tokens to placeholders |
| 20 | + placeholders = {} |
| 21 | + |
| 22 | + # Use a regular expression to find all the tokens |
| 23 | + tokens = re.findall(r'%\((.*?)\)s', text) |
| 24 | + |
| 25 | + # Replace each token with a unique placeholder |
| 26 | + for i, token in enumerate(tokens): |
| 27 | + placeholder = f'__PLACEHOLDER_{i}__' |
| 28 | + placeholders[placeholder] = f'%({token})s' |
| 29 | + text = text.replace(f'%({token})s', placeholder) |
| 30 | + |
| 31 | + # Perform the translation |
| 32 | + translator = deepl.Translator(api_token) |
| 33 | + translated_text = str(translator.translate_text(text, target_lang=lang)) |
| 34 | + |
| 35 | + # Replace the placeholders back with the original tokens |
| 36 | + for placeholder, token in placeholders.items(): |
| 37 | + translated_text = translated_text.replace(placeholder, token) |
| 38 | + |
| 39 | + return translated_text |
| 40 | + |
| 41 | + |
| 42 | +def process_file(filename, lang, api_token): |
| 43 | + po = polib.pofile(filename) |
| 44 | + for entry in po.untranslated_entries(): |
| 45 | + if not entry.msgstr: |
| 46 | + print(f"EN >>> {entry.msgid}") |
| 47 | + print('---------------------------------------------') |
| 48 | + entry.msgstr = translate(entry.msgid, lang, api_token) |
| 49 | + entry.fuzzy = True |
| 50 | + print(f"{lang} <<< {entry.msgstr}") |
| 51 | + print("\n") |
| 52 | + po.save(filename) |
| 53 | + |
| 54 | + |
| 55 | +if __name__ == '__main__': |
| 56 | + try: |
| 57 | + api_token = os.environ["DEEPL_API_TOKEN"] |
| 58 | + except KeyError: |
| 59 | + print("Export DEEPL_API_TOKEN into the environment") |
| 60 | + else: |
| 61 | + i18n = Path() |
| 62 | + for filename in i18n.glob("contents+*.po"): |
| 63 | + lang = filename.name.split("+")[1].split(".")[0] |
| 64 | + # We don't need to translate English. |
| 65 | + # Farsi isn't a valid target language for DeepL. |
| 66 | + if lang not in {"en", "fa"}: |
| 67 | + # Map ISO language codes to the DeepL target codes |
| 68 | + target_lang = { |
| 69 | + "pt": "pt-br", |
| 70 | + "zh_CN": "zh-HANS", |
| 71 | + "zh_TW": "zh-HANT", |
| 72 | + }.get(lang, lang) |
| 73 | + print(f"===== Processing {target_lang} =====") |
| 74 | + process_file(str(i18n / filename), target_lang, api_token) |
0 commit comments