Files
hockey_new/hockey_data/navigation_labels.py
2026-08-19 15:08:39 +03:00

95 lines
3.7 KiB
Python

from __future__ import annotations
from typing import Any
from xml.etree import ElementTree as ET
XML_LANG = "{http://www.w3.org/XML/1998/namespace}lang"
def _text(value: Any) -> str:
return str(value or "").strip()
def _labels(node: ET.Element) -> dict[str, dict[str, str]]:
result = {
"ru": {"label": "", "description": "", "short": ""},
"en": {"label": "", "description": "", "short": ""},
}
for label in node.findall("./label"):
language = _text(label.attrib.get(XML_LANG) or label.attrib.get("lang") or "ru").lower()
if language not in result:
continue
result[language] = {
"label": _text(label.text),
"description": _text(label.attrib.get("description")),
"short": _text(label.attrib.get("short")),
}
return result
def _merge_entry(target: dict[str, Any], source: dict[str, Any]) -> None:
for language in ("ru", "en"):
current = target.setdefault(language, {"label": "", "description": "", "short": ""})
incoming = source.get(language, {})
for key in ("label", "description", "short"):
if not current.get(key) and incoming.get(key):
current[key] = incoming[key]
def parse_navigation_labels_xml(content: bytes | str) -> dict[str, Any]:
raw = content.encode("utf-8") if isinstance(content, str) else content
root = ET.fromstring(raw)
columns: dict[str, dict[str, Any]] = {}
by_section: dict[str, dict[str, dict[str, Any]]] = {}
sections: dict[str, dict[str, Any]] = {}
for item in root.findall(".//list//item[@section]"):
section = _text(item.attrib.get("section"))
if section:
entry = _labels(item)
target = sections.setdefault(section, {})
_merge_entry(target, entry)
for columns_node in root.findall(".//columns"):
section_names = [part for part in _text(columns_node.attrib.get("sections")).split() if part]
for index, cell in enumerate(columns_node.findall("./cell")):
ref = _text(cell.attrib.get("ref"))
labels = _labels(cell)
if not ref:
ru = labels.get("ru", {}).get("label", "").casefold()
en = labels.get("en", {}).get("label", "").casefold()
if ru in {"игрок", "хоккеист"} or en == "player":
ref = "player"
elif ru in {"клуб", "команда"} or en == "team":
ref = "team"
elif ru == "" or en in {"", "no.", "number"}:
ref = "number"
elif index == 0:
ref = "rank"
else:
continue
entry = {
**labels,
"datatype": _text(cell.attrib.get("datatype")),
"sortable": _text(cell.attrib.get("sortable")),
"default": _text(cell.attrib.get("default")),
}
global_entry = columns.setdefault(ref, {})
_merge_entry(global_entry, entry)
for key in ("datatype", "sortable", "default"):
if not global_entry.get(key) and entry.get(key):
global_entry[key] = entry[key]
for section in section_names:
section_entry = by_section.setdefault(section, {}).setdefault(ref, {})
_merge_entry(section_entry, entry)
for key in ("datatype", "sortable", "default"):
if not section_entry.get(key) and entry.get(key):
section_entry[key] = entry[key]
return {
"available": bool(columns or sections),
"columns": columns,
"columns_by_section": by_section,
"sections": sections,
}