#-*- coding: utf-8 -*- # Copyright 2008-2013 Calculate Ltd. 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 class lang: """ Multilanguage class """ _modnames = {} GP = [""] 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 type(mod) == types.ModuleType and \ not name.startswith('__') and \ not name 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.UTF-8").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 """ if self._modnames.has_key(namemodule): return self._modnames[namemodule] return 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(object): 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 = filter(lambda x: x[0], ((create_key(k), v) for k, v in sorted(d.items(), reverse=True) if k)) def translate(self, s): for k, v in self._catalog: try: s = k.sub(v, s) except UnicodeDecodeError: return s return s