# Programmer: limodou # E-mail: limodou@gmail.com # # Copyleft 2005 limodou # # Distributed under the terms of the GPL (GNU Public License) # # NewEdit 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 2 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, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # $Id: i18n.py 19 2005-09-10 15:37:08Z limodou $ import gettext import glob import os.path import locale import codecs class _DUMY_CLASS:pass class I18n(object): def __init__(self, domain, path): self.translation ={} self.lang = '' self.domain = domain mos = glob.glob(os.path.join(path, '%s*.mo' % domain)) for filename in mos: f = os.path.splitext(os.path.basename(filename))[0] if f.startswith(domain + '_'): lang = f.split('_', 1)[1] self.translation[lang] = obj = _DUMY_CLASS() obj.mofile = os.path.normpath(filename) obj.transobj = None def install(self, lang): if self.translation.has_key(lang): if not self.translation[lang].transobj: self.translation[lang].transobj = obj = gettext.GNUTranslations(file(self.translation[lang].mofile, 'rb')) func = self.translation[lang].transobj.ugettext else: obj = gettext.NullTranslations() func = obj.ugettext return func class BasicTR(object): i18n = None defaultlang = None def init(i18n, defaultlang): BasicTR.i18n = i18n BasicTR.defaultlang = defaultlang init = staticmethod(init) def __init__(self, msg, lang=None): self.lang = lang self.func = None self.msg = None self.args = None self.nnodes = [] self.pnodes = [] self.setlang(self.lang) self.msg = msg def para(self, *args): self.args = args return self def __unicode__(self): return self.getvalue() def __str__(self): value = self.getvalue() if isinstance(value, unicode): try: return value.encode(locale.getdefaultlocale()[1]) except: return value.encode('utf-8') else: return value def getvalue(self): if self.args: if len(self.args) == 1 and isinstance(self.args[0], dict): value = self.func(self.msg) % self.args[0] else: value = self.func(self.msg) % self.args else: value = self.func(self.msg) return ''.join(map(self._getvalue, self.pnodes)) + value + ''.join(map(self._getvalue, self.nnodes)) def _getvalue(self, obj): if isinstance(obj, BasicTR): return unicode(obj) else: return obj def __repr__(self): return self.__str__() def __add__(self, obj): self.nnodes.append(obj) return self def __radd__(self, obj): self.pnodes.append(obj) return self def setlang(self, lang): self.lang = lang if not self.lang: lang = self.defaultlang else: lang = self.lang self.func = self.i18n.install(lang) for obj in self.pnodes: if isinstance(obj, BasicTR): obj.setlang(lang) for obj in self.nnodes: if isinstance(obj, BasicTR): obj.setlang(lang) def clear(self): self.lang = None self.setlang(self.lang) def encode(self, encoding): return self.getvalue().encode(encoding) def __getattr__(self, name): return getattr(self.getvalue(), name) def install(domain, path, lang, func='_'): i18nobj = I18n(domain, path) BasicTR.init(i18nobj, lang) import __builtin__ __builtin__.__dict__[func] = BasicTR def isobj(msg): if isinstance(msg, BasicTR): return True else: return False def Unicode(msg, encoding): if isobj(msg): return msg.getvalue() else: return unicode(msg, encoding) def listlang(): return BasicTR.i18n.translation.keys() + ['en'] if __name__ == '__main__': install('confbot', 'locale', 'zh_CN') #a = _('Success') + 'c' + _('%s is %s').para('1', '2') + 'aaa' a = _('You %s %s').para('1', '2') print a print Unicode(_('''Topic: %(topic)s %(lastlog)s''').para({ "topic" : 'topic', "lastlog" : "\n".join(['a']), }) + '\n---------------\n', 'gbk').encode('gbk')