diff --git a/gajim/common/i18n.py b/gajim/common/i18n.py index f7e0bb59a..a11cdd657 100644 --- a/gajim/common/i18n.py +++ b/gajim/common/i18n.py @@ -18,38 +18,56 @@ # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . +import os +import sys import locale import gettext -import os import unicodedata +from pathlib import Path DOMAIN = 'gajim' LANG = 'en' direction_mark = '\u200E' -_translations = None +_translation = gettext.NullTranslations() -def get_locale_dir(): +def get_locale_dirs(): if os.name == 'nt': - return None - # try to find domain in localedir - path = gettext.find(DOMAIN) - if path: - # extract localedir from localedir/language/LC_MESSAGES/domain.mo - path = os.path.split(path)[1] - path = os.path.split(path)[1] - localedir = os.path.split(path)[1] - elif os.path.exists('/app/share/run-as-flatpak'): - # Check if we run as flatpak - return '/app/share/locale' - else: - # fallback to user locale - base = os.getenv('XDG_DATA_HOME') - if base is None or base[0] != '/': - base = os.path.expanduser('~/.local/share') - localedir = os.path.join(base, "locale") - return localedir + return + path = gettext.find(DOMAIN) + if path is not None: + # gettext can find the location itself + # so we dont need the localedir + return + + if Path('/app/share/run-as-flatpak').exists(): + # Check if we run as flatpak + return [Path('/app/share/')] + + data_dirs = os.getenv('XDG_DATA_DIRS') + if data_dirs: + return list(map(Path, data_dirs.split(':'))) + return [Path('/usr/local/share/'), Path('/usr/share/')] + + +def iter_locale_dirs(): + locale_dirs = get_locale_dirs() + if locale_dirs is None: + yield None + return + + # gettext fallback + locale_dirs.append(Path(sys.base_prefix) / 'share') + + found_paths = [] + for path in locale_dirs: + locale_dir = path / 'locale' + if locale_dir in found_paths: + continue + found_paths.append(locale_dir) + if locale_dir.is_dir(): + yield locale_dir def initialize_direction_mark(): from gi.repository import Gtk @@ -106,7 +124,7 @@ def ngettext(s_sing, s_plural, n, replace_sing=None, replace_plural=None): In other words this is a hack to ngettext() to support %s %d etc.. """ - text = _translations.ngettext(s_sing, s_plural, n) + text = _translation.ngettext(s_sing, s_plural, n) if n == 1 and replace_sing is not None: text = text % replace_sing elif n > 1 and replace_plural is not None: @@ -119,30 +137,26 @@ try: except locale.Error as error: print(error) -try: - # en_US, fr_FR, el_GR etc.. - default = locale.getdefaultlocale()[0] - if default is not None: - LANG = default[:2] -except (ValueError, locale.Error): - pass - if os.name == 'nt': + try: + # en_US, fr_FR, el_GR etc.. + default = locale.getdefaultlocale()[0] + if default is not None: + LANG = default[:2] + except (ValueError, locale.Error): + pass os.environ['LANG'] = LANG -_localedir = get_locale_dir() -if hasattr(locale, 'bindtextdomain'): - locale.bindtextdomain(DOMAIN, _localedir) # type: ignore -gettext.textdomain(DOMAIN) - -gettext.install(DOMAIN, _localedir) - -try: - _ = gettext.translation(DOMAIN, _localedir).gettext -except OSError: - _ = gettext.gettext - -if gettext._translations: # type: ignore - _translations = list(gettext._translations.values())[0] # type: ignore +# Search for the translation in all locale dirs +for dir_ in iter_locale_dirs(): + try: + _translation = gettext.translation(DOMAIN, dir_) + _ = _translation.gettext + except OSError: + continue + else: + break else: - _translations = gettext.NullTranslations() + print('No translations found') + print('Dirs searched: %s' % get_locale_dirs()) + _ = _translation.gettext diff --git a/gajim/plugins/pluginmanager.py b/gajim/plugins/pluginmanager.py index 9b30bf266..6fe8a4449 100644 --- a/gajim/plugins/pluginmanager.py +++ b/gajim/plugins/pluginmanager.py @@ -38,6 +38,7 @@ from gajim.common import configpaths from gajim.common import modules from gajim.common.i18n import _ from gajim.common.exceptions import PluginsystemError +from gajim.plugins import plugins_i18n from gajim.plugins.helpers import log, log_calls, Singleton from gajim.plugins.helpers import GajimPluginActivateException @@ -542,7 +543,6 @@ class PluginManager(metaclass=Singleton): :todo: add scanning zipped modules ''' - from gajim.plugins.plugins_i18n import _ plugins_found = [] conf = configparser.ConfigParser() fields = ('name', 'short_name', 'version', 'description', 'authors', @@ -632,7 +632,7 @@ class PluginManager(metaclass=Singleton): if conf.get('info', option) == '': raise configparser.NoOptionError(option, 'info') if option == 'description': - setattr(module_attr, option, _(conf.get('info', option))) + setattr(module_attr, option, plugins_i18n._(conf.get('info', option))) continue setattr(module_attr, option, conf.get('info', option)) @@ -640,7 +640,7 @@ class PluginManager(metaclass=Singleton): except TypeError: # set plugin localization try: - module_attr._ = _ + module_attr._ = plugins_i18n._ except AttributeError: pass except configparser.NoOptionError: diff --git a/gajim/plugins/plugins_i18n.py b/gajim/plugins/plugins_i18n.py index 91d67d7f8..ea524f969 100644 --- a/gajim/plugins/plugins_i18n.py +++ b/gajim/plugins/plugins_i18n.py @@ -15,22 +15,16 @@ # along with Gajim. If not, see . import os -import locale import gettext from gajim.common import configpaths -APP = 'gajim_plugins' +DOMAIN = 'gajim_plugins' plugin_user_dir = configpaths.get('PLUGINS_USER') plugins_locale_dir = os.path.join(plugin_user_dir, 'locale') -if os.name != 'nt': - locale.setlocale(locale.LC_ALL, '') - gettext.bindtextdomain(APP, plugins_locale_dir) - gettext.textdomain(APP) - try: - t = gettext.translation(APP, plugins_locale_dir) + t = gettext.translation(DOMAIN, plugins_locale_dir) _ = t.gettext -except IOError: +except OSError: _ = gettext.gettext