Erster Stand des öffentlichen Ausschnitts aus dem Vault. Die .gitignore arbeitet als Positivliste: ausgeschlossen ist alles, eingeschlossen nur, was ausdrücklich wieder aufgenommen wird. Notizen, Projekte, Finanzen, das Sitzungsgedächtnis und settings.local.json bleiben damit außen vor. Der Kundenname in AI/Regelwerk/seo.md ist durch eine neutrale Bezeichnung ersetzt; die Regeln selbst sind unverändert. Co-Authored-By: Claude Opus 5 <[email protected]>
42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
"""Findet im Quellordner die Notizen, die zum Upload freigegeben sind."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
from bookstack.notiz import Notiz, lade_notiz
|
|
|
|
MAX_TITEL = 255
|
|
FREIGABE = re.compile(r"(?<![\w#-])#review-done(?![\w-])")
|
|
OFFEN = re.compile(r"(?<![\w#-])#review(?![\w-])")
|
|
UEBERSCHRIFT = re.compile(r"^#\s+(.+)$", re.MULTILINE)
|
|
|
|
|
|
def ist_freigegeben(notiz: Notiz) -> bool:
|
|
"""Freigegeben heißt: #review-done vorhanden und kein offenes #review mehr."""
|
|
return bool(FREIGABE.search(notiz.roh)) and not OFFEN.search(notiz.roh)
|
|
|
|
|
|
def finde_kandidaten(quelle: Path) -> list[Notiz]:
|
|
if not quelle.is_dir():
|
|
return []
|
|
gefunden: list[Notiz] = []
|
|
for pfad in sorted(quelle.rglob("*.md")):
|
|
if pfad.name.startswith((".", "_")):
|
|
continue
|
|
notiz = lade_notiz(pfad)
|
|
if ist_freigegeben(notiz):
|
|
gefunden.append(notiz)
|
|
return gefunden
|
|
|
|
|
|
def titel_von(notiz: Notiz) -> str:
|
|
"""Erste H1, sonst Frontmatter-title, sonst Dateiname."""
|
|
treffer = UEBERSCHRIFT.search(notiz.rumpf)
|
|
if treffer:
|
|
titel = treffer.group(1).strip()
|
|
else:
|
|
titel = notiz.frontmatter.get("title", "").strip() or notiz.pfad.stem
|
|
return titel[:MAX_TITEL]
|