Skip to content

Instantly share code, notes, and snippets.

@sepgh
Last active July 8, 2024 23:50
Show Gist options
  • Save sepgh/8cb7e43608be3e77fd837d85e16b3ed9 to your computer and use it in GitHub Desktop.
Save sepgh/8cb7e43608be3e77fd837d85e16b3ed9 to your computer and use it in GitHub Desktop.
A Django command to automatically add translations to po files
import json
import requests
from django.core.management.base import BaseCommand
from os.path import exists
import polib
class Command(BaseCommand):
"""
Complete missing and fuzzy translations of po files
"""
def add_arguments(self, parser):
parser.add_argument("file", type=str)
parser.add_argument("from_language", type=str)
parser.add_argument("to_language", type=str)
def handle(self, *args, **kwargs):
po_file = kwargs.get("file")
from_lang = kwargs.get("from_language")
to_lang = kwargs.get("to_language")
if not exists(po_file):
self.stdout.write("PO file does not exist: " + po_file)
return
po = polib.pofile(po_file)
self.stdout.write("Percentage of translations: " + str(po.percent_translated()))
if po.percent_translated() == 100:
self.stdout.write("DONE!")
return
lines = self.get_file_lines_as_list(po_file)
for entry in po.untranslated_entries() + po.fuzzy_entries():
translation = self.translate(entry.msgid, to_lang, from_lang)
if translation:
self.set_value_of_msgid(entry.msgid, translation, lines)
self.stdout.write(
"[Translated] " + entry.msgid + " -> " + translation
)
else:
self.stdout.write("[Skipping] " + entry.msgid)
self.stdout.write("Finished translating. Updating po file ...")
with open(po_file, "w") as fp:
for line in lines:
# write each item on a new line
if line not in [
"#, fuzzy",
] and not line.startswith("#|"):
fp.write("%s\n" % line)
self.stdout.write("Finished updating po file")
self.stdout.write("Done :) please check the PO file since this script can also break things :-s")
def get_file_lines_as_list(self, filename):
with open(filename) as file:
lines_ = file.readlines()
lines_ = [line_.rstrip() for line_ in lines_]
return lines_
def find_index_of_message(self, msgid_, lines_):
for i in range(0, len(lines_)):
line_: str = lines_[i]
if line_.startswith('msgid "' + msgid_):
return i
return -1
def set_value_of_msgid(self, msgid_, value_, lines_):
i_ = self.find_index_of_message(msgid_, lines_)
if i_ == -1:
return
lines_[i_ + 1] = 'msgstr "{value}"'.format(value=value_)
def translate(self, text_, to_lang_, from_lang_="en"):
api = "https://api.mymemory.translated.net/get?q={text}!&langpair={from_}|{to_}".format(
text=text_, from_=from_lang_, to_=to_lang_
)
response_ = requests.get(api)
response_json = json.loads(response_.text)
if (
"responseData" in response_json
and "translatedText" in response_json["responseData"]
):
return response_json["responseData"]["translatedText"]
return None
@sepgh
Copy link
Author

sepgh commented Jun 9, 2022

You have to install it as django management command. So under a relative application of your Django project, create a directory called management and place this script there. You can later run it with:

python manage.py potranslate {PATH_TO_PO_FILE} {LANGUAGE FROM} {LANGUAGE TO}

Example:

./manage.py potranslate ./locale/de/LC_MESSAGES/django.po en de

@fayomihorace
Copy link

This is awesome. Thanks a lot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment