bulid 63
This commit is contained in:
134
hockey_data/standings_parser.py
Normal file
134
hockey_data/standings_parser.py
Normal file
@@ -0,0 +1,134 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
from xml.etree import ElementTree as ET
|
||||
|
||||
from .match_parser import local_name, safe_int
|
||||
|
||||
|
||||
def _text(value: Any) -> str:
|
||||
return str(value or "").strip()
|
||||
|
||||
|
||||
def _team_payload(node: ET.Element, language: str) -> dict[str, Any]:
|
||||
attrs = {str(key): _text(value) for key, value in node.attrib.items()}
|
||||
name_ru = attrs.get("name", "")
|
||||
name_en = attrs.get("nameen", "")
|
||||
return {
|
||||
"id": attrs.get("id", ""),
|
||||
"entry_id": attrs.get("id", ""),
|
||||
"club_id": attrs.get("clubid", ""),
|
||||
"name": name_en if language == "en" and name_en else name_ru or name_en,
|
||||
"names": {"ru": name_ru, "en": name_en},
|
||||
"rank": safe_int(attrs.get("rank")),
|
||||
"games": safe_int(attrs.get("gp")),
|
||||
"wins": safe_int(attrs.get("w")),
|
||||
"overtime_wins": safe_int(attrs.get("otw")),
|
||||
"shootout_wins": safe_int(attrs.get("sow")),
|
||||
"shootout_losses": safe_int(attrs.get("sol")),
|
||||
"overtime_losses": safe_int(attrs.get("otl")),
|
||||
"losses": safe_int(attrs.get("l")),
|
||||
"points": safe_int(attrs.get("pts")),
|
||||
"points_pct": attrs.get("pts_pct", ""),
|
||||
"goals_for": safe_int(attrs.get("gf")),
|
||||
"goals_against": safe_int(attrs.get("ga")),
|
||||
"penalty_minutes": safe_int(attrs.get("pim")),
|
||||
"opponent_penalty_minutes": safe_int(attrs.get("pima")),
|
||||
"playoffs_in": attrs.get("playoffs_in", "").upper() == "Y",
|
||||
"playoffs_out": attrs.get("playoffs_out", "").upper() == "Y",
|
||||
"highlighted": False,
|
||||
"side": "",
|
||||
}
|
||||
|
||||
|
||||
def _group_payload(
|
||||
node: ET.Element,
|
||||
*,
|
||||
language: str,
|
||||
fallback_id: str,
|
||||
) -> dict[str, Any]:
|
||||
attrs = {str(key): _text(value) for key, value in node.attrib.items()}
|
||||
name_ru = attrs.get("name", "")
|
||||
name_en = attrs.get("name_en", "")
|
||||
teams = [
|
||||
_team_payload(child, language)
|
||||
for child in list(node)
|
||||
if local_name(child.tag).lower() == "team"
|
||||
]
|
||||
return {
|
||||
"id": attrs.get("item") or attrs.get("id") or fallback_id,
|
||||
"name": name_en if language == "en" and name_en else name_ru or name_en,
|
||||
"names": {"ru": name_ru, "en": name_en},
|
||||
"standings_type": attrs.get("standings_type", ""),
|
||||
"conference": attrs.get("conference", ""),
|
||||
"playoff_places": safe_int(attrs.get("in_playoff")),
|
||||
"teams": teams,
|
||||
}
|
||||
|
||||
|
||||
def parse_standings_xml(
|
||||
content: bytes | str,
|
||||
*,
|
||||
language: str = "ru",
|
||||
) -> dict[str, Any]:
|
||||
raw = content.encode("utf-8") if isinstance(content, str) else content
|
||||
root = ET.fromstring(raw)
|
||||
if local_name(root.tag).lower() != "standings":
|
||||
raise ValueError("Stat2TV вернул неизвестный формат турнирной таблицы")
|
||||
|
||||
league_groups: list[dict[str, Any]] = []
|
||||
conference_groups: list[dict[str, Any]] = []
|
||||
division_groups: list[dict[str, Any]] = []
|
||||
|
||||
for child in list(root):
|
||||
child_tag = local_name(child.tag).lower()
|
||||
if child_tag == "league":
|
||||
league_groups.append(
|
||||
_group_payload(child, language=language, fallback_id="league")
|
||||
)
|
||||
elif child_tag == "conferences":
|
||||
conference_groups.extend(
|
||||
_group_payload(
|
||||
group,
|
||||
language=language,
|
||||
fallback_id=f"conference-{index}",
|
||||
)
|
||||
for index, group in enumerate(list(child), start=1)
|
||||
if local_name(group.tag).lower() == "conference"
|
||||
)
|
||||
elif child_tag == "divisions":
|
||||
division_groups.extend(
|
||||
_group_payload(
|
||||
group,
|
||||
language=language,
|
||||
fallback_id=f"division-{index}",
|
||||
)
|
||||
for index, group in enumerate(list(child), start=1)
|
||||
if local_name(group.tag).lower() == "division"
|
||||
)
|
||||
|
||||
variants = [
|
||||
{
|
||||
"id": "league",
|
||||
"label": "League" if language == "en" else "Общая",
|
||||
"groups": league_groups,
|
||||
},
|
||||
{
|
||||
"id": "conferences",
|
||||
"label": "Conferences" if language == "en" else "Конференции",
|
||||
"groups": conference_groups,
|
||||
},
|
||||
{
|
||||
"id": "divisions",
|
||||
"label": "Divisions" if language == "en" else "Дивизионы",
|
||||
"groups": division_groups,
|
||||
},
|
||||
]
|
||||
variants = [variant for variant in variants if variant["groups"]]
|
||||
return {
|
||||
"tournament_id": _text(root.attrib.get("idtournament")),
|
||||
"generated_at": _text(root.attrib.get("genDate")),
|
||||
"order": _text(root.attrib.get("order")),
|
||||
"available": bool(variants),
|
||||
"variants": variants,
|
||||
}
|
||||
Reference in New Issue
Block a user