[FIX] core: fix check for text-only translated terms

`get_text_content` will transform contiguous space chars into single
spaces, plus translate special HTML elements
```
>>> " ".join(html.fromstring(f"a\n    b & c").text_content().split())
'a b & c'
```

In order the correctly verify if a term is text-only we need to use the
HTML parser. Note that to be resilient against bad XML, but valid HTML,
we cannot use the default XML parser.

Part-of: odoo/odoo#150152
This commit is contained in:
Alvaro Fuentes
2024-01-30 21:08:04 +00:00
parent d001a3a860
commit 86e3c3c72b
2 changed files with 10 additions and 2 deletions
+3 -2
View File
@@ -1853,14 +1853,15 @@ class _String(Field):
for term in new_terms:
text2terms[self.get_text_content(term)].append(term)
is_text = self.translate.is_text if hasattr(self.translate, 'is_text') else lambda term: True
for old_term in list(translation_dictionary.keys()):
if old_term not in new_terms:
old_term_text = self.get_text_content(old_term)
matches = get_close_matches(old_term_text, text2terms, 1, 0.9)
if matches:
closest_term = get_close_matches(old_term, text2terms[matches[0]], 1, 0)[0]
old_is_text = old_term == self.get_text_content(old_term)
closest_is_text = closest_term == self.get_text_content(closest_term)
old_is_text = is_text(old_term)
closest_is_text = is_text(closest_term)
if old_is_text or not closest_is_text:
translation_dictionary[closest_term] = translation_dictionary.pop(old_term)
# pylint: disable=not-callable
+7
View File
@@ -367,12 +367,19 @@ def get_text_content(term):
content = html.fromstring(term).text_content()
return " ".join(content.split())
def is_text(term):
""" Return whether the term has only text. """
return len(html.fromstring(f"<_>{term}</_>")) == 0
xml_translate.get_text_content = get_text_content
html_translate.get_text_content = get_text_content
xml_translate.term_converter = xml_term_converter
html_translate.term_converter = html_term_converter
xml_translate.is_text = is_text
html_translate.is_text = is_text
def translate_sql_constraint(cr, key, lang):
cr.execute("""
SELECT COALESCE(c.message->>%s, c.message->>'en_US') as message