"""Lädt Verarbeitungs-Profile aus mac-worker/profiles/*.yaml. Ein Profil definiert: - Prompts für Summary und Protocol - DOCX-Layout (Meta-Zeilen + Sektionen mit Typ) Sind keine Profile vorhanden, wirft get() FileNotFoundError beim ersten Zugriff. """ from __future__ import annotations import logging from dataclasses import dataclass, field from pathlib import Path import yaml log = logging.getLogger("mac-worker.profiles") PROFILES_DIR = Path(__file__).resolve().parent.parent.parent / "profiles" DEFAULT_PROFILE_NAME = "meeting" @dataclass class Profile: name: str display_name: str language: str = "de" summary_prompt: str = "" protocol_prompt: str = "" docx: dict = field(default_factory=dict) _cache: dict[str, Profile] = {} def _load() -> dict[str, Profile]: if _cache: return _cache if not PROFILES_DIR.exists(): log.warning("Profile-Verzeichnis %s existiert nicht", PROFILES_DIR) return _cache for f in sorted(PROFILES_DIR.glob("*.yaml")): try: data = yaml.safe_load(f.read_text(encoding="utf-8")) or {} p = Profile( name=data["name"], display_name=data.get("display_name", data["name"]), language=data.get("language", "de"), summary_prompt=data.get("summary_prompt", ""), protocol_prompt=data.get("protocol_prompt", ""), docx=data.get("docx") or {}, ) _cache[p.name] = p log.info("Profil geladen: %s (%s)", p.name, p.display_name) except Exception as e: # noqa: BLE001 log.error("Profil %s konnte nicht geladen werden: %s", f.name, e) return _cache def list_all() -> list[dict]: """Zur Auslieferung über /api/profiles.""" return [ {"name": p.name, "display_name": p.display_name, "language": p.language} for p in _load().values() ] def get(name: str | None) -> Profile: profiles = _load() if not profiles: raise FileNotFoundError( f"Keine Profile gefunden in {PROFILES_DIR} — bitte mind. eine YAML-Datei anlegen." ) if name and name in profiles: return profiles[name] if DEFAULT_PROFILE_NAME in profiles: return profiles[DEFAULT_PROFILE_NAME] return next(iter(profiles.values())) def reload() -> None: """Cache leeren (z. B. für Tests oder Hot-Reload via SIGHUP).""" _cache.clear()