diff options
| -rw-r--r-- | odoo/addons/test_translation_import/tests/test_term_count.py | 44 | ||||
| -rw-r--r-- | odoo/tools/translate.py | 22 |
2 files changed, 59 insertions, 7 deletions
diff --git a/odoo/addons/test_translation_import/tests/test_term_count.py b/odoo/addons/test_translation_import/tests/test_term_count.py index 234bc743fc3..87963c3550e 100644 --- a/odoo/addons/test_translation_import/tests/test_term_count.py +++ b/odoo/addons/test_translation_import/tests/test_term_count.py @@ -7,7 +7,7 @@ import io import odoo from odoo.tests import common, tagged from odoo.tools.misc import file_open, mute_logger -from odoo.tools.translate import _, _lt +from odoo.tools.translate import _, _lt, TranslationFileReader TRANSLATED_TERM = _lt("Klingon") @@ -228,6 +228,48 @@ class TestTermCount(common.TransactionCase): self.env.context = dict(self.env.context, lang="dot") self.assertEqual(_("Accounting"), "samva", "The code translation was not applied") + def test_export_pollution(self): + """ Test that exporting the translation only exports the translations of the module """ + with file_open('test_translation_import/i18n/dot.csv', 'rb') as f: + csv_file = base64.b64encode(f.read()) + + # dot.csv only contains one term + import_tlh = self.env["base.language.import"].create({ + 'name': 'Dothraki', + 'code': 'dot', + 'data': csv_file, + 'filename': 'dot.csv', + }) + with mute_logger('odoo.addons.base.models.res_lang'): + import_tlh.import_lang() + + # create a translation that has the same src as an existing field but no module + # information and a different res_id that the real field + # this translation should not be included in the export + self.env['ir.translation'].create({ + 'src': '1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB', + 'value': '1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB in Dothraki', + 'type': 'model', + 'name': 'ir.model.fields,field_description', + 'res_id': -1, + 'lang': 'dot', + }) + module = self.env.ref('base.module_test_translation_import') + export = self.env["base.language.export"].create({ + 'lang': 'dot', + 'format': 'po', + 'modules': [(6, 0, [module.id])] + }) + export.act_getfile() + po_file = export.data + reader = TranslationFileReader(base64.b64decode(po_file).decode(), fileformat='po') + for row in reader: + if row['value']: + # should contains only one row from the csv, not the manual one + self.assertEqual(row['src'], "Accounting") + self.assertEqual(row['value'], "samva") + + @tagged('post_install', '-at_install') class TestTranslationFlow(common.TransactionCase): diff --git a/odoo/tools/translate.py b/odoo/tools/translate.py index 1a96b8f192e..f8a4be823aa 100644 --- a/odoo/tools/translate.py +++ b/odoo/tools/translate.py @@ -903,11 +903,22 @@ class TranslationModuleReader: """ Export ir.translation values for all retrieved records """ IrTranslation = self.env['ir.translation'] - for module, source, name, res_id, ttype, comments in self._to_translate: - trans = IrTranslation._get_source(name, ttype, self._lang, source) if self._lang else "" + for module, source, name, res_id, ttype, comments, record_id in self._to_translate: + trans = ( + IrTranslation._get_source(name if type != "code" else None, ttype, self._lang, source, res_id=record_id) + if self._lang + else "" + ) yield (module, ttype, name, res_id, source, encode(trans) or '', comments) - def _push_translation(self, module, ttype, name, res_id, source, comments=None): + def _push_translation(self, module, ttype, name, res_id, source, comments=None, record_id=None): + """ Insert a translation that will be used in the file generation + In po file will create an entry + #: <ttype>:<name>:<res_id> + #, <comment> + msgid "<source>" + record_id is the database id of the record being translated + """ # empty and one-letter terms are ignored, they probably are not meant to be # translated, and would be very hard to translate anyway. sanitized_term = (source or '').strip() @@ -915,8 +926,7 @@ class TranslationModuleReader: sanitized_term = re.sub(r'\W+', '', sanitized_term) if not sanitized_term or len(sanitized_term) <= 1: return - - self._to_translate.append((module, source, name, res_id, ttype, tuple(comments or ()))) + self._to_translate.append((module, source, name, res_id, ttype, tuple(comments or ()), record_id)) def _get_translatable_records(self, records): """ Filter the records that are translatable @@ -1004,7 +1014,7 @@ class TranslationModuleReader: 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) + self._push_translation(module, trans_type, name, xml_name, term, record_id=record.id) def _get_module_from_path(self, path): for (mp, rec) in self._path_list: |
