migrate to gitea

This commit is contained in:
jonasgaudian
2026-02-14 18:12:28 +01:00
commit 7c17f0f0cf
21 changed files with 2037 additions and 0 deletions

173
xml_processor.py Normal file
View File

@@ -0,0 +1,173 @@
"""
XML file processor for Android resources
"""
import os
from lxml import etree
from typing import Dict, Tuple, List, Union
from models import TranslationItem
from config import Config
class XMLProcessor:
"""XML file processor for Android resources"""
def __init__(self, config: Config):
self.config = config
self.parser = etree.XMLParser(remove_blank_text=False, strip_cdata=False)
def load_xml_file(self, file_path: str) -> etree.Element:
"""Load and parse XML file"""
try:
tree = etree.parse(file_path, self.parser)
return tree.getroot()
except Exception as e:
print(f"Error loading XML file {file_path}: {e}")
return None
def save_xml_file(self, root: etree.Element, file_path: str):
"""Save XML file with formatting"""
try:
# Ensure proper formatting for the root element
if root.text is None:
root.text = "\n "
if root.tail is None:
root.tail = "\n"
# Ensure all children have proper tails for formatting
for i, child in enumerate(root):
if child.tail is None or child.tail.strip() == "":
child.tail = "\n "
# Make sure the last child ends with proper indentation
if len(root) > 0:
last_child = root[-1]
if not last_child.tail.endswith("\n"):
last_child.tail = "\n"
# Create backup if enabled
if self.config.output_config.get('create_backups', True):
backup_path = file_path + self.config.output_config.get('backup_suffix', '.backup')
if os.path.exists(file_path):
backup_tree = etree.ElementTree(root)
backup_tree.write(backup_path,
encoding='utf-8',
xml_declaration=True,
pretty_print=True)
# Save the modified file with pretty printing
tree = etree.ElementTree(root)
tree.write(file_path, encoding='utf-8', xml_declaration=True, pretty_print=True)
except Exception as e:
print(f"Error saving XML file {file_path}: {e}")
def extract_strings(self, root: etree.Element) -> Dict[str, TranslationItem]:
"""Extract strings and string-arrays from XML root element"""
strings = {}
for element in root:
if element.tag == 'string':
name = element.get('name')
value = element.text or ''
# Skip strings marked as non-translatable
translatable = element.get('translatable', 'true')
if translatable.lower() == 'false':
continue
# Handle CDATA and special characters
if isinstance(value, str):
value = value.strip()
# Get comment if exists
comment = None
if element.tail and element.tail.strip():
comment = element.tail.strip()
strings[name] = TranslationItem(name=name, value=value, comment=comment, item_type='string')
elif element.tag == 'string-array':
name = element.get('name')
# Skip arrays marked as non-translatable
translatable = element.get('translatable', 'true')
if translatable.lower() == 'false':
continue
# Extract all items from the string-array
items = []
for item in element:
if item.tag == 'item':
item_value = item.text or ''
if isinstance(item_value, str):
item_value = item_value.strip()
items.append(item_value)
# Get comment if exists
comment = None
if element.tail and element.tail.strip():
comment = element.tail.strip()
# Store with combined value for display
combined_value = " | ".join(items) if items else ""
strings[name] = TranslationItem(
name=name,
value=combined_value,
comment=comment,
item_type='string-array',
items=items
)
elif element.tag == 'plurals':
# Handle plurals - for now, skip or handle separately
name = element.get('name')
strings[name] = TranslationItem(name=name, value=f"<{element.tag}>", comment="Complex type", item_type='plurals')
return strings
def add_missing_strings(self, target_root: etree.Element, missing_strings: List[Tuple]):
"""Add missing strings and string-arrays to target XML"""
for item_data in missing_strings:
if len(item_data) == 4:
# Extended format: (name, value, item_type, items)
name, value, item_type, items = item_data
else:
# Regular string: (name, value)
name, value = item_data[0], item_data[1]
item_type = 'string'
items = []
if item_type == 'string-array':
# Check if string-array already exists
existing = target_root.find(f".//string-array[@name='{name}']")
if existing is None:
# Create new string-array element
new_array = etree.SubElement(target_root, 'string-array', name=name)
# Add items to the array
for i, item_value in enumerate(items):
item_elem = etree.SubElement(new_array, 'item')
item_elem.text = item_value
# Add proper indentation between items
item_elem.tail = "\n "
# Add proper tail for the array element itself
new_array.tail = "\n "
else:
# Regular string
existing = target_root.find(f".//string[@name='{name}']")
if existing is None:
# Create new string element with proper indentation
new_string = etree.SubElement(target_root, 'string', name=name)
new_string.text = value
# Add proper indentation and newlines
new_string.tail = "\n "
# Ensure the last element has proper closing
if len(target_root) > 0:
last_child = target_root[-1]
if last_child.tail and not last_child.tail.endswith("\n"):
last_child.tail += "\n"