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