tuxbot-bot/venv/lib/python3.7/site-packages/i18n/dbtranslator.py
2019-12-16 18:12:10 +01:00

113 lines
3.6 KiB
Python

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
#
from i18n.translator import Translator
def setup_model(engine):
Base = declarative_base(bind=engine)
Session = sessionmaker(bind=engine)
class TranslationEntry(Base):
__tablename__ = 'translation_entries'
language = Column(String, primary_key=True) # destination language, e.g. it_IT
msgid = Column(String, primary_key=True)
msgstr = Column(String)
msgstr_plural = Column(String)
def __init__(self, language, msgid, msgstr, msgstr_plural=None):
self.language = language
self.msgid = msgid
self.msgstr = msgstr
self.msgstr_plural = msgstr_plural
def __repr__(self):
return "<Translation('%s','%s', '%s')>" % (
self.language, self.msgid, self.msgstr)
Base.metadata.create_all(engine)
return locals()
class DBModel(object):
def __init__(self, engine):
self.__dict__.update(setup_model(engine))
class DBTranslator(Translator):
def __init__(self, rootdir, languages, dest_language=None, autocompile=True,
engine=None):
if engine is None:
raise TypeError('the engine parameter is non-optional')
Translator.__init__(self, rootdir, languages, dest_language, autocompile)
self.engine = engine
self.db = DBModel(engine)
self.session = self.db.Session()
self._cache = {}
def reload(self):
Translator.reload(self)
self.clear_cache()
def clear_cache(self):
self._cache.clear()
def add_translation(self, language, msgid, msgstr, msgstr_plural=None):
x = self.db.TranslationEntry(language, msgid, msgstr, msgstr_plural)
self.session.add(x)
self.session.commit()
self.clear_cache()
def _cached(self, fn, *args):
try:
return self._cache[args]
except KeyError:
res = fn(*args)
self._cache[args] = res
return res
def gettext(self, msgid):
def get(msgid):
entry = self._lookup_entry(msgid)
if entry is not None:
return entry.msgstr
else:
return Translator.gettext(self, msgid)
#
return self._cached(get, msgid)
def ngettext(self, msgid, msgid_plural, n):
def get(msgid, msgid_plural, is_plural):
entry = self._lookup_entry(msgid, msgid_plural)
if entry is not None:
if is_plural:
return entry.msgstr_plural
else:
return entry.msgstr
else:
return Translator.ngettext(self, msgid, msgid_plural, n)
#
is_plural = (n != 1)
return self._cached(get, msgid, msgid_plural, is_plural)
def _lookup_entry(self, msgid, msgid_plural=None):
Entry = self.db.TranslationEntry
q = self.session.query(Entry).filter_by(language = self.dest_language,
msgid = msgid)
if msgid_plural is None:
q = q.filter(Entry.msgstr_plural == None)
else:
q = q.filter(Entry.msgstr_plural != None)
rows = q.all()
if len(rows) == 0:
return None
elif len(rows) == 1:
return rows[0]
else:
# cannot happen because (language, msgid) is the primary key
assert False, "Multiple translations of %s found: %s" % (msgid, rows)