|
|
|
#!/usr/bin/python -OO
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2010-2018 The SABnzbd-Team <team@sabnzbd.org>
|
|
|
|
#
|
|
|
|
# This program is free software; you can redistribute it and/or
|
|
|
|
# modify it under the terms of the GNU General Public License
|
|
|
|
# as published by the Free Software Foundation; either version 2
|
|
|
|
# of the License, or (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program; if not, write to the Free Software
|
|
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
|
|
"""
|
|
|
|
make_mo - Compile PO files to MO files
|
|
|
|
"""
|
|
|
|
|
|
|
|
import glob
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import sys
|
|
|
|
import gettext
|
|
|
|
import subprocess
|
|
|
|
|
|
|
|
PO_DIR = 'po/main'
|
|
|
|
POE_DIR = 'po/email'
|
|
|
|
PON_DIR = 'po/nsis'
|
|
|
|
MO_DIR = 'locale'
|
|
|
|
EMAIL_DIR = 'email'
|
|
|
|
|
|
|
|
MO_LOCALE = '/LC_MESSAGES'
|
|
|
|
DOMAIN = 'SABnzbd'
|
|
|
|
DOMAIN_E = 'SABemail'
|
|
|
|
DOMAIN_N = 'SABnsis'
|
|
|
|
LANG_MARKER = 'language.txt'
|
|
|
|
NSIS = 'NSIS_Installer.nsi'
|
|
|
|
|
|
|
|
LanguageTable = {
|
|
|
|
'aa': ('Afar', 'Afaraf'),
|
|
|
|
'af': ('Afrikaans', 'Afrikaans'),
|
|
|
|
'ak': ('Akan', 'Akan'),
|
|
|
|
'sq': ('Albanian', 'Shqip'),
|
|
|
|
'an': ('Aragonese', 'Aragonés'),
|
|
|
|
'ae': ('Avestan', 'Avesta'),
|
|
|
|
'ay': ('Aymara', 'Aymararu'),
|
|
|
|
'bm': ('Bambara', 'Bamanankan'),
|
|
|
|
'eu': ('Basque', 'Euskara'),
|
|
|
|
'bi': ('Bislama', 'Bislama'),
|
|
|
|
'bs': ('Bosnian', 'Bosanskijezik'),
|
|
|
|
'br': ('Breton', 'Brezhoneg'),
|
|
|
|
'ca': ('Catalan', 'Català'),
|
|
|
|
'ch': ('Chamorro', 'Chamoru'),
|
|
|
|
'kw': ('Cornish', 'Kernewek'),
|
|
|
|
'co': ('Corsican', 'Corsu'),
|
|
|
|
'hr': ('Croatian', 'Hrvatski'),
|
|
|
|
'cs': ('Czech', 'Cesky, ceština'),
|
|
|
|
'da': ('Danish', 'Dansk'),
|
|
|
|
'nl': ('Dutch', 'Nederlands'),
|
|
|
|
'en': ('English', 'English'),
|
|
|
|
'eo': ('Esperanto', 'Esperanto'),
|
|
|
|
'et': ('Estonian', 'Eesti'),
|
|
|
|
'fo': ('Faroese', 'Føroyskt'),
|
|
|
|
'fj': ('Fijian', 'Vosa Vakaviti'),
|
|
|
|
'fi': ('Finnish', 'Suomi'),
|
|
|
|
'fr': ('French', 'Français'),
|
|
|
|
'gl': ('Galician', 'Galego'),
|
|
|
|
'de': ('German', 'Deutsch'),
|
|
|
|
'he': ('Hebrew', 'עִבְרִית'),
|
|
|
|
'hz': ('Herero', 'Otjiherero'),
|
|
|
|
'ho': ('Hiri Motu', 'Hiri Motu'),
|
|
|
|
'hu': ('Hungarian', 'Magyar'),
|
|
|
|
'id': ('Indonesian', 'Bahasa Indonesia'),
|
|
|
|
'ga': ('Irish', 'Gaeilge'),
|
|
|
|
'io': ('Ido', 'Ido'),
|
|
|
|
'is': ('Icelandic', 'Íslenska'),
|
|
|
|
'it': ('Italian', 'Italiano'),
|
|
|
|
'jv': ('Javanese', 'BasaJawa'),
|
|
|
|
'rw': ('Kinyarwanda', 'Ikinyarwanda'),
|
|
|
|
'kg': ('Kongo', 'KiKongo'),
|
|
|
|
'kj': ('Kwanyama', 'Kuanyama'),
|
|
|
|
'la': ('Latin', 'Lingua latina'),
|
|
|
|
'lb': ('Luxembourgish', 'Lëtzebuergesch'),
|
|
|
|
'lg': ('Luganda', 'Luganda'),
|
|
|
|
'li': ('Limburgish', 'Limburgs'),
|
|
|
|
'ln': ('Lingala', 'Lingála'),
|
|
|
|
'lt': ('Lithuanian', 'Lietuviukalba'),
|
|
|
|
'lv': ('Latvian', 'Latviešuvaloda'),
|
|
|
|
'gv': ('Manx', 'Gaelg'),
|
|
|
|
'mg': ('Malagasy', 'Malagasy fiteny'),
|
|
|
|
'mt': ('Maltese', 'Malti'),
|
|
|
|
'nb': ('Norwegian', 'Norsk'), # Bokmål
|
|
|
|
'nn': ('Norwegian', 'Norsk'), # Nynorsk
|
|
|
|
'no': ('Norwegian', 'Norsk'),
|
|
|
|
'oc': ('Occitan', 'Occitan'),
|
|
|
|
'om': ('Oromo', 'Afaan Oromoo'),
|
|
|
|
'pl': ('Polish', 'Polski'),
|
|
|
|
'pt': ('Portuguese', 'Português'),
|
|
|
|
'pt_BR': ('PortugueseBR', 'Português, Brasil'), # NSIS uses "PortugueseBR"
|
|
|
|
'rm': ('Romansh', 'Rumantsch grischun'),
|
|
|
|
'rn': ('Kirundi', 'kiRundi'),
|
|
|
|
'ro': ('Romanian', 'Româna'),
|
|
|
|
'sc': ('Sardinian', 'Sardu'),
|
|
|
|
'se': ('Northern Sami', 'Davvisámegiella'),
|
|
|
|
'sm': ('Samoan', 'Gagana fa\'a Samoa'),
|
|
|
|
'gd': ('Gaelic', 'Gàidhlig'),
|
|
|
|
'ru': ('Russian', 'русский язык'),
|
|
|
|
'sr': ('Serbian', 'српски'),
|
|
|
|
'sn': ('Shona', 'Chi Shona'),
|
|
|
|
'sk': ('Slovak', 'Slovencina'),
|
|
|
|
'sl': ('Slovene', 'Slovenšcina'),
|
|
|
|
'st': ('Southern Sotho', 'Sesotho'),
|
|
|
|
'es': ('Spanish', 'Español, castellano'), # NSIS cannot handle "Spanish Castilian"
|
|
|
|
'su': ('Sundanese', 'Basa Sunda'),
|
|
|
|
'sw': ('Swahili', 'Kiswahili'),
|
|
|
|
'ss': ('Swati', 'SiSwati'),
|
|
|
|
'sv': ('Swedish', 'Svenska'),
|
|
|
|
'tn': ('Tswana', 'Setswana'),
|
|
|
|
'to': ('Tonga (Tonga Islands)', 'faka Tonga'),
|
|
|
|
'tr': ('Turkish', 'Türkçe'),
|
|
|
|
'ts': ('Tsonga', 'Xitsonga'),
|
|
|
|
'tw': ('Twi', 'Twi'),
|
|
|
|
'ty': ('Tahitian', 'Reo Tahiti'),
|
|
|
|
'wa': ('Walloon', 'Walon'),
|
|
|
|
'cy': ('Welsh', 'Cymraeg'),
|
|
|
|
'wo': ('Wolof', 'Wollof'),
|
|
|
|
'fy': ('Western Frisian', 'Frysk'),
|
|
|
|
'xh': ('Xhosa', 'isi Xhosa'),
|
|
|
|
'yo': ('Yoruba', 'Yorùbá'),
|
|
|
|
'zu': ('Zulu', 'isi Zulu'),
|
|
|
|
'zh_CN': ('SimpChinese', '简体中文'),
|
|
|
|
}
|
|
|
|
|
|
|
|
# Filter for retrieving readable language from PO file
|
|
|
|
RE_LANG = re.compile(r'"Language-Description:\s([^"]+)\\n')
|
|
|
|
|
|
|
|
def run(cmd):
|
|
|
|
""" Run system command, returns exit-code and stdout """
|
|
|
|
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
|
|
txt = p.stdout.read()
|
|
|
|
return p.wait(), txt
|
|
|
|
|
|
|
|
|
|
|
|
def process_po_folder(domain, folder, extra=''):
|
|
|
|
""" Process each PO file in folder """
|
|
|
|
result = True
|
|
|
|
for fname in glob.glob(os.path.join(folder, '*.po')):
|
|
|
|
basename = os.path.split(fname)[1]
|
|
|
|
name = os.path.splitext(basename)[0]
|
|
|
|
mo_path = os.path.normpath('%s/%s%s' % (MO_DIR, name, MO_LOCALE))
|
|
|
|
mo_name = '%s.mo' % domain
|
|
|
|
if not os.path.exists(mo_path):
|
|
|
|
os.makedirs(mo_path)
|
|
|
|
|
|
|
|
# Create the MO file
|
|
|
|
mo_file = os.path.join(mo_path, mo_name)
|
|
|
|
print 'Compile %s' % mo_file
|
|
|
|
ret, output = run('%s %s -o "%s" "%s"' % (TOOL, extra, mo_file, fname))
|
|
|
|
if ret != 0:
|
|
|
|
print '\nMissing %s. Please install this package first.' % TOOL
|
|
|
|
exit(1)
|
|
|
|
if 'WARNING:' in output:
|
|
|
|
print output
|
|
|
|
result = False
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
def remove_mo_files():
|
|
|
|
""" Remove MO files in locale """
|
|
|
|
for root, dirs, files in os.walk(MO_DIR, topdown=False):
|
|
|
|
for f in files:
|
|
|
|
if not f.startswith(DOMAIN):
|
|
|
|
os.remove(os.path.join(root, f))
|
|
|
|
|
|
|
|
|
|
|
|
def translate_tmpl(prefix, lng):
|
|
|
|
""" Translate template 'prefix' into language 'lng' """
|
|
|
|
src = open(EMAIL_DIR + '/%s-en.tmpl' % prefix, 'r')
|
|
|
|
data = src.read().decode('utf-8')
|
|
|
|
src.close()
|
|
|
|
data = _(data).encode('utf-8')
|
|
|
|
fp = open('email/%s-%s.tmpl' % (prefix, lng), 'wb')
|
|
|
|
if not -1 < data.find('UTF-8') < 30:
|
|
|
|
fp.write('#encoding UTF-8\n')
|
|
|
|
fp.write(data)
|
|
|
|
fp.close()
|
|
|
|
|
|
|
|
|
|
|
|
def make_templates():
|
|
|
|
""" Create email templates """
|
|
|
|
if not os.path.exists('email'):
|
|
|
|
os.makedirs('email')
|
|
|
|
for path in glob.glob(os.path.join(MO_DIR, '*')):
|
|
|
|
lng = os.path.split(path)[1]
|
|
|
|
if lng != 'en' and os.path.exists(os.path.join(POE_DIR,lng+'.po')):
|
|
|
|
print 'Create email template for %s' % lng
|
|
|
|
trans = gettext.translation(DOMAIN_E, MO_DIR, [lng], fallback=False, codeset='latin-1')
|
|
|
|
# The unicode flag will make _() return Unicode
|
|
|
|
trans.install(unicode=True, names=['lgettext'])
|
|
|
|
|
|
|
|
translate_tmpl('email', lng)
|
|
|
|
translate_tmpl('rss', lng)
|
|
|
|
translate_tmpl('badfetch', lng)
|
|
|
|
|
|
|
|
mo_path = os.path.normpath('%s/%s%s/%s.mo' % (MO_DIR, path, MO_LOCALE, DOMAIN_E))
|
|
|
|
if os.path.exists(mo_path):
|
|
|
|
os.remove(mo_path)
|
|
|
|
|
|
|
|
|
|
|
|
def patch_nsis():
|
|
|
|
""" Patch translation into the NSIS script """
|
|
|
|
RE_NSIS = re.compile(r'^(\s*LangString\s+)(\w+)(\s+\$\{LANG_)(\w+)\}\s+(".*)', re.I)
|
|
|
|
languages = [os.path.split(path)[1] for path in glob.glob(os.path.join(MO_DIR, '*'))]
|
|
|
|
|
|
|
|
src = open(NSIS, 'r')
|
|
|
|
new = []
|
|
|
|
for line in src:
|
|
|
|
m = RE_NSIS.search(line)
|
|
|
|
if m:
|
|
|
|
leader = m.group(1)
|
|
|
|
item = m.group(2)
|
|
|
|
rest = m.group(3)
|
|
|
|
langname = m.group(4).upper()
|
|
|
|
text = m.group(5).strip('"\n')
|
|
|
|
if langname == 'ENGLISH':
|
|
|
|
# Write back old content
|
|
|
|
new.append(line)
|
|
|
|
# Replace silly $\ construction with just a \
|
|
|
|
text = text.replace('$\\"', '"').replace('$\\', '\\')
|
|
|
|
for lcode in languages:
|
|
|
|
lng = LanguageTable.get(lcode)
|
|
|
|
if lng and lcode != 'en':
|
|
|
|
lng = lng[0].decode('utf-8').encode('latin-1').upper()
|
|
|
|
if item == 'MsgLangCode':
|
|
|
|
trans = lcode
|
|
|
|
else:
|
|
|
|
trans = gettext.translation(DOMAIN_N, MO_DIR, [lcode], fallback=False, codeset='latin-1')
|
|
|
|
# The unicode flag will make _() return Unicode
|
|
|
|
trans.install(unicode=True, names=['lgettext'])
|
|
|
|
trans = _(text).encode('utf-8')
|
|
|
|
trans = trans.replace('\r', '').replace('\n', '\\r\\n')
|
|
|
|
trans = trans.replace('\\', '$\\').replace('"', '$\\"')
|
|
|
|
line = '%s%s%s%s} "%s"\n' % (leader, item, rest, lng, trans)
|
|
|
|
new.append(line)
|
|
|
|
elif lng is None:
|
|
|
|
print 'Warning: unsupported language %s (%s), add to table in this script' % (langname, lcode)
|
|
|
|
else:
|
|
|
|
new.append(line)
|
|
|
|
src.close()
|
|
|
|
|
|
|
|
dst = open(NSIS + '.tmp', 'w')
|
|
|
|
for line in new:
|
|
|
|
dst.write(line)
|
|
|
|
dst.close()
|
|
|
|
|
|
|
|
#----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
# Determine location of MsgFmt tool
|
|
|
|
path, py = os.path.split(sys.argv[0])
|
|
|
|
tl = os.path.abspath(os.path.normpath(os.path.join(path, 'msgfmt.py')))
|
|
|
|
if os.path.exists(tl):
|
|
|
|
if os.name == 'nt':
|
|
|
|
TOOL = 'python "%s"' % tl
|
|
|
|
else:
|
|
|
|
TOOL = '"%s"' % tl
|
|
|
|
|
|
|
|
result = True
|
|
|
|
if len(sys.argv) > 1 and sys.argv[1] == 'all':
|
|
|
|
print 'NSIS MO file'
|
|
|
|
result = result and process_po_folder(DOMAIN_N, PON_DIR)
|
|
|
|
|
|
|
|
print "Patch NSIS script"
|
|
|
|
patch_nsis()
|
|
|
|
|
|
|
|
print 'Email MO files'
|
|
|
|
result = result and process_po_folder(DOMAIN_E, POE_DIR)
|
|
|
|
|
|
|
|
print "Create email templates from MO files"
|
|
|
|
make_templates()
|
|
|
|
|
|
|
|
|
|
|
|
print 'Main program MO files'
|
|
|
|
# -n option added to remove all newlines from the translations
|
|
|
|
result = result and process_po_folder(DOMAIN, PO_DIR, '-n')
|
|
|
|
|
|
|
|
print "Remove temporary templates"
|
|
|
|
remove_mo_files()
|
|
|
|
|
|
|
|
print
|
|
|
|
if result:
|
|
|
|
exit(0)
|
|
|
|
else:
|
|
|
|
print 'WARNINGS present!'
|
|
|
|
exit(1)
|