diff options
| author | Christophe Simonis <chs@odoo.com> | 2017-06-15 18:44:16 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2017-06-15 18:44:16 +0200 |
| commit | 1b50c829ef383705647d0c2df7c89e9051ec40fb (patch) | |
| tree | 036df47c7cf94424f04d7ff9dac371fb79e2b1e4 /odoo | |
| parent | 0c2e018d4c416d0f47a3b64f1c28ce067dbab291 (diff) | |
| parent | 9713dc2e1f515b1260eaf26ec6bbfd5443f37d65 (diff) | |
[MERGE] forward port branch saas-15 up to 9713dc2e1f5
Diffstat (limited to 'odoo')
| -rw-r--r-- | odoo/addons/base/ir/ir_translation.py | 12 | ||||
| -rw-r--r-- | odoo/addons/base/tests/test_translate.py | 69 | ||||
| -rw-r--r-- | odoo/http.py | 2 | ||||
| -rw-r--r-- | odoo/models.py | 10 | ||||
| -rw-r--r-- | odoo/sql_db.py | 13 |
5 files changed, 97 insertions, 9 deletions
diff --git a/odoo/addons/base/ir/ir_translation.py b/odoo/addons/base/ir/ir_translation.py index 997f4a611df..50ba56fcf23 100644 --- a/odoo/addons/base/ir/ir_translation.py +++ b/odoo/addons/base/ir/ir_translation.py @@ -544,16 +544,18 @@ class IrTranslation(models.Model): record = trans.env[mname].browse(trans.res_id) field = record._fields[fname] if callable(field.translate): - # check whether applying (trans.src -> trans.value) then - # (trans.value -> trans.src) gives the original value back + src = trans.src + val = trans.value.strip() + # check whether applying (src -> val) then (val -> src) + # gives the original value back value0 = field.translate(lambda term: None, record[fname]) - value1 = field.translate({trans.src: trans.value}.get, value0) + value1 = field.translate({src: val}.get, value0) # don't check the reverse if no translation happened if value0 == value1: continue - value2 = field.translate({trans.value: trans.src}.get, value1) + value2 = field.translate({val: src}.get, value1) if value2 != value0: - raise ValidationError(_("Translation is not valid:\n%s") % trans.value) + raise ValidationError(_("Translation is not valid:\n%s") % val) @api.model def create(self, vals): diff --git a/odoo/addons/base/tests/test_translate.py b/odoo/addons/base/tests/test_translate.py index de607798a82..328906c89c2 100644 --- a/odoo/addons/base/tests/test_translate.py +++ b/odoo/addons/base/tests/test_translate.py @@ -270,3 +270,72 @@ class TestTranslation(TransactionCase): categories = padawans_fr.search([('id', 'in', [self.customers.id, padawans.id])], order='name') self.assertEqual(categories.ids, [padawans.id, self.customers.id], "Search ordered by translated name should return Padawans (Apprentis) before Customers (Clients)") + + +class TestXMLTranslation(TransactionCase): + def setUp(self): + super(TestXMLTranslation, self).setUp() + self.env['ir.translation'].load_module_terms(['base'], ['fr_FR']) + + def test_copy(self): + """ Create a simple view, fill in translations, and copy it. """ + env_en = self.env(context={}) + env_fr = self.env(context={'lang': 'fr_FR'}) + + archf = '<form string="%s"><div>%s</div><div>%s</div></form>' + terms_en = ('Knife', 'Fork', 'Spoon') + terms_fr = ('Couteau', 'Fourchette', 'Cuiller') + view0 = self.env['ir.ui.view'].create({ + 'name': 'test', + 'model': 'res.partner', + 'arch': archf % terms_en, + }) + for src, value in zip(terms_en, terms_fr): + self.env['ir.translation'].create({ + 'type': 'model', + 'name': 'ir.ui.view,arch_db', + 'lang': 'fr_FR', + 'res_id': view0.id, + 'src': src, + 'value': value, + }) + + # check translated field + self.assertEqual(view0.with_env(env_en).arch_db, archf % terms_en) + self.assertEqual(view0.with_env(env_fr).arch_db, archf % terms_fr) + + # copy without lang + view1 = view0.with_env(env_en).copy({}) + self.assertEqual(view1.with_env(env_en).arch_db, archf % terms_en) + self.assertEqual(view1.with_env(env_fr).arch_db, archf % terms_fr) + + # copy with lang='fr_FR' + view2 = view0.with_env(env_fr).copy({}) + self.assertEqual(view2.with_env(env_en).arch_db, archf % terms_en) + self.assertEqual(view2.with_env(env_fr).arch_db, archf % terms_fr) + + # copy with lang='fr_FR' and translate=html_translate + self.patch(type(self.env['ir.ui.view']).arch_db, 'translate', html_translate) + view3 = view0.with_env(env_fr).copy({}) + self.assertEqual(view3.with_env(env_en).arch_db, archf % terms_en) + self.assertEqual(view3.with_env(env_fr).arch_db, archf % terms_fr) + + def test_spaces(self): + """ Create translations where value has surrounding spaces. """ + archf = '<form string="%s"><div>%s</div><div>%s</div></form>' + terms_en = ('Knife', 'Fork', 'Spoon') + terms_fr = (' Couteau', 'Fourchette ', ' Cuiller ') + view0 = self.env['ir.ui.view'].create({ + 'name': 'test', + 'model': 'res.partner', + 'arch': archf % terms_en, + }) + for src, value in zip(terms_en, terms_fr): + self.env['ir.translation'].create({ + 'type': 'model', + 'name': 'ir.ui.view,arch_db', + 'lang': 'fr_FR', + 'res_id': view0.id, + 'src': src, + 'value': value, + }) diff --git a/odoo/http.py b/odoo/http.py index 0b3ad105e39..c32d0178b8a 100644 --- a/odoo/http.py +++ b/odoo/http.py @@ -167,6 +167,8 @@ def redirect_with_hash(url, code=303): # See extensive test page at http://greenbytes.de/tech/tc/httpredirects/ if request.httprequest.user_agent.browser in ('firefox',): return werkzeug.utils.redirect(url, code) + if urlparse.urlparse(url, scheme='http').scheme not in ('http', 'https'): + url = 'http://' + url url = url.replace("'", "%27").replace("<", "%3C") return "<html><head><script>window.location = '%s' + location.hash;</script></head></html>" % url diff --git a/odoo/models.py b/odoo/models.py index 518e0f7b859..b0b8361691a 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3812,16 +3812,18 @@ class BaseModel(object): # for translatable fields we copy their translations trans_name, source_id, target_id = get_trans(field, old, new) domain = [('name', '=', trans_name), ('res_id', '=', source_id)] + new_val = new_wo_lang[name] + if old.env.lang: + # the new value *without lang* must be the old value without lang + new_wo_lang[name] = old_wo_lang[name] for vals in Translation.search_read(domain): del vals['id'] del vals['source'] # remove source to avoid triggering _set_src del vals['module'] # duplicated vals is not linked to any module vals['res_id'] = target_id if vals['lang'] == old.env.lang and field.translate is True: - # 'source' to force the call to _set_src - # 'value' needed if value is changed in copy(), want to see the new_value - vals['source'] = old_wo_lang[name] - vals['value'] = new_wo_lang[name] + # the value should be the new value (given by copy()) + vals['value'] = new_val Translation.create(vals) @api.multi diff --git a/odoo/sql_db.py b/odoo/sql_db.py index 9a438d387de..b4c69824ab2 100644 --- a/odoo/sql_db.py +++ b/odoo/sql_db.py @@ -54,6 +54,19 @@ psycopg2.extensions.register_type(psycopg2.extensions.new_type((700, 701, 1700,) from . import tools from .tools.func import frame_codeinfo + +from tools import parse_version as pv +if pv(psycopg2.__version__) < pv('2.7'): + from psycopg2._psycopg import QuotedString + def adapt_string(adapted): + """Python implementation of psycopg/psycopg2#459 from v2.7""" + if '\x00' in adapted: + raise ValueError("A string literal cannot contain NUL (0x00) characters.") + return QuotedString(adapted) + + psycopg2.extensions.register_adapter(str, adapt_string) + psycopg2.extensions.register_adapter(unicode, adapt_string) + from datetime import timedelta import threading from inspect import currentframe |
