Files
planer2/backend/projekte.py
2026-07-29 15:19:41 +02:00

79 lines
2.2 KiB
Python

"""Projekte = Ordner unter daten/. Kein Registry-File, das Listing ist die Liste."""
import shutil
import config
# Die Arbeitskopie einer laufenden Planung. Liegt im Projektordner und beginnt mit
# einem Punkt — damit taucht sie im Listing nicht als eigenes Projekt auf.
PLANUNG = ".planung"
def _pruefe_name(name: str):
if not name or not name.strip():
raise ValueError("Projektname darf nicht leer sein")
if "/" in name or "\\" in name or name.startswith("."):
raise ValueError("Ungültiger Projektname")
def _ordner(name: str):
_pruefe_name(name)
return config.DATEN_DIR / name
def liste() -> list[dict]:
if not config.DATEN_DIR.exists():
return []
ordner = sorted(
(p for p in config.DATEN_DIR.iterdir() if p.is_dir()),
key=lambda p: p.name.lower(),
)
return [{"name": p.name} for p in ordner]
def anlegen(name: str):
ziel = _ordner(name)
if ziel.exists():
raise ValueError(f"Projekt „{name}“ existiert bereits")
ziel.mkdir(parents=True)
def umbenennen(alt: str, neu: str):
quelle = _ordner(alt)
ziel = _ordner(neu)
if not quelle.is_dir():
raise FileNotFoundError(f"Projekt „{alt}“ nicht gefunden")
if ziel.exists():
raise ValueError(f"Projekt „{neu}“ existiert bereits")
quelle.rename(ziel)
def loeschen(name: str):
ordner = _ordner(name)
if not ordner.is_dir():
raise FileNotFoundError(f"Projekt „{name}“ nicht gefunden")
shutil.rmtree(ordner)
def stand(name: str):
"""Der Projektordner selbst — was das Projekt heute kann.
Nur wer den umgesetzten Stand meint, ruft das. Alles andere nimmt `wurzel()`.
"""
ordner = _ordner(name)
if not ordner.is_dir():
raise FileNotFoundError(f"Projekt „{name}“ nicht gefunden")
return ordner
def wurzel(name: str):
"""Der Ordner, in dem gerade gearbeitet wird.
Ohne offene Planung ist das der Projektordner. Läuft eine Planung, ist es ihre
Arbeitskopie — und zwar für alles: Karten, Gespräch, Gedächtnis. Ein
Schalter statt einer Fallunterscheidung in jeder Schreibfunktion.
"""
ordner = stand(name)
kopie = ordner / PLANUNG
return kopie if kopie.is_dir() else ordner