Initial commit: breakpilot-lehrer - Lehrer KI Platform

Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website,
Klausur-Service, School-Service, Voice-Service, Geo-Service,
BreakPilot Drive, Agent-Core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Boenisch
2026-02-11 23:47:26 +01:00
commit 5a31f52310
1224 changed files with 425430 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
"""
AI Processing - Core Utilities.
Basis-Funktionen für API-Zugriff, Encoding und Verzeichnisse.
"""
from pathlib import Path
import shutil
import os
import base64
import logging
logger = logging.getLogger(__name__)
# Verzeichnisse
BASE_DIR = Path.home() / "Arbeitsblaetter"
EINGANG_DIR = BASE_DIR / "Eingang"
BEREINIGT_DIR = BASE_DIR / "Bereinigt"
# Vision API Konfiguration
VISION_API = os.getenv("VISION_API", "claude").lower()
def get_openai_api_key() -> str:
"""Holt den OpenAI API Key aus der Umgebungsvariable."""
api_key = os.getenv("OPENAI_API_KEY")
if not api_key:
raise RuntimeError("OPENAI_API_KEY ist nicht gesetzt. Bitte API-Schlüssel als Umgebungsvariable setzen.")
return api_key
def get_anthropic_api_key() -> str:
"""Holt den Anthropic API Key aus der Umgebungsvariable."""
api_key = os.getenv("ANTHROPIC_API_KEY")
if not api_key:
raise RuntimeError("ANTHROPIC_API_KEY ist nicht gesetzt.")
return api_key
def encode_image_to_data_url(input_path: Path) -> str:
"""Kodiert ein Bild als Data-URL für Vision APIs."""
image_bytes = input_path.read_bytes()
image_b64 = base64.b64encode(image_bytes).decode("utf-8")
return f"data:image/jpeg;base64,{image_b64}"
def encode_image_to_base64(input_path: Path) -> str:
"""Kodiert ein Bild als Base64-String."""
image_bytes = input_path.read_bytes()
return base64.b64encode(image_bytes).decode("utf-8")
def ensure_directories():
"""Stellt sicher, dass alle benötigten Verzeichnisse existieren."""
EINGANG_DIR.mkdir(parents=True, exist_ok=True)
BEREINIGT_DIR.mkdir(parents=True, exist_ok=True)
def dummy_process_scan(input_path: Path) -> Path:
"""Einfache Kopie in den Ordner Bereinigt bleibt als Fallback erhalten."""
if not input_path.exists():
raise FileNotFoundError(f"Eingabedatei nicht gefunden: {input_path}")
new_name = input_path.stem + "_bereinigt" + input_path.suffix
target = BEREINIGT_DIR / new_name
shutil.copy2(input_path, target)
return target
def get_vision_api() -> str:
"""Gibt die konfigurierte Vision API zurück."""
return VISION_API