From 1969e95b75af4ac31ba7cf1cc20036738690cbc2 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Tue, 31 Dec 2019 21:55:24 +0800 Subject: [PATCH] rewrite i18n --- appPublic/MiniI18N.py | 96 ++----------------------- appPublic/i18n.py | 160 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+), 92 deletions(-) create mode 100644 appPublic/i18n.py diff --git a/appPublic/MiniI18N.py b/appPublic/MiniI18N.py index 62f7dea..81c2afe 100755 --- a/appPublic/MiniI18N.py +++ b/appPublic/MiniI18N.py @@ -67,7 +67,6 @@ class MiniI18N: self.coding = coding self.id = 'i18n' self.langTextDict = {} - self.messages = {} self.setupMiniI18N() self.missed_pt = None self.translated_pt = None @@ -100,98 +99,16 @@ class MiniI18N: [ self.clientLangs.pop(k,None) for k in self.clientLangs.keys() if self.clientLangs[k]['timestamp'] < tim ] def getLangDict(self,lang): - return self.langTextDict.get('lang',{}) + lang = self.getLangMapping(lang) + return self.langTextDict.get(lang,{}) def getLangText(self,msg,lang=None) : """ """ if lang==None : lang = self.getCurrentLang() - if lang not in self.langTextDict.keys() : - self.langTextDict[lang] = {} - if msg not in self.messages.keys() : - self.messages[msg] = '' - dict = self.langTextDict[lang] - if msg not in dict.keys() : - return msg - return dict[msg] - - def getMissTextList(self,lang=None) : - """ - """ - if lang==None : - lang = self.getCurrentLang() - if lang not in self.langTextDict.keys() : - self.langTextDict[lang] = {} - texts = [] - - keys = list(self.messages.keys()) - keys.sort() - for i in keys : - if i not in self.langTextDict[lang].keys() : - texts.append(charEncode(i) + ':' ) - - s = '\n'.join(texts) - return s - - def getTranslatedTextList(self,lang=None) : - """ - """ - if lang==None : - lang = self.getCurrentLang() - if lang not in self.langTextDict.keys() : - self.langTextDict[lang] = {} - texts = [] - keys = list(self.langTextDict[lang].keys()) - keys.sort() - for i in keys : - texts.append(charEncode(i) + ':' + charEncode(self.langTextDict[lang][i])) - - s = '\n'.join(texts) - return s - - def I18nTranslating(self,newtexts,lang=None,submit='') : - """ - """ - if lang==None : - lang = self.getCurrentLang() - if lang not in self.langTextDict.keys() : - self.langTextDict[lang] = {} - - textDict = getTextDictFromLines(newtexts.split('\n')) - d = {} - if lang in self.langTextDict : - d = self.langTextDict[lang] - self.langTextDict[lang].update(textDict) - for i in textDict.keys() : - self.messages[i] = '' - self.writeTranslateMessage() - - def writeUntranslatedMessages(self) : - p = os.path.join(self.path,'i18n') - langs = [] - - for f in os.listdir(p) : - if os.path.isdir(os.path.join(p,f)) : - langs.append(f) - for lang in langs: - p1 = os.path.join(self.path,'i18n',lang) - if not os.path.exists(p1) : - _mkdir(p1) - p2 = os.path.join(p1,'unmsg.txt') - f = codecs.open(p2,'w',self.coding) - f.write(self.getMissTextList(lang)) - f.close() - - - def writeTranslateMessage(self) : - p1 = os.path.join(self.path,'i18n',self.getCurrentLang()) - if not os.path.exists(p1) : - _mkdir(p1) - p2 = os.path.join(p1,'msg.txt') - f = codecs.open(p2,'w',self.ccoding) - f.write(self.getTranslatedTextList()) - f.close() + textMapping = self.getLangDict(lang) + return textMapping.get(msg,msg) def setupMiniI18N(self) : """ @@ -209,12 +126,7 @@ class MiniI18N: f = codecs.open(p1,'r',self.coding) textDict = getTextDictFromLines(f.readlines()) f.close() - d = {} - if dir in self.langTextDict : - d = self.langTextDict[dir] self.langTextDict[dir] = textDict - for i in textDict.keys() : - self.messages[i] = '' self._p_changed = 1 diff --git a/appPublic/i18n.py b/appPublic/i18n.py new file mode 100644 index 0000000..fee5aef --- /dev/null +++ b/appPublic/i18n.py @@ -0,0 +1,160 @@ +import os,re,sys +import codecs +from appPublic.folderUtils import _mkdir +from appPublic.Singleton import SingletonDecorator +from appPublic.folderUtils import ProgramPath +from appPublic.jsonConfig import getConfig +import threading +import time + +import locale + +comment_re = re.compile(r'\s*#.*') +msg_re = re.compile(r'\s*([^:]*)\s*:\s*([^\s].*)') + +def dictModify(d, md) : + for i in md.keys() : + if md[i]!=None : + d[i] = md[i] + return d + +convert_pairs = {':':'\\x3A', + '\n':'\\x0A', + '\r':'\\x0D', +} + +def charEncode(s) : + r = '' + v = s.split('\\') + s = '\\\\'.join(v) + for i in convert_pairs.keys() : + v = s.split(i) + s = convert_pairs[i].join(v) + # print 'i=',i,'iv=',convert_pairs[i],'s=',s + return s + +def charDecode(s) : + for i in convert_pairs.items() : + v = s.split(i[1]) + s = i[0].join(v) + v = s.split('\\\\') + s = '\\'.join(v) + return s + +def getTextDictFromLines(lines) : + d = {} + for l in lines : + l = ''.join(l.split('\r')) + if comment_re.match(l) : + continue + m = msg_re.match(l) + if m : + grp = m.groups() + d[charDecode(grp[0])] = charDecode(grp[1]) + return d + +def getFirstLang(lang) : + s = lang.split(',') + return s[0] + +@SingletonDecorator +class MiniI18N: + """ + """ + def __init__(self,path,lang=None,coding='utf8') : + self.path = path + l = locale.getdefaultlocale() + self.curLang = l[0] + self.coding = coding + self.id = 'i18n' + self.langTextDict = {} + self.messages = {} + self.setupMiniI18N() + self.missed_pt = None + self.translated_pt = None + self.header_pt = None + self.footer_pt = None + self.show_pt=None + self.clientLangs = {} + self.languageMapping = {} + self.timeout = 600 + config = getConfig() + for l1,l in config.langMapping.items(): + self.setLangMapping(l1,l) + + def __call__(self,msg,lang=None) : + """ + """ + if type(msg) == type(b''): + msg = msg.decode(self.coding) + return self.getLangText(msg,lang) + + def setLangMapping(self,lang,path): + self.languageMapping[lang] = path + + def getLangMapping(self,lang): + return self.languageMapping.get(lang,lang) + + def setTimeout(self,timeout=600): + self.timeout = timeout + + def delClientLangs(self): + t = threading.currentThread() + tim = time.time() - self.timeout + [ self.clientLangs.pop(k,None) for k in self.clientLangs.keys() if self.clientLangs[k]['timestamp'] < tim ] + + def getLangDict(self,lang): + lang = self.getLangMapping(lang) + return self.langTextDict.get(lang,{}) + + def getLangText(self,msg,lang=None) : + """ + """ + if lang==None : + lang = self.getCurrentLang() + textMapping = self.getLangDict(lang) + return textMapping.get(msg,msg) + + def setupMiniI18N(self) : + """ + """ + + p = os.path.join(self.path,'i18n') + langs = [] + + for f in os.listdir(p) : + if os.path.isdir(os.path.join(p,f)) : + langs.append(f) + for dir in langs : + p1 = os.path.join(p,dir,'msg.txt') + if os.path.exists(p1) : + f = codecs.open(p1,'r',self.coding) + textDict = getTextDictFromLines(f.readlines()) + f.close() + d = {} + if dir in self.langTextDict : + d = self.langTextDict[dir] + self.langTextDict[dir] = textDict + for i in textDict.keys() : + self.messages[i] = '' + + self._p_changed = 1 + + def setCurrentLang(self,lang): + lang = self.getLangMapping(lang) + t = time.time() + threadid = threading.currentThread() + a = dict(timestamp=t,lang=lang) + self.clientLangs[threadid] = a + + def getCurrentLang(self) : + """ + """ + threadid = threading.currentThread() + return self.clientLangs[threadid]['lang'] + +def getI18N(coding='utf8'): + path = ProgramPath() + i18n = MiniI18N(path,coding) + return i18n +