diff options
Diffstat (limited to 'sugar_network/toolkit/i18n.py')
-rw-r--r-- | sugar_network/toolkit/i18n.py | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/sugar_network/toolkit/i18n.py b/sugar_network/toolkit/i18n.py new file mode 100644 index 0000000..86d3cae --- /dev/null +++ b/sugar_network/toolkit/i18n.py @@ -0,0 +1,134 @@ +# Copyright (C) 2014 Aleksey Lim +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os +import logging +from gettext import translation + + +# To let `encode()` working properly, avoid msgids gettext'izing +# but still populate .po files parsing the source code +_ = lambda x: x + +_logger = logging.getLogger('i18n') +_i18n = {} + + +def default_lang(): + """Default language to fallback for localized strings. + + :returns: + string in format of HTTP's Accept-Language + + """ + return default_langs()[0] + + +def default_langs(): + """Default languages list, i.e., including all secondory languages. + + :returns: + list of strings in format of HTTP's Accept-Language + + """ + global _default_langs + + if _default_langs is None: + locales = os.environ.get('LANGUAGE') + if locales: + locales = [i for i in locales.split(':') if i.strip()] + else: + from locale import getdefaultlocale + locales = [getdefaultlocale()[0]] + if not locales: + _default_langs = ['en'] + else: + _default_langs = [] + for locale in locales: + lang = locale.strip().split('.')[0].lower() + if lang == 'c': + lang = 'en' + elif '_' in lang: + lang, region = lang.split('_') + if lang != region: + lang = '-'.join([lang, region]) + _default_langs.append(lang) + _logger.info('Default languages are %r', _default_langs) + + return _default_langs + + +def decode(value, accept_language=None): + if not value: + return '' + if not isinstance(value, dict): + return value + + if accept_language is None: + accept_language = default_langs() + elif isinstance(accept_language, basestring): + accept_language = [accept_language] + accept_language.append('en') + + stripped_value = None + for lang in accept_language: + result = value.get(lang) + if result is not None: + return result + + prime_lang = lang.split('-')[0] + if prime_lang != lang: + result = value.get(prime_lang) + if result is not None: + return result + + if stripped_value is None: + stripped_value = {} + for k, v in value.items(): + if '-' in k: + stripped_value[k.split('-', 1)[0]] = v + result = stripped_value.get(prime_lang) + if result is not None: + return result + + return value[min(value.keys())] + + +def encode(msgid, *args, **kwargs): + if not _i18n: + from sugar_network.toolkit.languages import LANGUAGES + for lang in LANGUAGES: + _i18n[lang] = translation('sugar-network', languages=[lang]) + result = {} + + for lang, trans in _i18n.items(): + msgstr = trans.gettext(msgid) + if args: + msgargs = [] + for arg in args: + msgargs.append(decode(arg, lang)) + msgstr = msgstr % tuple(msgargs) + elif kwargs: + msgargs = {} + for key, value in kwargs.items(): + msgargs[key] = decode(value, lang) + msgstr = msgstr % msgargs + result[lang] = msgstr + + return result + + +_default_lang = None +_default_langs = None |