Permalink
Browse files

[FIX] tools: skip bad translations

Backport of fccfd36, 4ba7fbb and 1421949 to saas-11.3

[FIX] tools: use pot as reference file

In the first attempt at #26134, the pot_targets was cleared after creating
the pot_rows object.

Since the rows not present in the pot_targets are now skipped, clearing the pot
should not be done.

Still use a temporary list pot_rows to avoid modifying the list we are iterating
on.

Update the .po test file to match the new file format

[FIX] tools: import translation file without pot

Due to fccfd36 and 4ba7fbb the translations were only imported, considering the
.pot as the reference.

During import or a manual csv or po file, there is no pot file.

Add tests with Klingon and Dothraki
  • Loading branch information...
mart-e committed Aug 2, 2018
1 parent 93b2a55 commit 2de89988632d8ddb53966a973223d7fa1c7c6f98
@@ -0,0 +1,2 @@
module,type,name,res_id,src,value,comments
test_translation_import,code,addons/test_translation_import/models.py,20,Accounting,samva,
@@ -35,7 +35,7 @@ msgid "test.translation.import"
msgstr "test.translation.import in french"
#. module: test_translation_import
#: help:test.translation.import,name:0
#: model:ir.model.fields,help:test_translation_import.field_test_translation_import__name
msgid "Efgh"
msgstr "Efgh in french"
@@ -41,7 +41,7 @@ msgid "test.translation.import"
msgstr ""
#. module: test_translation_import
#: help:test.translation.import,name:0
#: model:ir.model.fields,help:test_translation_import.field_test_translation_import__name
msgid "Efgh"
msgstr ""
@@ -0,0 +1,20 @@
# This is a test PO file, not a complete one. It is manually maintained
# to test the import translation behavior of Odoo.
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server saas~11.4\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-09-18 13:20+0000\n"
"PO-Revision-Date: 2018-09-18 13:20+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: test_translation_import
#: code:addons/test_translation_import/models.py:18
#, python-format
msgid "Klingon"
msgstr "tlhIngan"
@@ -14,3 +14,7 @@ class m(models.TransientModel):
# With the name label above, this source string should be generated twice.
_('1XBUO5PUYH2RYZSA1FTLRYS8SPCNU1UYXMEYMM25ASV7JC2KTJZQESZYRV9L8CGB')
_('Klingon')
_('Accounting')
@@ -1,10 +1,13 @@
# -*- coding: utf-8 -*-
from contextlib import closing
import base64
import io
import odoo
from odoo.tests import common
from odoo.tools.misc import file_open, mute_logger
from odoo.tools.translate import _
class TestTermCount(common.TransactionCase):
@@ -79,3 +82,49 @@ def update_translations():
menu.with_context(lang='fr_FR').name = "Nouveau nom"
update_translations()
self.assertEqual(menu.with_context(lang='fr_FR').name, "Nouveau nom", 'The translation of "New Name" should be "Nouveau nom"')
def test_import_from_po_file(self):
"""Test the import from a single po file works"""
with file_open('test_translation_import/i18n/tlh.po', 'rb') as f:
po_file = base64.encodestring(f.read())
import_tlh = self.env["base.language.import"].create({
'name': 'Klingon',
'code': 'tlh',
'data': po_file,
'filename': 'tlh.po',
})
with mute_logger('odoo.addons.base.models.res_lang'):
import_tlh.import_lang()
lang_count = self.env['res.lang'].search_count([('code', '=', 'tlh')])
self.assertEqual(lang_count, 1, "The imported language was not creates")
trans_count = self.env['ir.translation'].search_count([('lang', '=', 'tlh')])
self.assertEqual(trans_count, 1, "The imported translations were not created")
self.env.context = dict(self.env.context, lang="tlh")
self.assertEqual(_("Klingon"), "tlhIngan", "The code translation was not applied")
def test_import_from_csv_file(self):
"""Test the import from a single CSV file works"""
with file_open('test_translation_import/i18n/dot.csv', 'rb') as f:
po_file = base64.encodestring(f.read())
import_tlh = self.env["base.language.import"].create({
'name': 'Dothraki',
'code': 'dot',
'data': po_file,
'filename': 'dot.csv',
})
with mute_logger('odoo.addons.base.models.res_lang'):
import_tlh.import_lang()
lang_count = self.env['res.lang'].search_count([('code', '=', 'dot')])
self.assertEqual(lang_count, 1, "The imported language was not creates")
trans_count = self.env['ir.translation'].search_count([('lang', '=', 'dot')])
self.assertEqual(trans_count, 1, "The imported translations were not created")
self.env.context = dict(self.env.context, lang="dot")
self.assertEqual(_("Accounting"), "samva", "The code translation was not applied")
View
@@ -1037,6 +1037,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True,
# (Because the POT comments are correct on Launchpad but not the
# PO comments due to a Launchpad limitation. See LP bug 933496.)
pot_reader = []
use_pot_reference = False
# now, the serious things: we read the language file
fileobj.seek(0)
@@ -1065,6 +1066,7 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True,
pot_handle = file_open(os.path.join(
addons, module, i18n_dir, module + '.pot'), mode='rb')
pot_reader = PoFile(pot_handle)
use_pot_reference = True
except:
pass
@@ -1099,12 +1101,18 @@ def process_row(row):
dic['lang'] = lang
dic.update(pycompat.izip(fields, row))
# discard the target from the POT targets.
src = dic['src']
if src in pot_targets:
target = pot_targets[src]
if use_pot_reference:
# discard the target from the POT targets.
src = dic['src']
target_key = (dic['type'], dic['name'], dic['type'] != 'code' and dic['res_id'] or 0)
target = pot_targets.get(src)
if not target or target_key not in target.targets:
_logger.info("Translation '%s' (%s, %s, %s) not found in reference pot, skipping",
src[:60], dic['type'], dic['name'], dic['res_id'])
return
target.value = dic['value']
target.targets.discard((dic['type'], dic['name'], dic['type'] != 'code' and dic['res_id'] or 0))
target.targets.discard(target_key)
# This would skip terms that fail to specify a res_id
res_id = dic['res_id']
@@ -1132,16 +1140,16 @@ def process_row(row):
for row in reader:
process_row(row)
# Then process the entries implied by the POT file (which is more
# correct w.r.t. the targets) if some of them remain.
pot_rows = []
for src, target in pot_targets.items():
if target.value:
for type, name, res_id in target.targets:
pot_rows.append((type, name, res_id, src, target.value, target.comments))
pot_targets.clear()
for row in pot_rows:
process_row(row)
if use_pot_reference:
# Then process the entries implied by the POT file (which is more
# correct w.r.t. the targets) if some of them remain.
pot_rows = []
for src, target in pot_targets.items():
if target.value:
for type, name, res_id in target.targets:
pot_rows.append((type, name, res_id, src, target.value, target.comments))
for row in pot_rows:
process_row(row)
irt_cursor.finish()
Translation.clear_caches()

0 comments on commit 2de8998

Please sign in to comment.