2023-01-04 21:36:26 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
import sys
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import polib
|
2023-01-05 19:12:35 +01:00
|
|
|
import json
|
2023-01-04 21:36:26 +01:00
|
|
|
from babel.messages.frontend import main as pybabel
|
|
|
|
from libretranslate.language import load_languages, improve_translation_formatting
|
|
|
|
from libretranslate.locales import get_available_locales
|
|
|
|
from translatehtml import translate_html
|
2023-01-04 23:54:07 +01:00
|
|
|
from libretranslate.app import get_version
|
2023-01-04 21:36:26 +01:00
|
|
|
|
|
|
|
# Update strings
|
|
|
|
if __name__ == "__main__":
|
2023-01-05 19:12:35 +01:00
|
|
|
print("Loading languages")
|
|
|
|
languages = load_languages()
|
|
|
|
en_lang = next((l for l in languages if l.code == 'en'), None)
|
|
|
|
if en_lang is None:
|
|
|
|
print("Error: English model not found. You need it to run this script.")
|
|
|
|
exit(1)
|
|
|
|
|
2023-01-04 21:36:26 +01:00
|
|
|
locales_dir = os.path.join("libretranslate", "locales")
|
|
|
|
if not os.path.isdir(locales_dir):
|
|
|
|
os.makedirs(locales_dir)
|
|
|
|
|
2023-01-05 19:12:35 +01:00
|
|
|
# Dump language list so it gets picked up by pybabel
|
|
|
|
langs_file = os.path.join(locales_dir, ".langs.py")
|
|
|
|
with open(langs_file, 'w') as f:
|
|
|
|
for l in languages:
|
|
|
|
f.write("_(%s)\n" % json.dumps(l.name))
|
|
|
|
print("Wrote %s" % langs_file)
|
|
|
|
|
2023-01-04 21:36:26 +01:00
|
|
|
messagespot = os.path.join(locales_dir, "messages.pot")
|
|
|
|
print("Updating %s" % messagespot)
|
2023-01-04 23:54:07 +01:00
|
|
|
sys.argv = ["", "extract", "-F", "babel.cfg", "-k", "_e _h",
|
|
|
|
"--copyright-holder", "LibreTranslate Authors",
|
|
|
|
"--project", "LibreTranslate",
|
|
|
|
"--version", get_version(),
|
|
|
|
"-o", messagespot, "libretranslate"]
|
2023-01-04 21:36:26 +01:00
|
|
|
pybabel()
|
|
|
|
|
2023-01-05 19:12:35 +01:00
|
|
|
|
2023-01-04 21:36:26 +01:00
|
|
|
|
|
|
|
lang_codes = [l.code for l in languages if l != "en"]
|
|
|
|
lang_codes = ["it"] # TODO REMOVE
|
|
|
|
|
|
|
|
# Init/update
|
|
|
|
for l in lang_codes:
|
|
|
|
cmd = "init"
|
|
|
|
if os.path.isdir(os.path.join(locales_dir, l)):
|
|
|
|
cmd = "update"
|
|
|
|
|
|
|
|
sys.argv = ["", cmd, "-i", messagespot, "-d", locales_dir, "-l", l]
|
|
|
|
pybabel()
|
|
|
|
|
|
|
|
# Automatically translate strings with libretranslate
|
|
|
|
# when a language model is available and a string is empty
|
|
|
|
|
|
|
|
locales = get_available_locales()
|
|
|
|
for locale in locales:
|
|
|
|
if locale == 'en':
|
|
|
|
continue
|
|
|
|
|
|
|
|
tgt_lang = next((l for l in languages if l.code == locale), None)
|
|
|
|
|
|
|
|
if tgt_lang is None:
|
|
|
|
# We cannot translate
|
|
|
|
continue
|
|
|
|
|
|
|
|
translator = en_lang.get_translation(tgt_lang)
|
|
|
|
|
|
|
|
messages_file = os.path.join(locales_dir, locale, "LC_MESSAGES", 'messages.po')
|
|
|
|
if os.path.isfile(messages_file):
|
|
|
|
print("Translating '%s'" % locale)
|
|
|
|
pofile = polib.pofile(messages_file)
|
|
|
|
c = 0
|
|
|
|
|
|
|
|
for entry in pofile.untranslated_entries():
|
|
|
|
text = entry.msgid
|
|
|
|
|
|
|
|
# Extract placeholders
|
2023-01-05 19:12:35 +01:00
|
|
|
placeholders = re.findall(r'%\(?[^\)]*\)?s', text)
|
2023-01-04 21:36:26 +01:00
|
|
|
|
|
|
|
for p in range(0, len(placeholders)):
|
|
|
|
text = text.replace(placeholders[p], "<x>%s</x>" % p)
|
|
|
|
|
|
|
|
if len(placeholders) > 0:
|
|
|
|
translated = str(translate_html(translator, text))
|
|
|
|
else:
|
|
|
|
translated = improve_translation_formatting(text, translator.translate(text))
|
2023-01-05 19:12:35 +01:00
|
|
|
|
2023-01-04 21:36:26 +01:00
|
|
|
# Restore placeholders
|
|
|
|
for p in range(0, len(placeholders)):
|
|
|
|
tag = "<x>%s</x>" % p
|
|
|
|
if tag in translated:
|
|
|
|
translated = translated.replace(tag, placeholders[p])
|
|
|
|
else:
|
|
|
|
# Meh, append
|
|
|
|
translated += " " + placeholders[p]
|
|
|
|
|
|
|
|
print(entry.msgid, " --> ", translated)
|
|
|
|
entry.msgstr = translated
|
|
|
|
c += 1
|
|
|
|
|
|
|
|
if c > 0:
|
|
|
|
pofile.save(messages_file)
|
|
|
|
print("Saved %s" % messages_file)
|
|
|
|
|
|
|
|
|
|
|
|
|