[IMP] translation: load translations from ir.translation after authenticating, use local POs for bootstrap only (login page)
bzr revid: odo@openerp.com-20120918072802-568n19bg1ecm1m2t
This commit is contained in:
parent
aef309a11c
commit
a3a2ec416b
|
@ -19,7 +19,6 @@ import zlib
|
|||
from xml.etree import ElementTree
|
||||
from cStringIO import StringIO
|
||||
|
||||
import babel.messages.pofile
|
||||
import werkzeug.utils
|
||||
import werkzeug.wrappers
|
||||
try:
|
||||
|
@ -203,47 +202,8 @@ def module_installed(req):
|
|||
sorted_modules = module_topological_sort(modules)
|
||||
return sorted_modules
|
||||
|
||||
def module_installed_bypass_session(dbname):
|
||||
loadable = openerpweb.addons_manifest.keys()
|
||||
modules = {}
|
||||
try:
|
||||
import openerp.modules.registry
|
||||
registry = openerp.modules.registry.RegistryManager.get(dbname)
|
||||
with registry.cursor() as cr:
|
||||
m = registry.get('ir.module.module')
|
||||
# TODO The following code should move to ir.module.module.list_installed_modules()
|
||||
domain = [('state','=','installed'), ('name','in', loadable)]
|
||||
ids = m.search(cr, 1, [('state','=','installed'), ('name','in', loadable)])
|
||||
for module in m.read(cr, 1, ids, ['name', 'dependencies_id']):
|
||||
modules[module['name']] = []
|
||||
deps = module.get('dependencies_id')
|
||||
if deps:
|
||||
deps_read = registry.get('ir.module.module.dependency').read(cr, 1, deps, ['name'])
|
||||
dependencies = [i['name'] for i in deps_read]
|
||||
modules[module['name']] = dependencies
|
||||
except Exception,e:
|
||||
pass
|
||||
sorted_modules = module_topological_sort(modules)
|
||||
return sorted_modules
|
||||
|
||||
def module_boot(req):
|
||||
serverside = []
|
||||
dbside = []
|
||||
for i in req.config.server_wide_modules:
|
||||
if i in openerpweb.addons_manifest:
|
||||
serverside.append(i)
|
||||
# if only one db load every module at boot
|
||||
dbs = []
|
||||
try:
|
||||
dbs = db_list(req)
|
||||
except xmlrpclib.Fault:
|
||||
# ignore access denied
|
||||
pass
|
||||
if len(dbs) == 1:
|
||||
dbside = module_installed_bypass_session(dbs[0])
|
||||
dbside = [i for i in dbside if i not in serverside]
|
||||
addons = serverside + dbside
|
||||
return addons
|
||||
return [m for m in req.config.server_wide_modules if m in openerpweb.addons_manifest]
|
||||
|
||||
def concat_xml(file_list):
|
||||
"""Concatenate xml files
|
||||
|
@ -531,6 +491,38 @@ def parse_context(context, session):
|
|||
except ValueError:
|
||||
return common.nonliterals.Context(session, context)
|
||||
|
||||
|
||||
# PO file parsing - only used to boostrap translations on the login page
|
||||
try:
|
||||
# Use the faster PO parser from OpenERP server when available
|
||||
from openerp.tools.translate import TinyPoFile
|
||||
def _local_web_translations(trans_file):
|
||||
messages = []
|
||||
try:
|
||||
with open(trans_file) as t_file:
|
||||
po = TinyPoFile(t_file)
|
||||
for _, _, _, source, value, comments in po:
|
||||
if "openerp-web" in comments:
|
||||
messages.append({'id': source, 'string': value})
|
||||
except Exception:
|
||||
pass
|
||||
return messages
|
||||
except ImportError:
|
||||
# Otherwise fallback to Babel's slightly slower PO parser
|
||||
import babel.messages.pofile
|
||||
def _local_web_translations(trans_file):
|
||||
messages = []
|
||||
try:
|
||||
with open(trans_file) as t_file:
|
||||
po = babel.messages.pofile.read_po(t_file)
|
||||
except Exception:
|
||||
return
|
||||
for x in po:
|
||||
if x.id and x.string and "openerp-web" in x.auto_comments:
|
||||
messages.append({'id': x.id, 'string': x.string})
|
||||
return messages
|
||||
|
||||
|
||||
#----------------------------------------------------------
|
||||
# OpenERP Web web Controllers
|
||||
#----------------------------------------------------------
|
||||
|
@ -576,6 +568,7 @@ class Home(openerpweb.Controller):
|
|||
def login(self, req, db, login, key):
|
||||
return login_and_redirect(req, db, login, key)
|
||||
|
||||
|
||||
class WebClient(openerpweb.Controller):
|
||||
_cp_path = "/web/webclient"
|
||||
|
||||
|
@ -658,41 +651,59 @@ class WebClient(openerpweb.Controller):
|
|||
last_modified, checksum)
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def translations(self, req, mods, lang):
|
||||
lang_model = req.session.model('res.lang')
|
||||
ids = lang_model.search([("code", "=", lang)])
|
||||
if ids:
|
||||
lang_obj = lang_model.read(ids[0], ["direction", "date_format", "time_format",
|
||||
"grouping", "decimal_point", "thousands_sep"])
|
||||
else:
|
||||
lang_obj = None
|
||||
def bootstrap_translations(self, req, mods):
|
||||
""" Load local translations from *.po files, as a temporary solution
|
||||
until we have established a valid session. This is meant only
|
||||
for translating the login page and db management chrome, using
|
||||
the browser's language. """
|
||||
lang = req.httprequest.accept_languages.best or 'en'
|
||||
# For performance reasons we only load a single translation, so for
|
||||
# sub-languages (that should only be partially translated) we load the
|
||||
# main language PO instead - that should be enough for the login screen.
|
||||
if '-' in lang: # RFC2616 uses '-' separators for sublanguages
|
||||
lang = [lang.split('-',1)[0], lang]
|
||||
|
||||
if "_" in lang:
|
||||
separator = "_"
|
||||
else:
|
||||
separator = "@"
|
||||
langs = lang.split(separator)
|
||||
langs = [separator.join(langs[:x]) for x in range(1, len(langs) + 1)]
|
||||
|
||||
proxy = req.session.proxy("translation")
|
||||
messages = proxy.load(req.session._db, mods, langs, "web")
|
||||
translations_per_module = {}
|
||||
for addon_name in mods:
|
||||
if not messages[addon_name]['messages']:
|
||||
addons_path = openerpweb.addons_manifest[addon_name]['addons_path']
|
||||
for l in langs:
|
||||
f_name = os.path.join(addons_path, addon_name, "i18n", l + ".po")
|
||||
if not os.path.exists(f_name):
|
||||
continue
|
||||
try:
|
||||
with open(f_name) as t_file:
|
||||
po = babel.messages.pofile.read_po(t_file)
|
||||
except Exception:
|
||||
continue
|
||||
for x in po:
|
||||
if x.id and x.string and "openerp-web" in x.auto_comments:
|
||||
messages[addon_name]["messages"].append({'id': x.id, 'string': x.string})
|
||||
return {"modules": messages,
|
||||
"lang_parameters": lang_obj}
|
||||
addons_path = openerpweb.addons_manifest[addon_name]['addons_path']
|
||||
f_name = os.path.join(addons_path, addon_name, "i18n", lang + ".po")
|
||||
if not os.path.exists(f_name):
|
||||
continue
|
||||
translations_per_module[addon_name] = {'messages': _local_web_translations(f_name)}
|
||||
|
||||
return {"modules": translations_per_module,
|
||||
"lang_parameters": None}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def translations(self, req, mods, lang):
|
||||
res_lang = req.session.model('res.lang')
|
||||
ids = res_lang.search([("code", "=", lang)])
|
||||
lang_params = None
|
||||
if ids:
|
||||
lang_params = res_lang.read(ids[0], ["direction", "date_format", "time_format",
|
||||
"grouping", "decimal_point", "thousands_sep"])
|
||||
|
||||
# Regional languages (ll_CC) must inherit/override their parent lang (ll), but this is
|
||||
# done server-side when the language is loaded, so we only need to load the user's lang.
|
||||
start = datetime.datetime.now()
|
||||
ir_translation = req.session.model('ir.translation')
|
||||
translations_per_module = {}
|
||||
messages = ir_translation.search_read([('module','in',mods),('lang','=',lang),
|
||||
('comments','like','openerp-web'),('value','!=',False),
|
||||
('value','!=','')],
|
||||
['module','src','value','lang'], order='module')
|
||||
for mod, msg_group in itertools.groupby(messages, key=operator.itemgetter('module')):
|
||||
translations_per_module.setdefault(mod,{'messages':[]})
|
||||
translations_per_module[mod]['messages'].extend({'id': m['src'],
|
||||
'string': m['value']} \
|
||||
for m in msg_group)
|
||||
|
||||
print "Loaded translations in ", datetime.datetime.now()-start
|
||||
import pprint
|
||||
pprint.pprint(translations_per_module)
|
||||
|
||||
return {"modules": translations_per_module,
|
||||
"lang_parameters": lang_params}
|
||||
|
||||
@openerpweb.jsonrequest
|
||||
def version_info(self, req):
|
||||
|
@ -769,7 +780,7 @@ class Database(openerpweb.Controller):
|
|||
{'fileToken': int(token)}
|
||||
)
|
||||
except xmlrpclib.Fault, e:
|
||||
return simplejson.dumps([[],[{'error': e.faultCode, 'title': 'backup Database'}]])
|
||||
return simplejson.dumps([[],[{'error': e.faultCode, 'title': 'backup Database'}]])
|
||||
|
||||
@openerpweb.httprequest
|
||||
def restore(self, req, db_file, restore_pwd, new_db):
|
||||
|
|
|
@ -57,7 +57,12 @@ instance.web.Session = instance.web.JsonRPC.extend( /** @lends instance.web.Sess
|
|||
if(self.session_is_valid()) {
|
||||
return deferred.pipe(function() { return self.load_modules(); });
|
||||
}
|
||||
return deferred;
|
||||
return $.when(
|
||||
deferred,
|
||||
self.rpc('/web/webclient/bootstrap_translations', {mods: instance._modules}).pipe(function(trans) {
|
||||
instance.web._t.database.set_bundle(trans);
|
||||
})
|
||||
);
|
||||
});
|
||||
},
|
||||
/**
|
||||
|
|
|
@ -407,7 +407,7 @@
|
|||
<a class="oe_logo" href="#"><img t-att-src='_s + "/web/static/src/img/logo.png"'/></a>
|
||||
<div class="oe_secondary_menus_container"/>
|
||||
<div class="oe_footer">
|
||||
Powered by <a href="http://www.openerp.com" target="_blank"><span>Open</span>ERP</a>
|
||||
Powered by <a href="http://www.openerp.com" target="_blank"><span>OpenERP</span></a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="oe_application">
|
||||
|
|
Loading…
Reference in New Issue