apppublic/appPublic/i18n.py
2022-05-20 19:52:02 +08:00

162 lines
3.5 KiB
Python

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(path=None, coding='utf8'):
if path is None:
path = ProgramPath()
i18n = MiniI18N(path,coding)
return i18n