bulid 63
This commit is contained in:
94
hockey_data/navigation_labels.py
Normal file
94
hockey_data/navigation_labels.py
Normal file
@@ -0,0 +1,94 @@
|
||||
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,
|
||||
}
|
||||
Reference in New Issue
Block a user