Files
planer/backend/projekte.py
2026-07-23 11:54:31 +02:00

75 lines
2.8 KiB
Python

"""Projektliste: konfigurierte Pfade aus projekte.txt (eine Zeile = absoluter Pfad,
#-Kommentare). Von Hand editierbar; hinzufuegen/entfernen bedienen die UI."""
from pathlib import Path
import config
def lade() -> list[dict]:
"""→ [{name, pfad, fehler?}]. Toter Pfad oder Basename-Kollision wird als Eintrag
mit `fehler` gemeldet, nie still verschluckt."""
if not config.PROJEKTE_DATEI.is_file():
return []
out: list[dict] = []
gesehen: dict[str, str] = {}
for zeile in config.PROJEKTE_DATEI.read_text(encoding="utf-8").splitlines():
zeile = zeile.strip()
if not zeile or zeile.startswith("#"):
continue
pfad = Path(zeile).expanduser()
name = pfad.name
eintrag = {"name": name, "pfad": str(pfad)}
if not pfad.is_dir():
eintrag["fehler"] = "Pfad existiert nicht"
elif name in gesehen:
eintrag["fehler"] = f"Namenskollision mit {gesehen[name]}"
else:
gesehen[name] = str(pfad)
out.append(eintrag)
return out
def finde(name: str) -> Path | None:
for p in lade():
if p["name"] == name and "fehler" not in p:
return Path(p["pfad"])
return None
def hinzufuegen(pfad: str) -> None:
"""Hängt einen Pfad an projekte.txt an. Wirft ValueError bei ungültigem
Verzeichnis, Duplikat oder Basename-Kollision."""
p = Path(pfad).expanduser()
if not p.is_absolute():
raise ValueError("Pfad muss absolut sein")
if not p.is_dir():
raise ValueError(f"{p} ist kein Verzeichnis")
for e in lade():
if e["pfad"] == str(p):
raise ValueError(f"{p} ist schon eingetragen")
if e["name"] == p.name:
raise ValueError(f"Namenskollision mit {e['pfad']}")
text = ""
if config.PROJEKTE_DATEI.is_file():
text = config.PROJEKTE_DATEI.read_text(encoding="utf-8")
if text and not text.endswith("\n"):
text += "\n"
config.PROJEKTE_DATEI.write_text(text + str(p) + "\n", encoding="utf-8")
def entfernen(name: str) -> None:
"""Streicht den Eintrag aus projekte.txt — nur die Zeile; .planer/ im Repo
bleibt unberührt. Wirft ValueError, wenn der Name nicht eingetragen ist."""
if not config.PROJEKTE_DATEI.is_file():
raise ValueError(f"'{name}' nicht in projekte.txt")
rest, getroffen = [], False
for zeile in config.PROJEKTE_DATEI.read_text(encoding="utf-8").splitlines():
s = zeile.strip()
if s and not s.startswith("#") and Path(s).expanduser().name == name:
getroffen = True
continue
rest.append(zeile)
if not getroffen:
raise ValueError(f"'{name}' nicht in projekte.txt")
config.PROJEKTE_DATEI.write_text("\n".join(rest) + ("\n" if rest else ""), encoding="utf-8")