diff options
author | Philipp Hörist <philipp@hoerist.com> | 2023-05-29 11:57:33 +0300 |
---|---|---|
committer | Philipp Hörist <philipp@hoerist.com> | 2023-05-29 12:43:30 +0300 |
commit | c45fbdd8b5bc7ccd3c3b68cdb688bc8091c00a89 (patch) | |
tree | 800ba2012b34ef5da76853b128303ec0c249015b | |
parent | 32601f1cd673193bec698f819b0ec7c17a40ce19 (diff) |
refactor: Allow to import i18n module without side effects
- Add new method for translation
- Remove stderr if translations are missing
-rw-r--r-- | gajim/common/app.py | 4 | ||||
-rw-r--r-- | gajim/common/i18n.py | 124 | ||||
-rw-r--r-- | gajim/gtk/message_input.py | 4 | ||||
-rw-r--r-- | gajim/main.py | 6 |
4 files changed, 82 insertions, 56 deletions
diff --git a/gajim/common/app.py b/gajim/common/app.py index 2f1fa89d2..d0c694d23 100644 --- a/gajim/common/app.py +++ b/gajim/common/app.py @@ -49,7 +49,7 @@ from gajim.common import configpaths from gajim.common import ged as ged_module from gajim.common import types from gajim.common.const import Display -from gajim.common.i18n import LANG +from gajim.common.i18n import get_default_lang if typing.TYPE_CHECKING: from gajim.common.call_manager import CallManager @@ -294,7 +294,7 @@ def detect_dependencies() -> None: for dep, val in _dependencies.items(): log('gajim').info('%-13s %s', dep, val) - log('gajim').info('Used language: %s', LANG) + log('gajim').info('Used language: %s', get_default_lang()) def detect_desktop_env() -> str | None: diff --git a/gajim/common/i18n.py b/gajim/common/i18n.py index 746056473..d5c4e513f 100644 --- a/gajim/common/i18n.py +++ b/gajim/common/i18n.py @@ -33,39 +33,23 @@ from pathlib import Path DOMAIN = 'gajim' -def get_win32_default_lang() -> str: - import ctypes - windll = ctypes.windll.kernel32 - return locale.windows_locale[windll.GetUserDefaultUILanguage()] - - -def get_darwin_default_lang() -> str: - from AppKit import NSLocale - - # FIXME: This returns a two letter language code (en, de, fr) - # We need a way to get en_US, de_DE etc. - return NSLocale.currentLocale().languageCode() +def init() -> None: + _trans.init() def get_default_lang() -> str: - if sys.platform == 'win32': - return get_win32_default_lang() - - if sys.platform == 'darwin': - return get_darwin_default_lang() - - return locale.getdefaultlocale()[0] or 'en' + return _trans.get_default_lang() def get_rfc5646_lang(lang: str | None = None) -> str: if lang is None: - lang = LANG + lang = _trans.get_default_lang() return lang.replace('_', '-') def get_short_lang_code(lang: str | None = None) -> str: if lang is None: - lang = LANG + lang = _trans.get_default_lang() return lang[:2] @@ -84,10 +68,6 @@ def is_rtl_text(text: str) -> bool: return False -def p_(context: str, message: str) -> str: - return _translation.pgettext(context, message) - - def ngettext(s_sing: str, s_plural: str, n: int, @@ -100,7 +80,7 @@ def ngettext(s_sing: str, In other words this is a hack to ngettext() to support %s %d etc.. ''' - text = _translation.ngettext(s_sing, s_plural, n) + text = _trans.translation.ngettext(s_sing, s_plural, n) if n == 1 and replace_sing is not None: return text % replace_sing @@ -109,29 +89,69 @@ def ngettext(s_sing: str, return text -try: - locale.setlocale(locale.LC_ALL, '') -except locale.Error as error: - print(error, file=sys.stderr) - -LANG = get_default_lang() -if sys.platform == 'win32': - # Set the env var on Windows because gettext.find() uses it to - # find the translation - # Use LANGUAGE instead of LANG, LANG sets LC_ALL and thus - # doesn't retain other region settings like LC_TIME - os.environ['LANGUAGE'] = LANG - - -package_dir = cast(Path, importlib.resources.files('gajim')) -locale_dir = package_dir / 'data' / 'locale' - -try: - _translation = gettext.translation(DOMAIN, locale_dir) - _ = _translation.gettext - if hasattr(locale, 'bindtextdomain'): - locale.bindtextdomain(DOMAIN, locale_dir) -except OSError: - _translation = gettext.NullTranslations() - _ = _translation.gettext - print('No translations found for', LANG, file=sys.stderr) +class Translation: + def __init__(self) -> None: + self.translation = gettext.NullTranslations() + self._default_lang = None + + def get_default_lang(self) -> str: + assert self._default_lang is not None + return self._default_lang + + @staticmethod + def _get_win32_default_lang() -> str: + import ctypes + windll = ctypes.windll.kernel32 + return locale.windows_locale[windll.GetUserDefaultUILanguage()] + + @staticmethod + def _get_darwin_default_lang() -> str: + from AppKit import NSLocale + + # FIXME: This returns a two letter language code (en, de, fr) + # We need a way to get en_US, de_DE etc. + return NSLocale.currentLocale().languageCode() + + def _get_default_lang(self) -> str: + if sys.platform == 'win32': + return self._get_win32_default_lang() + + if sys.platform == 'darwin': + return self._get_darwin_default_lang() + + return locale.getdefaultlocale()[0] or 'en' + + def init(self) -> None: + try: + locale.setlocale(locale.LC_ALL, '') + except locale.Error as error: + print(error, file=sys.stderr) + + self._default_lang = self._get_default_lang() + if sys.platform == 'win32': + # Set the env var on Windows because gettext.find() uses it to + # find the translation + # Use LANGUAGE instead of LANG, LANG sets LC_ALL and thus + # doesn't retain other region settings like LC_TIME + os.environ['LANGUAGE'] = self._default_lang + + package_dir = cast(Path, importlib.resources.files('gajim')) + locale_dir = package_dir / 'data' / 'locale' + + try: + self.translation = gettext.translation(DOMAIN, locale_dir) + if hasattr(locale, 'bindtextdomain'): + locale.bindtextdomain(DOMAIN, locale_dir) + except OSError: + pass + + self.install() + + def install(self) -> None: + global _, g_, p_ + _ = self.translation.gettext + g_ = self.translation.gettext + p_ = self.translation.pgettext + + +_trans = Translation() diff --git a/gajim/gtk/message_input.py b/gajim/gtk/message_input.py index 7c850d2f5..4b682498b 100644 --- a/gajim/gtk/message_input.py +++ b/gajim/gtk/message_input.py @@ -34,7 +34,7 @@ from gajim.common import ged from gajim.common.events import MessageSent from gajim.common.ged import EventHelper from gajim.common.i18n import _ -from gajim.common.i18n import LANG +from gajim.common.i18n import get_default_lang from gajim.common.styling import PlainBlock from gajim.common.styling import process from gajim.common.types import ChatContactT @@ -219,7 +219,7 @@ class MessageInputTextView(Gtk.TextView, EventHelper): # use the default one lang = app.settings.get('speller_language') if not lang: - lang = LANG + lang = get_default_lang() assert isinstance(lang, str) lang = Gspell.language_lookup(lang) diff --git a/gajim/main.py b/gajim/main.py index 3783a536c..cb07a37c3 100644 --- a/gajim/main.py +++ b/gajim/main.py @@ -95,6 +95,11 @@ def _check_required_deps() -> None: check_version('sqlite', sqlite3.sqlite_version, _MIN_SQLITE_VER) +def _init_translations() -> None: + import gajim.common.i18n + gajim.common.i18n.init() + + def _init_gui(gui: str) -> None: if gui == 'GTK': _init_gtk() @@ -162,5 +167,6 @@ def run() -> None: _check_required_deps() _set_proc_title() _set_env_vars() + _init_translations() _init_gui('GTK') _run_app() |