diff --git a/upgrade_analysis/models/upgrade_analysis.py b/upgrade_analysis/models/upgrade_analysis.py index 2c67ac051..fcdd48774 100644 --- a/upgrade_analysis/models/upgrade_analysis.py +++ b/upgrade_analysis/models/upgrade_analysis.py @@ -408,31 +408,30 @@ class UpgradeAnalysis(models.Model): target_dict[xml_id] = record @classmethod - def _parse_paths(self, xml_paths, module_name): + def _parse_files(self, xml_files, module_name): records_update = {} records_noupdate = {} parser = etree.XMLParser( remove_blank_text=True, strip_cdata=False, ) - for xml_path in xml_paths: + for xml_file in xml_files: try: # This is for a final correct pretty print # Ref.: https://stackoverflow.com/a/7904066 # Also don't strip CDATA tags as needed for HTML content - tree = etree.parse(xml_path, parser=parser) + root_node = etree.fromstring(xml_file.encode("utf-8"), parser=parser) except etree.XMLSyntaxError: continue # Support xml files with root Element either odoo or openerp # Condition: each xml file should have only one root element # {, or —rarely— }; - root_node = tree.getroot() root_node_noupdate = nodeattr2bool(root_node, "noupdate", False) if root_node.tag not in ("openerp", "odoo", "data"): raise ValidationError( _( "Unexpected root Element: %s in file: %s" - % (tree.getroot(), xml_path) + % (root_node.getroot(), xml_file) ) ) for node in root_node: @@ -463,26 +462,26 @@ class UpgradeAnalysis(models.Model): local_modules = local_record_obj.list_modules() all_remote_modules = remote_record_obj.list_modules() for local_module in local_modules: - remote_paths = [] + remote_files = [] remote_modules = [] remote_update, remote_noupdate = {}, {} for remote_module in all_remote_modules: if local_module == renamed_modules.get( remote_module, merged_modules.get(remote_module, remote_module) ): - remote_paths.extend( + remote_files.extend( remote_record_obj.get_xml_records(remote_module) ) remote_modules.append(remote_module) - add_remote_update, add_remote_noupdate = self._parse_paths( - remote_paths, remote_module + add_remote_update, add_remote_noupdate = self._parse_files( + remote_files, remote_module ) remote_update.update(add_remote_update) remote_noupdate.update(add_remote_noupdate) if not remote_modules: continue - local_paths = local_record_obj.get_xml_records(local_module) - local_update, local_noupdate = self._parse_paths(local_paths, local_module) + local_files = local_record_obj.get_xml_records(local_module) + local_update, local_noupdate = self._parse_files(local_files, local_module) diff = self._get_xml_diff( remote_update, remote_noupdate, local_update, local_noupdate ) diff --git a/upgrade_analysis/models/upgrade_record.py b/upgrade_analysis/models/upgrade_record.py index fdcd0e707..f62c7ca3e 100644 --- a/upgrade_analysis/models/upgrade_record.py +++ b/upgrade_analysis/models/upgrade_record.py @@ -5,6 +5,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import ast +import logging import os from odoo import api, fields, models @@ -12,6 +13,8 @@ from odoo.exceptions import ValidationError from odoo.modules.module import MANIFEST_NAMES, get_module_path from odoo.tools.translate import _ +_logger = logging.getLogger(__name__) + class UpgradeRecord(models.Model): _name = "upgrade.record" @@ -159,7 +162,7 @@ class UpgradeRecord(models.Model): # The order of the keys are important. # Load files in the same order as in # module/loading.py:load_module_graph - paths = [] + files = [] for key in ["init_xml", "update_xml", "data"]: if not manifest.get(key): continue @@ -167,5 +170,13 @@ class UpgradeRecord(models.Model): if not xml_file.lower().endswith(".xml"): continue parts = xml_file.split("/") - paths.append(os.path.join(addon_dir, *parts)) - return paths + try: + with open(os.path.join(addon_dir, *parts), "r") as xml_handle: + files.append(xml_handle.read()) + except UnicodeDecodeError: + _logger.warning( + "Encoding error: Unable to read %s", + os.path.join(addon_dir, *parts), + ) + continue + return files