Files
boehmitools-main/plugins/tandoor-lint/backend.py
T
2026-07-24 21:37:03 +02:00

105 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
Plugin-Adapter für die Rezept-Inventur.
Nur lesend: Es gibt hier bewusst keinen Endpunkt, der etwas verändern könnte.
"""
from __future__ import annotations
import json
import sys
from typing import Any
from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse
from pydantic import BaseModel, Field
from core.jobs import job_router
TOOL = "lint.py"
SEVERITIES = {"err", "warn", "info"}
class ScanRequest(BaseModel):
only: list[str] = Field(default_factory=list)
skip: list[str] = Field(default_factory=list)
insecure: bool = False
def create_app(ctx):
tool = ctx.path("tool", TOOL)
report_file = ctx.data_dir / "bericht" / "bericht.json"
csv_file = ctx.data_dir / "bericht" / "befunde.csv"
def tool_env() -> dict:
"""
Umgebung für den Subprozess.
Wichtig: DATA_DIR ausdrücklich mitgeben. Ohne das schreibt das Skript
seinen Rückfallpfad neben die Anwendung — im Container ist der
schreibgeschützt, und die Oberfläche würde den Bericht nie finden.
"""
env = ctx.settings.tool_env()
env["DATA_DIR"] = str(ctx.data_dir)
return env
app = FastAPI(title=ctx.meta.name, docs_url="/api/docs", redoc_url=None)
@app.get("/", include_in_schema=False)
def index():
return FileResponse(ctx.path("static", "index.html"))
@app.get("/api/state")
def state() -> dict[str, Any]:
report = None
if report_file.is_file():
try:
report = json.loads(report_file.read_text(encoding="utf-8"))
except Exception:
report = None
running = [j.info() for j in ctx.jobs.running(ctx.id)]
return {
"report": report,
"tandoor": ctx.settings.status()["tandoor"],
"running": running[0] if running else None,
"has_csv": csv_file.is_file(),
}
@app.get("/api/export.csv")
def export():
if not csv_file.is_file():
raise HTTPException(404, "Noch kein Bericht vorhanden.")
return FileResponse(csv_file, media_type="text/csv", filename="befunde.csv")
@app.post("/api/run/scan")
async def run_scan(request: ScanRequest) -> dict[str, Any]:
if ctx.jobs.running(ctx.id):
raise HTTPException(409, "Die Inventur läuft bereits.")
if not ctx.settings.status()["tandoor"]:
raise HTTPException(400, "Tandoor-URL und Token fehlen siehe Einstellungen.")
argv = [sys.executable, str(tool)]
if request.insecure:
argv.append("--insecure")
argv.append("pruefen")
bad = [s for s in request.only if s not in SEVERITIES]
if bad:
raise HTTPException(400, f"Unbekannter Schweregrad: {bad}")
if request.only:
argv += ["--nur", ",".join(request.only)]
if request.skip:
# Die Schlüssel prüft das Skript selbst; hier nur grob absichern.
clean = [s for s in request.skip if s.replace("_", "").isalnum()]
if clean:
argv += ["--ohne", ",".join(clean)]
job = await ctx.jobs.start(
plugin=ctx.id, label="Inventur der Sammlung", argv=argv,
cwd=ctx.data_dir, env=tool_env(),
)
return job.info()
app.include_router(job_router(ctx.jobs, ctx.id))
return app