| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- import csv
- import xml.etree.ElementTree as ET
- from collections import defaultdict
- from dataclasses import dataclass
- from decimal import Decimal, InvalidOperation
- from pathlib import Path
- from clients import calculate_customer, find_xml_files
- @dataclass(frozen=True)
- class SummaryResult:
- xml_count: int
- customer_count: int
- def extract_session(xml_path: Path) -> tuple[str, Decimal] | None:
- try:
- root = ET.parse(xml_path).getroot()
- except ET.ParseError:
- return None
- session = root.find("Session")
- if session is None:
- return None
- client_description = session.find("SessionDescription[@Name='ClientName']")
- client_name = "" if client_description is None else client_description.get("Description", "")
- duration = session.get("Duration", "").strip()
- if not client_name.strip() or not duration:
- return None
- try:
- return calculate_customer(client_name), Decimal(duration)
- except InvalidOperation:
- return None
- def write_summary(rows: list[dict[str, str]], output: Path) -> None:
- output.parent.mkdir(parents=True, exist_ok=True)
- with output.open("w", newline="", encoding="latin-1", errors="replace") as csv_file:
- writer = csv.DictWriter(csv_file, fieldnames=["Kunde", "AnzahlSitzungen", "Dauer"], delimiter=";")
- writer.writeheader()
- writer.writerows(rows)
- def format_duration(duration: Decimal) -> str:
- value = format(duration, "f")
- if "." in value:
- value = value.rstrip("0").rstrip(".")
- return value or "0"
- def run(directory: Path, output: Path) -> SummaryResult:
- if not directory.is_dir():
- raise ValueError(f"Das Verzeichnis existiert nicht: {directory}")
- totals: defaultdict[str, list[Decimal | int]] = defaultdict(lambda: [0, Decimal("0")])
- checked_count = 0
- for xml_file in find_xml_files(directory):
- checked_count += 1
- session = extract_session(xml_file)
- if session is None:
- continue
- customer, duration = session
- totals[customer][0] += 1
- totals[customer][1] += duration
- rows = [
- {
- "Kunde": customer,
- "AnzahlSitzungen": str(values[0]),
- "Dauer": format_duration(values[1]),
- }
- for customer, values in sorted(totals.items(), key=lambda item: item[0].casefold())
- ]
- write_summary(rows, output)
- return SummaryResult(xml_count=checked_count, customer_count=len(rows))
|