| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import csv
- import xml.etree.ElementTree as ET
- from dataclasses import dataclass
- from datetime import datetime
- from pathlib import Path
- from clients import calculate_customer
- @dataclass(frozen=True)
- class SessionDetailsResult:
- xml_count: int
- activity_count: int
- def find_xml_files(directory: Path) -> list[Path]:
- return sorted(
- path
- for path in directory.rglob("*")
- if path.is_file() and path.suffix.lower() == ".xml" and not path.name.lower().startswith("sessions")
- )
- def extract_session_details(xml_path: Path) -> list[dict[str, str]]:
- try:
- root = ET.parse(xml_path).getroot()
- except ET.ParseError:
- return []
- session = root.find("Session")
- if session is None:
- return []
- client_description = session.find("SessionDescription[@Name='ClientName']")
- client_name = "" if client_description is None else client_description.get("Description", "")
- if not client_name.strip():
- return []
- customer = calculate_customer(client_name)
- activities = []
- for activity in session.findall("UserActivity"):
- date_time = activity.get("DateTime", "").strip()
- activity_type = activity.get("Type", "").strip()
- try:
- parsed_date_time = datetime.fromisoformat(date_time.replace("Z", "+00:00"))
- except ValueError:
- continue
- if date_time and activity_type:
- activities.append((parsed_date_time, date_time, activity_type))
- day_counts = {}
- for parsed_date_time, _, _ in activities:
- day_counts[parsed_date_time.date()] = day_counts.get(parsed_date_time.date(), 0) + 1
- rows = []
- for index, (parsed_date_time, date_time, activity_type) in enumerate(activities):
- next_date_time = activities[index + 1][0] if index + 1 < len(activities) else parsed_date_time
- duration = min(max(int((next_date_time - parsed_date_time).total_seconds()), 0), 900)
- if (
- len(day_counts) > 1
- and day_counts[parsed_date_time.date()] == 1
- and activity_type == "SupportAndPresentationMode"
- ):
- duration = 0
- rows.append(
- {
- "DateTime": date_time,
- "Kunde": customer,
- "UserActivityType": activity_type,
- "Duration": str(duration),
- }
- )
- return rows
- def write_session_details(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=["DateTime", "Kunde", "UserActivityType", "Duration"],
- delimiter=";",
- )
- writer.writeheader()
- writer.writerows(rows)
- def run(directory: Path, output: Path) -> SessionDetailsResult:
- if not directory.is_dir():
- raise ValueError(f"Das Verzeichnis existiert nicht: {directory}")
- xml_files = find_xml_files(directory)
- rows = [row for xml_file in xml_files for row in extract_session_details(xml_file)]
- rows.sort(key=lambda row: row["DateTime"])
- write_session_details(rows, output)
- return SessionDetailsResult(xml_count=len(xml_files), activity_count=len(rows))
|