# -*- coding: utf-8 -*- # Copyright 2008-2016 Mir Calculate. http://www.calculate-linux.org # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os import gettext from gettext import gettext as _ import threading import types import sys import re from gettext import Catalog from importlib import reload class Lang: """ Multilanguage class """ _modnames = {} GP = [""] orig_gettext = _ def __init__(self): self.nameDomain = self.GP[0] self.__catalog = None # translate language for all modules self._translators = {} def __translate(self, message): """Method return message without changes""" return self.__gettranslate()(message) def setLanguage(self, module, glob=False): """Set translate language for modules 'module'. module - export python module if the module export other modules, then lang will be set for them Method must be call after module for translate""" if glob: for name, mod in vars(module).items(): if (isinstance(mod, types.ModuleType) and not name.startswith('__') and name not in sys.builtin_module_names and (hasattr(mod, '__file__') and ( "calculate" in mod.__file__ or not mod.__file__.startswith('/usr/lib')))): self.__setLang(mod) self.setLanguage(mod, True) return self.__setLang(module) def __setLang(self, module): """ Set translate language for module 'module'. """ if module.__name__ in self._modnames.keys(): return True module._ = self.__translate self._modnames[module.__name__] = module._ @staticmethod def get_current_lang(): """ Получить текущий язык """ env = os.environ cur_thread = threading.currentThread() if hasattr(cur_thread, "lang"): return cur_thread.lang return env.get("LANG", "en_US.utf8").split('.')[0].split("_")[0] def __gettranslate(self): l = self.get_current_lang() if l in self._translators: return self._translators[l] if l == 'en': trans = lambda x: x else: la = [l] # reload(gettext) if gettext.find(self.nameDomain, self.__catalog, la): """Если найден словарь то инициализируем переводчик""" transl = gettext.translation(self.nameDomain, self.__catalog, la) trans = transl.gettext else: trans = lambda x: x self._translators[l] = trans return trans def getTranslatorByName(self, namemodule): """Method for detect already imported translate modules """ return self._modnames.get(namemodule, 0) def setGlobalDomain(self, nameDomain): """ Method for set global translate domain """ self.GP[0] = nameDomain self.nameDomain = self.GP[0] return True def setLocalDomain(self, nameDomain): """ Method for set local translate domain """ self.nameDomain = nameDomain return True def setGlobalTranslate(domain, *modules): _lang = Lang() _lang.setGlobalDomain(domain) for mod in modules: _lang.setLanguage(mod, glob=True) def setLocalTranslate(domain, *modules): _lang = Lang() _lang.setLocalDomain(domain) for mod in modules: _lang.setLanguage(mod) def getLazyLocalTranslate(translateFunc): class Translate: def __init__(self, s): self.s = s self._format_args = None def __str__(self): if self._format_args is None: return translateFunc(self.s) else: return translateFunc(self.s).format(*self._format_args[0], **self._format_args[1]) def __hash__(self): return hash(self.s) def format(self, *args, **kwargs): self._format_args = (args, kwargs) return self return Translate class RegexpLocalization(): def __init__(self, domain, languages=(Lang.get_current_lang())): try: self.set_translate_dict(Catalog(domain, languages=languages)._catalog) except IOError: self._catalog = {} def set_translate_dict(self, d): def create_key(k): try: return re.compile(k.replace("\\\\", "\\")) except re.error: return None # self._catalog = list(filter(lambda x: x[0], # ((create_key(k), v) for k, v in # sorted(d.items(), reverse=True) if k))) self._catalog = [x for x in [(create_key(k), v) for k, v in sorted(d.items(), reverse=True) if k] if x[0]] def translate(self, s): for k, v in self._catalog: try: s = k.sub(v, s) except UnicodeDecodeError: return s return s