[IMP] ir.translation,tools.translate._(): cleanup and speedup if translations via _()
- Removed expensive inspect.stack() (courtesy of xrg) - Improved heuristics for detection of context/lang and cursor - Switch to using ir.translation when possible instead of direct DB hit to benefit from cache - Cleanup lp bug: https://launchpad.net/bugs/624114 fixed bzr revid: odo@openerp.com-20101215114019-psrsu998inw6cksu
This commit is contained in:
parent
516dc572c4
commit
650490d61d
|
@ -138,7 +138,7 @@ class ir_translation(osv.osv):
|
||||||
and source. All values passed to this method should be unicode (not byte strings),
|
and source. All values passed to this method should be unicode (not byte strings),
|
||||||
especially ``source``.
|
especially ``source``.
|
||||||
|
|
||||||
:param name: identification of the term to translate, such as field name
|
:param name: identification of the term to translate, such as field name (optional if source is passed)
|
||||||
:param types: single string defining type of term to translate (see ``type`` field on ir.translation), or sequence of allowed types (strings)
|
:param types: single string defining type of term to translate (see ``type`` field on ir.translation), or sequence of allowed types (strings)
|
||||||
:param lang: language code of the desired translation
|
:param lang: language code of the desired translation
|
||||||
:param source: optional source term to translate (should be unicode)
|
:param source: optional source term to translate (should be unicode)
|
||||||
|
@ -153,19 +153,22 @@ class ir_translation(osv.osv):
|
||||||
if isinstance(types, basestring):
|
if isinstance(types, basestring):
|
||||||
types = (types,)
|
types = (types,)
|
||||||
if source:
|
if source:
|
||||||
cr.execute('select value ' \
|
query = """SELECT value
|
||||||
'from ir_translation ' \
|
FROM ir_translation
|
||||||
'where lang=%s ' \
|
WHERE lang=%s
|
||||||
'and type in %s ' \
|
AND type in %s
|
||||||
'and name=%s ' \
|
AND src=%s"""
|
||||||
'and src=%s',
|
params = (lang or '', types, source)
|
||||||
(lang or '', types, tools.ustr(name), source))
|
if name:
|
||||||
|
query += " AND name=%s"
|
||||||
|
params += (tools.ustr(name),)
|
||||||
|
cr.execute(query, params)
|
||||||
else:
|
else:
|
||||||
cr.execute('select value ' \
|
cr.execute("""SELECT value
|
||||||
'from ir_translation ' \
|
FROM ir_translation
|
||||||
'where lang=%s ' \
|
WHERE lang=%s
|
||||||
'and type in %s ' \
|
AND type in %s
|
||||||
'and name=%s',
|
AND name=%s"""
|
||||||
(lang or '', types, tools.ustr(name)))
|
(lang or '', types, tools.ustr(name)))
|
||||||
res = cr.fetchone()
|
res = cr.fetchone()
|
||||||
trad = res and res[0] or u''
|
trad = res and res[0] or u''
|
||||||
|
|
|
@ -26,10 +26,12 @@ import inspect
|
||||||
import itertools
|
import itertools
|
||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
|
import pooler
|
||||||
import re
|
import re
|
||||||
import logging
|
import logging
|
||||||
import tarfile
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import threading
|
||||||
from os.path import join
|
from os.path import join
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -153,48 +155,79 @@ logger = logging.getLogger('translate')
|
||||||
|
|
||||||
class GettextAlias(object):
|
class GettextAlias(object):
|
||||||
|
|
||||||
|
def _get_db_pool(self):
|
||||||
|
# find current DB based on thread/worker db name (see netsvc)
|
||||||
|
db_name = getattr(threading.currentThread(), 'dbname', None)
|
||||||
|
if db_name:
|
||||||
|
dbname = getattr(threading.currentThread(), 'dbname')
|
||||||
|
return pooler.get_db_and_pool(dbname)
|
||||||
|
return (None, None)
|
||||||
|
|
||||||
def _get_cr(self, frame):
|
def _get_cr(self, frame):
|
||||||
is_new_cr = False
|
new_cr = False
|
||||||
cr = frame.f_locals.get('cr')
|
cr = frame.f_locals.get('cr', frame.f_locals.get('cursor'))
|
||||||
if not cr:
|
if not cr:
|
||||||
s = frame.f_locals.get('self', {})
|
s = frame.f_locals.get('self', {})
|
||||||
cr = getattr(s, 'cr', False)
|
cr = getattr(s, 'cr', None)
|
||||||
if not cr:
|
if not cr:
|
||||||
if frame.f_globals.get('pooler', False):
|
db, _ = self._get_db_pool()
|
||||||
# TODO: we should probably get rid of the 'is_new_cr' case: no cr in locals -> no translation for you
|
if db:
|
||||||
dbs = frame.f_globals['pooler'].pool_dic.keys()
|
cr = db.cursor()
|
||||||
if len(dbs) == 1:
|
new_cr = True
|
||||||
cr = pooler.get_db(dbs[0]).cursor()
|
return cr, new_cr
|
||||||
is_new_cr = True
|
|
||||||
return cr, is_new_cr
|
|
||||||
|
|
||||||
def _get_lang(self, frame):
|
def _get_lang(self, frame):
|
||||||
lang = frame.f_locals.get('context', {}).get('lang', False)
|
lang = None
|
||||||
|
ctx = frame.f_locals.get('context')
|
||||||
|
if not ctx:
|
||||||
|
kwargs = frame.f_locals.get('kwargs')
|
||||||
|
if kwargs is None:
|
||||||
|
args = frame.f_locals.get('args')
|
||||||
|
if args and isinstance(args, (list, tuple)) \
|
||||||
|
and isinstance(args[-1], dict):
|
||||||
|
ctx = args[-1]
|
||||||
|
elif isinstance(kwargs, dict):
|
||||||
|
ctx = kwargs.get('context')
|
||||||
|
if ctx:
|
||||||
|
lang = ctx.get('lang')
|
||||||
if not lang:
|
if not lang:
|
||||||
args = frame.f_locals.get('args', False)
|
s = frame.f_locals.get('self', {})
|
||||||
if args:
|
c = getattr(s, 'localcontext', None)
|
||||||
lang = args[-1].get('lang', False)
|
if c:
|
||||||
if not lang:
|
lang = c.get('lang')
|
||||||
s = frame.f_locals.get('self', {})
|
|
||||||
c = getattr(s, 'localcontext', {})
|
|
||||||
lang = c.get('lang', False)
|
|
||||||
return lang
|
return lang
|
||||||
|
|
||||||
def __call__(self, source):
|
def __call__(self, source):
|
||||||
is_new_cr = False
|
|
||||||
res = source
|
res = source
|
||||||
|
cr = None
|
||||||
|
new_cr = False
|
||||||
try:
|
try:
|
||||||
frame = inspect.stack()[1][0]
|
frame = inspect.currentframe()
|
||||||
cr, is_new_cr = self._get_cr(frame)
|
if frame is None:
|
||||||
|
return source
|
||||||
|
frame = frame.f_back
|
||||||
|
if not frame:
|
||||||
|
return source
|
||||||
lang = self._get_lang(frame)
|
lang = self._get_lang(frame)
|
||||||
if lang and cr:
|
if lang:
|
||||||
cr.execute('SELECT value FROM ir_translation WHERE lang=%s AND type IN (%s, %s) AND src=%s', (lang, 'code','sql_constraint', source))
|
cr, new_cr = self._get_cr(frame)
|
||||||
res_trans = cr.fetchone()
|
if cr:
|
||||||
res = res_trans and res_trans[0] or source
|
# Try to use ir.translation to benefit from global cache if possible
|
||||||
|
_, pool = self._get_db_pool()
|
||||||
|
if pool:
|
||||||
|
res = pool.get('ir.translation')._get_source(cr, 1, None, ('code','sql_constraint'), lang, source)
|
||||||
|
else:
|
||||||
|
cr.execute('SELECT value FROM ir_translation WHERE lang=%s AND type IN (%s, %s) AND src=%s', (lang, 'code','sql_constraint', source))
|
||||||
|
res_trans = cr.fetchone()
|
||||||
|
res = res_trans and res_trans[0] or source
|
||||||
|
else:
|
||||||
|
logger.debug('no context cursor detected, skipping translation for "%r"', source)
|
||||||
|
else:
|
||||||
|
logger.debug('no translation language detected, skipping translation for "%r" ', source)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.debug('translation went wrong for string %s', repr(source))
|
logger.debug('translation went wrong for "%r", skipped', source)
|
||||||
finally:
|
finally:
|
||||||
if is_new_cr:
|
if cr and new_cr:
|
||||||
cr.close()
|
cr.close()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue