109 lines
4.1 KiB
Python
109 lines
4.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import re
|
|
from pathlib import Path
|
|
import logging
|
|
|
|
# Set up logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def upgrade(file_manager):
|
|
"""Convert <report> tags to <record model='ir.actions.report'> format in XML files."""
|
|
# Filter files to only XML files
|
|
files = [file for file in file_manager if file.path.suffix == ".xml"]
|
|
if not files:
|
|
logger.info("No XML files found to process")
|
|
return
|
|
|
|
# Regex pattern to match <report> tags (both self-closing and with content)
|
|
report_tag_re = re.compile(
|
|
r"""
|
|
<report\s+ # Opening <report tag with whitespace
|
|
([^>]*?) # Capture all attributes (non-greedy)
|
|
(?:/>|>.*?</report>) # Either self-closing or with closing tag
|
|
""",
|
|
re.VERBOSE | re.DOTALL,
|
|
)
|
|
|
|
def convert_report_to_record(match):
|
|
"""Convert report tag to record format."""
|
|
attributes_str = match.group(1).strip()
|
|
|
|
# Parse attributes using regex
|
|
attr_pattern = r'(\w+)=(["\'])(.*?)\2'
|
|
attributes = dict(re.findall(attr_pattern, attributes_str))
|
|
|
|
if not attributes:
|
|
return match.group(0) # Return original if no attributes found
|
|
|
|
# Extract id for the record
|
|
record_id = attributes.get('id', '')
|
|
if not record_id:
|
|
logger.warning("Found report tag without id attribute, skipping conversion")
|
|
return match.group(0)
|
|
|
|
# Map report attributes to record fields
|
|
field_mapping = {
|
|
'string': 'name',
|
|
'model': 'model',
|
|
'report_type': 'report_type',
|
|
'name': 'report_name',
|
|
'file': 'report_file',
|
|
'attachment_use': 'attachment_use',
|
|
'print_report_name': 'print_report_name',
|
|
'binding_model_id': 'binding_model_id',
|
|
'binding_type': 'binding_type',
|
|
'multi': 'multi',
|
|
'paperformat_id': 'paperformat_id',
|
|
'groups_id': 'groups_id',
|
|
}
|
|
|
|
# Build the record tag
|
|
record_lines = [f'<record id="{record_id}" model="ir.actions.report">']
|
|
|
|
# Add fields based on mapping
|
|
for report_attr, field_name in field_mapping.items():
|
|
if report_attr in attributes:
|
|
value = attributes[report_attr]
|
|
|
|
# Handle special cases
|
|
if report_attr == 'attachment_use':
|
|
# Convert string to boolean representation
|
|
if value.lower() in ('false', '0', 'no'):
|
|
value = 'False'
|
|
elif value.lower() in ('true', '1', 'yes'):
|
|
value = 'True'
|
|
|
|
# Handle reference fields (those ending with _id)
|
|
if field_name.endswith('_id') and not value.startswith('ref(') and not value.startswith('eval('):
|
|
if '.' in value: # Looks like an XML ID reference
|
|
record_lines.append(f' <field name="{field_name}" ref="{value}"/>')
|
|
else:
|
|
record_lines.append(f' <field name="{field_name}">{value}</field>')
|
|
else:
|
|
record_lines.append(f' <field name="{field_name}">{value}</field>')
|
|
|
|
record_lines.append(' </record>')
|
|
|
|
return '\n'.join(record_lines)
|
|
|
|
# Process each file
|
|
for fileno, file in enumerate(files, start=1):
|
|
content = file.content
|
|
original_content = content
|
|
|
|
# Replace matching <report> tags
|
|
content = report_tag_re.sub(convert_report_to_record, content)
|
|
|
|
# Only update if changes were made
|
|
if content != original_content:
|
|
file.content = content
|
|
logger.info(
|
|
f"Converted <report> tags to <record> format in {file.path}"
|
|
)
|
|
else:
|
|
logger.debug(f"No <report> tags found in {file.path}")
|
|
|
|
file_manager.print_progress(fileno, len(files)) |