[FIX] tools: import translation file without pot
Due tofccfd36and4ba7fbbthe 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 Fixes #27044
This commit is contained in:
@@ -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,
|
||||
|
@@ -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 @@ class TestTermCount(common.TransactionCase):
|
||||
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")
|
||||
|
||||
+23
-19
@@ -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,17 +1101,18 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True,
|
||||
dic['lang'] = lang
|
||||
dic.update(pycompat.izip(fields, row))
|
||||
|
||||
# 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
|
||||
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(target_key)
|
||||
target.value = dic['value']
|
||||
target.targets.discard(target_key)
|
||||
|
||||
# This would skip terms that fail to specify a res_id
|
||||
res_id = dic['res_id']
|
||||
@@ -1137,15 +1140,16 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True,
|
||||
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))
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user