Skip to content
Permalink
Browse files

[test] export in batch

So much performance
  • Loading branch information...
mart-e committed Oct 30, 2019
1 parent 87d0e35 commit f377af9a26c101677ccf1f3e56a76d3409895637
Showing with 67 additions and 36 deletions.
  1. +67 −36 odoo/tools/translate.py
@@ -13,7 +13,7 @@
import tarfile
import tempfile
import threading
from collections import defaultdict
from collections import defaultdict, namedtuple
from datetime import datetime
from os.path import join

@@ -783,9 +783,7 @@ def write_rows(self, rows):
self.tar.close()

# Methods to export the translation file

def trans_export(lang, modules, buffer, format, cr):

reader = TranslationModuleReader(cr, modules=modules, lang=lang)
writer = TranslationFileWriter(buffer, fileformat=format, lang=lang)
writer.write_rows(reader)
@@ -872,6 +870,8 @@ def handle_text(text, lineno):
_extract_translatable_qweb_terms(tree.getroot(), handle_text)
return result

ImdInfo = namedtuple('ExternalId', ['name', 'model', 'res_id', 'module'])


class TranslationModuleReader:
""" Retrieve translated records per module
@@ -918,29 +918,55 @@ def _push_translation(self, module, ttype, name, res_id, source, comments=None):

self._to_translate.append((module, source, name, res_id, ttype, tuple(comments or ())))

def _get_translatable_record(self, model, res_id):
if model not in self.env:
_logger.error("Unable to find object %r", model)
return False

original = record = self.env[model].browse(res_id)
if not record.exists():
_logger.warning("Unable to find object %r with id %d", model, res_id)
return False
def _get_translatable_records(self, records):
""" Filter the records that are translatable
if not record._translate:
return False
A record is considered as untranslatable if:
- it does not exist
- the model is flagged with _translate=False
- it is a field of a model flagged with _translate=False
- it is a selection of a field of a model flagged with _translate=False
if record._name == 'ir.model.fields.selection':
record = record.field_id
if record._name == 'ir.model.fields':
field_name = record.name
field_model = self.env.get(record.model)
if (field_model is None or not field_model._translate or
field_name not in field_model._fields):
return False
:param records: a list of namedtuple ImdInfo belonging to the same model
"""
model = next(iter(records)).model
if model not in self.env:
_logger.error("Unable to find object %r", model)
return self.browse()

if not self.env[model]._translate:
return self.env[model].browse()

res_ids = [r.res_id for r in records]
records = self.env[model].browse(res_ids).exists()
if len(records) < len(res_ids):
missing_ids = set(records.ids) - set(res_ids)
_logger.warning("Unable to find objects %r with id %d", model, ', '.join(missing_ids))
if not records:
return records

if model == 'ir.model.fields.selection':
fields = defaultdict(list)
for selection in records:
fields[selection.field_id] = selection
for field, selection in fields.items():
field_name = field.name
field_model = self.env.get(field.model)
if (field_model is None or not field_model._translate or
field_name not in field_model._fields):
# the selection is linked to a model with _translate=False, remove it
records -= selection
elif model == 'ir.model.fields':
for field in records:
field_name = field.name
field_model = self.env.get(field.model)
if (field_model is None or not field_model._translate or
field_name not in field_model._fields):
# the field is linked to a model with _translate=False, remove it
records -= field

return records

return original

def _export_translatable_records(self):
""" Export translations of all translated records having an external id """
@@ -958,22 +984,27 @@ def _export_translatable_records(self):

self._cr.execute(query, (query_param,))

records_per_model = defaultdict(dict)
for (xml_name, model, res_id, module) in self._cr.fetchall():
record = self._get_translatable_record(model, res_id)
if not record:
records_per_model[model][res_id] = ImdInfo(xml_name, model, res_id, module)

for model, imd_per_id in records_per_model.items():
records = self._get_translatable_records(imd_per_id.values())
if not records:
continue

xml_name = "%s.%s" % (module, xml_name)
for field_name, field in record._fields.items():
if field.translate:
name = model + "," + field_name
try:
value = record[field_name] or ''
except Exception:
continue
for term in set(field.get_trans_terms(value)):
trans_type = 'model_terms' if callable(field.translate) else 'model'
self._push_translation(module, trans_type, name, xml_name, term)
for record in records:
xml_name = "%s.%s" % (imd_per_id[record.id].module, imd_per_id[record.id].name)
for field_name, field in record._fields.items():
if field.translate:
name = model + "," + field_name
try:
value = record[field_name] or ''
except Exception:
continue
for term in set(field.get_trans_terms(value)):
trans_type = 'model_terms' if callable(field.translate) else 'model'
self._push_translation(module, trans_type, name, xml_name, term)

def _get_module_from_path(self, path):
for (mp, rec) in self._path_list:

0 comments on commit f377af9

Please sign in to comment.
You can’t perform that action at this time.