"""Der Stand des letzten Laufs — die Basis des Drei-Wege-Vergleichs.""" from __future__ import annotations import json from datetime import datetime from pathlib import Path from .abgleich import Basiseintrag DATEINAME = ".plane-sync.json" VERSION = 1 class Zustand: def __init__(self, pfad: Path, roh: dict, warnung: str | None = None): self.pfad = pfad self.warnung = warnung self.plane_projekt: str | None = roh.get("plane_project") self.eintraege: dict[str, Basiseintrag] = { marker: Basiseintrag( marker=marker, work_item_id=werte["work_item_id"], titel=werte["titel"], erledigt=bool(werte["erledigt"]), ) for marker, werte in (roh.get("eintraege") or {}).items() } self._letzter_lauf: str | None = roh.get("letzter_lauf") def setze(self, eintrag: Basiseintrag) -> None: """Trägt einen Eintrag ein und speichert sofort — das macht den Lauf wiederaufsetzbar.""" self.eintraege[eintrag.marker] = eintrag self.speichere() def entferne_marker(self, marker: str) -> None: self.eintraege.pop(marker, None) self.speichere() def setze_lauf_zeit(self) -> None: self._letzter_lauf = datetime.now().astimezone().isoformat(timespec="seconds") self.speichere() def speichere(self) -> None: inhalt = { "version": VERSION, "plane_project": self.plane_projekt, "letzter_lauf": self._letzter_lauf, "eintraege": { marker: { "work_item_id": e.work_item_id, "titel": e.titel, "erledigt": e.erledigt, } for marker, e in sorted(self.eintraege.items()) }, } self.pfad.write_text( json.dumps(inhalt, ensure_ascii=False, indent=2) + "\n", encoding="utf-8" ) def lies(pfad: Path) -> Zustand: pfad = Path(pfad) if not pfad.exists(): return Zustand(pfad, {}) try: return Zustand(pfad, json.loads(pfad.read_text(encoding="utf-8"))) except (json.JSONDecodeError, KeyError, TypeError) as fehler: return Zustand( pfad, {}, warnung=( f"{pfad} ist unlesbar ({fehler}). Der Lauf behandelt sie als leer; " "dadurch erscheinen bereits abgeglichene Aufgaben erneut." ), )