From 387779a4ef1ee6377452d8029e42361b90c65497 Mon Sep 17 00:00:00 2001 From: Oliver Braasch Date: Wed, 23 Sep 2026 22:17:07 +0200 Subject: [PATCH] Dateien nach "/" hochladen --- app.py | 49 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index 9f22017..9e20db4 100644 --- a/app.py +++ b/app.py @@ -25,6 +25,7 @@ import tempfile import threading import time import urllib.request +from datetime import datetime from functools import wraps from pathlib import Path from urllib.parse import urlparse @@ -216,11 +217,19 @@ def generate_report_summary(result: dict) -> str | None: risk = result.get("risk_assessment") or {} issues = result.get("issues") or result.get("findings") or [] + components = result.get("components") or [] + other_fields = { + k: v + for k, v in result.items() + if k not in ("issues", "findings", "components", "risk_assessment") + } compact = { "score": risk.get("score"), "severity": risk.get("severity"), "recommendation": risk.get("recommendation"), "total_issues": len(issues), + "scanned_files": [c.get("path") or c.get("file") for c in components][:15], + "other_metadata": other_fields, "top_issues": [ { "severity": i.get("severity"), @@ -234,12 +243,15 @@ def generate_report_summary(result: dict) -> str | None: prompt = ( "Du bekommst das JSON-Ergebnis eines automatisierten Sicherheits-Scans für einen " - "AI-Agent-Skill. Schreibe eine kurze, laienverständliche Zusammenfassung auf Deutsch " - "für jemanden ohne Security-Hintergrund, als Fließtext in 2-3 kurzen Absätzen " - "(keine Überschriften, keine Code-Blöcke, keine Aufzählungszeichen):\n" - "Absatz 1: Gesamteinschätzung in 1-2 Sätzen – wie riskant ist es grob?\n" - "Absatz 2: Die wichtigsten Funde in einfachen Worten, ohne unerklärte Fachbegriffe.\n" - "Absatz 3: Konkrete Handlungsempfehlung (bedenkenlos nutzbar / mit Vorsicht " + "AI-Agent-Skill. Schreibe auf Deutsch einen kurzen, laienverständlichen Bericht für " + "jemanden ohne Security-Hintergrund, als Fließtext in 4 kurzen Absätzen, getrennt " + "durch eine Leerzeile (keine Überschriften, keine Code-Blöcke, keine Aufzählungszeichen):\n" + "Absatz 1: Wofür dieser Skill laut den vorliegenden Daten (Dateinamen, Metadaten, " + "Fundtexte) gedacht ist – 1-2 Sätze. Falls der Zweck nicht erkennbar ist, schreibe " + "das ehrlich so.\n" + "Absatz 2: Gesamteinschätzung des Risikos in 1-2 Sätzen.\n" + "Absatz 3: Die wichtigsten Funde in einfachen Worten, ohne unerklärte Fachbegriffe.\n" + "Absatz 4: Konkrete Handlungsempfehlung (bedenkenlos nutzbar / mit Vorsicht " "nutzbar / besser nicht installieren) und eine kurze Begründung warum.\n\n" f"Scan-Ergebnis:\n{json.dumps(compact, ensure_ascii=False)}" ) @@ -358,6 +370,21 @@ footer{ max-width:760px;margin:0 auto;padding:0 24px 40px;color:#9aa2ab;font-size:.85em; } a{color:var(--orange)} +.meta-line{color:var(--ink-soft);font-size:.85em;margin:-4px 0 20px} +.print-btn{ + background:transparent;color:var(--ink);border:1px solid var(--border); + margin-top:0;padding:9px 16px;font-weight:600; +} +.print-btn:hover{background:#f3f4f6} +@media print{ + body{background:#fff} + header{background:#0d0e10 !important;-webkit-print-color-adjust:exact;print-color-adjust:exact} + .no-print{display:none !important} + .card{box-shadow:none;border:1px solid #ccc;page-break-inside:avoid} + details{display:block !important} + details summary{display:none} + a{color:inherit;text-decoration:none} +} @@ -368,7 +395,7 @@ a{color:var(--orange)}
-
+
@@ -385,6 +412,10 @@ a{color:var(--orange)}
{% if result %} +

+ Gescannt am {{ scanned_at }} · Ziel: {{ target_label }} + · +

{% if summary_paragraphs %}

Verständliche Zusammenfassung

@@ -533,6 +564,8 @@ def index(): summary_text = generate_report_summary(result) summary_failed = summary_text is None + target_label = git_url if git_url else (zip_file.filename if zip_file else "-") + return render_template_string( PAGE, allow_llm=ALLOW_LLM, @@ -543,6 +576,8 @@ def index(): summary_paragraphs=[p for p in (summary_text or "").split("\n\n") if p.strip()], summary_failed=summary_failed, result_json=json.dumps(result, indent=2, ensure_ascii=False), + scanned_at=datetime.now().strftime("%d.%m.%Y %H:%M"), + target_label=target_label, error=None, ) return render_template_string(