From 86e3c3c72bed97e9ab5824b08ebf8b82c1a9ce39 Mon Sep 17 00:00:00 2001 From: Alvaro Fuentes Date: Fri, 26 Jan 2024 12:10:01 +0100 Subject: [PATCH] [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 --- odoo/fields.py | 5 +++-- odoo/tools/translate.py | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/odoo/fields.py b/odoo/fields.py index 04083a0cfe4..470d74f088e 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -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 diff --git a/odoo/tools/translate.py b/odoo/tools/translate.py index 9011f96d5d0..311dfe3b996 100644 --- a/odoo/tools/translate.py +++ b/odoo/tools/translate.py @@ -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