From 28c7e439404f10b318745b10236ccfb42d011aae Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 4 Apr 2020 17:26:47 +0530 Subject: [PATCH] Fix #1860831 [Two Portuguese when to choose the language](https://bugs.launchpad.net/calibre/+bug/1860831) --- setup/translations.py | 10 ++-- src/calibre/utils/localization.py | 79 ++++++++++++++++++------------- 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/setup/translations.py b/setup/translations.py index 5891be5497..8528112613 100644 --- a/setup/translations.py +++ b/setup/translations.py @@ -555,7 +555,7 @@ class Translations(POT): # {{{ def _compile_website_translations(self, name='website', threshold=50): from calibre.utils.zipfile import ZipFile, ZipInfo, ZIP_STORED from calibre.ptempfile import TemporaryDirectory - from calibre.utils.localization import get_iso639_translator, get_language, get_iso_language + from calibre.utils.localization import get_language, translator_for_lang self.info('Compiling', name, 'translations...') srcbase = self.j(self.d(self.SRC), 'translations', name) if not os.path.exists(srcbase): @@ -596,11 +596,9 @@ class Translations(POT): # {{{ lang_names = {} for l in dl: - if l == 'en': - t = get_language - else: - t = getattr(get_iso639_translator(l), 'gettext' if ispy3 else 'ugettext') - t = partial(get_iso_language, t) + translator = translator_for_lang(l)['translator'] + t = getattr(translator, 'gettext' if ispy3 else 'ugettext') + t = partial(get_language, gettext_func=t) lang_names[l] = {x: t(x) for x in dl} zi = ZipInfo('lang-names.json') zi.compress_type = ZIP_STORED diff --git a/src/calibre/utils/localization.py b/src/calibre/utils/localization.py index 6228e4fa4b..c652d308c2 100644 --- a/src/calibre/utils/localization.py +++ b/src/calibre/utils/localization.py @@ -209,50 +209,61 @@ def load_po(path): return buf -def set_translators(): - global _lang_trans, lcdata - # To test different translations invoke as - # CALIBRE_OVERRIDE_LANG=de_DE.utf8 program - lang = get_lang() - t = buf = iso639 = None - +def translator_for_lang(lang): + t = buf = iso639 = lcdata = None if 'CALIBRE_TEST_TRANSLATION' in os.environ: buf = load_po(os.path.expanduser(os.environ['CALIBRE_TEST_TRANSLATION'])) - if lang: - mpath = get_lc_messages_path(lang) - if buf is None and mpath and os.access(mpath + '.po', os.R_OK): - buf = load_po(mpath + '.po') + mpath = get_lc_messages_path(lang) + if buf is None and mpath and os.access(mpath + '.po', os.R_OK): + buf = load_po(mpath + '.po') - if mpath is not None: - from zipfile import ZipFile - with ZipFile(P('localization/locales.zip', - allow_user_override=False), 'r') as zf: - if buf is None: - buf = io.BytesIO(zf.read(mpath + '/messages.mo')) - if mpath == 'nds': - mpath = 'de' - isof = mpath + '/iso639.mo' + if mpath is not None: + from zipfile import ZipFile + with ZipFile(P('localization/locales.zip', + allow_user_override=False), 'r') as zf: + if buf is None: + buf = io.BytesIO(zf.read(mpath + '/messages.mo')) + if mpath == 'nds': + mpath = 'de' + isof = mpath + '/iso639.mo' + try: + iso639 = io.BytesIO(zf.read(isof)) + except: + pass # No iso639 translations for this lang + if buf is not None: + from calibre.utils.serialize import msgpack_loads try: - iso639 = io.BytesIO(zf.read(isof)) + lcdata = msgpack_loads(zf.read(mpath + '/lcdata.calibre_msgpack')) except: - pass # No iso639 translations for this lang - if buf is not None: - from calibre.utils.serialize import msgpack_loads - try: - lcdata = msgpack_loads(zf.read(mpath + '/lcdata.calibre_msgpack')) - except: - pass # No lcdata + pass # No lcdata if buf is not None: t = GNUTranslations(buf) if iso639 is not None: - iso639 = _lang_trans = GNUTranslations(iso639) + iso639 = GNUTranslations(iso639) t.add_fallback(iso639) if t is None: t = NullTranslations() + return {'translator': t, 'iso639_translator': iso639, 'lcdata': lcdata} + + +def set_translators(): + global _lang_trans, lcdata + # To test different translations invoke as + # CALIBRE_OVERRIDE_LANG=de_DE.utf8 program + lang = get_lang() + + if lang: + q = translator_for_lang(lang) + t = q['translator'] + _lang_trans = q['iso639_translator'] + if q['lcdata']: + lcdata = q['lcdata'] + else: + t = NullTranslations() try: set_translators.lang = t.info().get('language') except Exception: @@ -386,15 +397,17 @@ def get_iso_language(lang_trans, lang): return lang_trans(ans) -def get_language(lang): - translate = _ +def get_language(lang, gettext_func=None): + translate = gettext_func or _ lang = _lcase_map.get(lang, lang) if lang in _extra_lang_codes: # The translator was not active when _extra_lang_codes was defined, so # re-translate return translate(_extra_lang_codes[lang]) - attr = 'gettext' if sys.version_info.major > 2 else 'ugettext' - return get_iso_language(getattr(_lang_trans, attr, translate), lang) + if gettext_func is None: + attr = 'gettext' if sys.version_info.major > 2 else 'ugettext' + gettext_func = getattr(_lang_trans, attr, translate) + return get_iso_language(gettext_func, lang) def calibre_langcode_to_name(lc, localize=True):