]> git.ipfire.org Git - collecty.git/blob - src/collecty/locales.py
locale: Fix fallback to default locale
[collecty.git] / src / collecty / locales.py
1 #!/usr/bin/python3
2 ###############################################################################
3 # #
4 # collecty - A system statistics collection daemon for IPFire #
5 # Copyright (C) 2015 IPFire development team #
6 # #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
11 # #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
16 # #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 # #
20 ###############################################################################
21
22 import gettext
23 import os
24
25 from .constants import *
26 from .i18n import TEXTDOMAIN
27
28 import logging
29 log = logging.getLogger("collecty.locale")
30 log.propagate = 1
31
32 class Locale(object):
33 def __init__(self, lang):
34 self.lang = lang
35
36 def translate(self, message, plural_message=None, count=None):
37 if plural_message is not None:
38 assert count is not None
39
40 # Replace the message by the plural message if
41 # we are using plural.
42 if count > 1:
43 message = plural_message
44
45 return message
46
47
48 class GettextLocale(Locale):
49 def __init__(self, lang, translation):
50 Locale.__init__(self, lang)
51
52 self.translation = translation
53
54 # Bind gettext functions
55 self.gettext = self.translation.gettext
56 self.ngettext = self.translation.ngettext
57
58 def translate(self, message, plural_message=None, count=None):
59 if plural_message is not None:
60 assert count is not None
61 return self.ngettext(message, plural_message, count)
62
63 return self.gettext(message)
64
65
66 def _find_all_locales(domain, directory):
67 locales = {
68 DEFAULT_LOCALE : Locale(DEFAULT_LOCALE),
69 }
70
71 for lang in os.listdir(directory):
72 if lang.startswith("."):
73 continue
74
75 filename = os.path.join(directory, lang, "LC_MESSAGES",
76 "%s.mo" % domain)
77
78 # Check if a translation file exists and go on if not
79 if not os.path.exists(filename):
80 continue
81
82 try:
83 translation = gettext.translation(domain,
84 directory, languages=[lang])
85 except Exception as e:
86 log.error("Cound not load translation for %s: %s" \
87 % (lang, e))
88 continue
89
90 locales[lang] = GettextLocale(lang, translation)
91
92 log.debug("Loaded translations: %s" % ", ".join(locales.keys()))
93
94 return locales
95
96 _locales = _find_all_locales(TEXTDOMAIN, "/usr/share/locale")
97
98 def get_supported_locales():
99 return list(_locales.keys())
100
101 def get_closest(*langs):
102 for lang in langs:
103 if not lang:
104 continue
105
106 lang = lang.replace("-", "_")
107 parts = lang.split("_")
108
109 if len(parts) > 2:
110 continue
111
112 elif len(parts) == 2:
113 parts[0] = parts[0].lower()
114 parts[1] = parts[1].upper()
115 lang = "_".join(parts)
116
117 for l in (lang, parts[0]):
118 try:
119 return _locales[l]
120 except KeyError:
121 pass
122
123 def get(*langs):
124 return get_closest(*langs) or _locales.get(DEFAULT_LOCALE, None)