2019-09-10 00:54:28 +00:00
|
|
|
import os
|
|
|
|
import os.path as op
|
|
|
|
import shutil
|
|
|
|
import tempfile
|
|
|
|
|
|
|
|
import polib
|
|
|
|
|
|
|
|
from . import pygettext
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
LC_MESSAGES = "LC_MESSAGES"
|
2019-09-10 00:54:28 +00:00
|
|
|
|
|
|
|
# There isn't a 1-on-1 exact fit between .po language codes and cocoa ones
|
|
|
|
PO2COCOA = {
|
2020-01-01 02:16:27 +00:00
|
|
|
"pl_PL": "pl",
|
|
|
|
"pt_BR": "pt-BR",
|
|
|
|
"zh_CN": "zh-Hans",
|
2019-09-10 00:54:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
COCOA2PO = {v: k for k, v in PO2COCOA.items()}
|
|
|
|
|
2021-08-21 21:56:27 +00:00
|
|
|
STRING_EXT = ".strings"
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
def get_langs(folder):
|
|
|
|
return [name for name in os.listdir(folder) if op.isdir(op.join(folder, name))]
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
def files_with_ext(folder, ext):
|
|
|
|
return [op.join(folder, fn) for fn in os.listdir(folder) if fn.endswith(ext)]
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
def generate_pot(folders, outpath, keywords, merge=False):
|
|
|
|
if merge and not op.exists(outpath):
|
|
|
|
merge = False
|
|
|
|
if merge:
|
|
|
|
_, genpath = tempfile.mkstemp()
|
|
|
|
else:
|
|
|
|
genpath = outpath
|
|
|
|
pyfiles = []
|
|
|
|
for folder in folders:
|
|
|
|
for root, dirs, filenames in os.walk(folder):
|
2020-01-01 02:16:27 +00:00
|
|
|
keep = [fn for fn in filenames if fn.endswith(".py")]
|
2019-09-10 00:54:28 +00:00
|
|
|
pyfiles += [op.join(root, fn) for fn in keep]
|
|
|
|
pygettext.main(pyfiles, outpath=genpath, keywords=keywords)
|
|
|
|
if merge:
|
|
|
|
merge_po_and_preserve(genpath, outpath)
|
2021-03-18 00:55:00 +00:00
|
|
|
try:
|
|
|
|
os.remove(genpath)
|
|
|
|
except Exception:
|
|
|
|
print("Exception while removing temporary folder %s\n", genpath)
|
2019-09-10 00:54:28 +00:00
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
def compile_all_po(base_folder):
|
|
|
|
langs = get_langs(base_folder)
|
|
|
|
for lang in langs:
|
|
|
|
pofolder = op.join(base_folder, lang, LC_MESSAGES)
|
2020-01-01 02:16:27 +00:00
|
|
|
pofiles = files_with_ext(pofolder, ".po")
|
2019-09-10 00:54:28 +00:00
|
|
|
for pofile in pofiles:
|
|
|
|
p = polib.pofile(pofile)
|
2020-01-01 02:16:27 +00:00
|
|
|
p.save_as_mofile(pofile[:-3] + ".mo")
|
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
|
|
|
|
def merge_locale_dir(target, mergeinto):
|
|
|
|
langs = get_langs(target)
|
|
|
|
for lang in langs:
|
|
|
|
if not op.exists(op.join(mergeinto, lang)):
|
|
|
|
continue
|
|
|
|
mofolder = op.join(target, lang, LC_MESSAGES)
|
2020-01-01 02:16:27 +00:00
|
|
|
mofiles = files_with_ext(mofolder, ".mo")
|
2019-09-10 00:54:28 +00:00
|
|
|
for mofile in mofiles:
|
|
|
|
shutil.copy(mofile, op.join(mergeinto, lang, LC_MESSAGES))
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
def merge_pots_into_pos(folder):
|
|
|
|
# We're going to take all pot files in `folder` and for each lang, merge it with the po file
|
|
|
|
# with the same name.
|
2020-01-01 02:16:27 +00:00
|
|
|
potfiles = files_with_ext(folder, ".pot")
|
2019-09-10 00:54:28 +00:00
|
|
|
for potfile in potfiles:
|
|
|
|
refpot = polib.pofile(potfile)
|
|
|
|
refname = op.splitext(op.basename(potfile))[0]
|
|
|
|
for lang in get_langs(folder):
|
2020-01-01 02:16:27 +00:00
|
|
|
po = polib.pofile(op.join(folder, lang, LC_MESSAGES, refname + ".po"))
|
2019-09-10 00:54:28 +00:00
|
|
|
po.merge(refpot)
|
|
|
|
po.save()
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
def merge_po_and_preserve(source, dest):
|
|
|
|
# Merges source entries into dest, but keep old entries intact
|
|
|
|
sourcepo = polib.pofile(source)
|
|
|
|
destpo = polib.pofile(dest)
|
|
|
|
for entry in sourcepo:
|
|
|
|
if destpo.find(entry.msgid) is not None:
|
|
|
|
# The entry is already there
|
|
|
|
continue
|
|
|
|
destpo.append(entry)
|
|
|
|
destpo.save()
|
|
|
|
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
def normalize_all_pos(base_folder):
|
|
|
|
"""Normalize the format of .po files in base_folder.
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
When getting POs from external sources, such as Transifex, we end up with spurious diffs because
|
|
|
|
of a difference in the way line wrapping is handled. It wouldn't be a big deal if it happened
|
|
|
|
once, but these spurious diffs keep overwriting each other, and it's annoying.
|
2020-01-01 02:16:27 +00:00
|
|
|
|
2019-09-10 00:54:28 +00:00
|
|
|
Our PO files will keep polib's format. Call this function to ensure that freshly pulled POs
|
|
|
|
are of the right format before committing them.
|
|
|
|
"""
|
|
|
|
langs = get_langs(base_folder)
|
|
|
|
for lang in langs:
|
|
|
|
pofolder = op.join(base_folder, lang, LC_MESSAGES)
|
2020-01-01 02:16:27 +00:00
|
|
|
pofiles = files_with_ext(pofolder, ".po")
|
2019-09-10 00:54:28 +00:00
|
|
|
for pofile in pofiles:
|
|
|
|
p = polib.pofile(pofile)
|
|
|
|
p.save()
|