This commit is contained in:
team3
2026-06-30 00:14:18 +02:00
parent 3e3559aa8f
commit c794fcaccf
152 changed files with 9485 additions and 9583 deletions

View File

@@ -2,7 +2,7 @@ from pathlib import Path
from config import STORAGE_DIR, PROJECTS_DIR, PROJECT_ROOT
THEMEN_DIR = STORAGE_DIR / "themen"
TOPICS_DIR = STORAGE_DIR / "topics"
def _safe(name: str) -> str:
@@ -10,42 +10,42 @@ def _safe(name: str) -> str:
def topic_dir(topic: str) -> Path:
return THEMEN_DIR / _safe(topic)
return TOPICS_DIR / _safe(topic)
def arbeit_dir(topic: str) -> Path:
return topic_dir(topic) / "arbeit"
def bausteine_path(topic: str) -> Path:
return topic_dir(topic) / "bausteine.md"
def blocks_path(topic: str) -> Path:
return topic_dir(topic) / "blocks.md"
def subbausteine_path(topic: str) -> Path:
"""Sidecar: pro Baustein die Subbausteine mit Stufe (von allen Guides geteilt)."""
return topic_dir(topic) / "subbausteine.json"
def subblocks_path(topic: str) -> Path:
"""Sidecar: the subblocks with level per block (shared by all guides)."""
return topic_dir(topic) / "subblocks.json"
def frage_muster_path(topic: str) -> Path:
"""Sidecar: pro Baustein vordefinierte Frage-Muster (Subbaustein × Typ → Beispielfrage)."""
return topic_dir(topic) / "frage_muster.json"
def question_pattern_path(topic: str) -> Path:
"""Sidecar: predefined question patterns per block (subblock × typeexample question)."""
return topic_dir(topic) / "question_pattern.json"
def quelle_path(topic: str) -> Path:
"""Persistierte Quellen-Wahl pro Thema: {type, ort, spec}."""
return topic_dir(topic) / "quelle.json"
def source_path(topic: str) -> Path:
"""Persisted source choice per topic: {type, location, spec}."""
return topic_dir(topic) / "source.json"
def quelle_crawl_dir(topic: str) -> Path:
"""Zielordner für gecrawlte Link-Quellen (Seiten + PDF-.txt)."""
return topic_dir(topic) / "quelle"
def source_crawl_dir(topic: str) -> Path:
"""Target folder for crawled link sources (pages + PDF .txt)."""
return topic_dir(topic) / "source"
def safe_ordner(ort: str) -> Path | None:
"""Ordnerpfad relativ zum Repo-Root, gesandboxt. None bei leer/Ausbruch (../, absolut außerhalb)."""
if not ort or not ort.strip():
def safe_folder(location: str) -> Path | None:
"""Folder path relative to the repo root, sandboxed. None if empty/escaping (../, absolute outside)."""
if not location or not location.strip():
return None
p = (PROJECT_ROOT / ort.strip()).resolve()
p = (PROJECT_ROOT / location.strip()).resolve()
try:
p.relative_to(PROJECT_ROOT)
except ValueError:
@@ -57,11 +57,11 @@ def guide_content_path(topic: str, format_name: str) -> Path:
return topic_dir(topic) / "guides" / f"{format_name}.json"
def bausteine_topics() -> list[str]:
"""Themen, für die ein Themen-Ordner existiert."""
if not THEMEN_DIR.is_dir():
def blocks_topics() -> list[str]:
"""Topics for which a topic folder exists."""
if not TOPICS_DIR.is_dir():
return []
return [d.name for d in THEMEN_DIR.iterdir() if d.is_dir()]
return [d.name for d in TOPICS_DIR.iterdir() if d.is_dir()]
def project_dir(name: str) -> Path: