from fastapi import FastAPI, Request, Form from fastapi.responses import HTMLResponse, RedirectResponse from jinja2 import Template import requests import json from dateutil import parser, tz from pathlib import Path app = FastAPI() API_URL = "http://192.168.18.4:8000/results/updatecheck/" READ_API_KEY = "read_key_1" REFERENCE_FILE = "reference_versions.json" def fetch_raw_lines(): try: response = requests.get(API_URL, headers={"Authorization": f"Bearer {READ_API_KEY}"}, timeout=5) response.raise_for_status() return response.json().get("lines", []) except Exception as e: print(f"❌ Fehler beim Abrufen der Logs: {e}") return [] def fetch_reference(): try: with open(REFERENCE_FILE) as f: return json.load(f) except Exception: return {} def fetch_latest_per_host(): lines = fetch_raw_lines() reference = fetch_reference() latest = {} for line in lines: parts = line.strip().split(",", 3) if len(parts) < 4: continue timestamp, hostname, _, packages = parts if hostname not in latest or timestamp > latest[hostname]["timestamp"]: latest[hostname] = { "timestamp": timestamp, "raw": packages } result = {} for host, entry in latest.items(): try: dt = parser.isoparse(entry["timestamp"]).astimezone(tz.gettz("Europe/Berlin")) display_time = dt.strftime("%Y-%m-%d %H:%M:%S") except: display_time = entry["timestamp"] pkgs = {} for p in entry["raw"].strip(";").split(";"): if "=" in p: k, v = p.split("=", 1) pkgs[k] = { "current": v, "expected": reference.get(k) } result[host] = { "timestamp": display_time, "packages": pkgs } return result def fetch_history_for_host(hostname): lines = fetch_raw_lines() history = [] for line in lines: parts = line.strip().split(",", 3) if len(parts) < 4 or parts[1] != hostname: continue timestamp, _, _, raw = parts pkgs = {} for p in raw.strip(";").split(";"): if "=" in p: k, v = p.split("=", 1) pkgs[k] = v history.append({"timestamp": timestamp, "packages": pkgs}) history.sort(key=lambda x: x["timestamp"], reverse=True) return history @app.get("/", response_class=HTMLResponse) def index(): data = fetch_latest_per_host() return MAIN_TEMPLATE.render(data=data) @app.get("/host/{hostname}", response_class=HTMLResponse) def host_view(hostname: str): return HOST_TEMPLATE.render(hostname=hostname, history=fetch_history_for_host(hostname)) @app.get("/edit", response_class=HTMLResponse) def edit_view(): try: data = Path(REFERENCE_FILE).read_text() except: data = "{}" return EDIT_TEMPLATE.render(content=data) @app.post("/edit", response_class=RedirectResponse) def edit_post(content: str = Form(...)): try: json.loads(content) Path(REFERENCE_FILE).write_text(content) except Exception as e: print(f"Fehler beim Schreiben der Referenzdatei: {e}") return RedirectResponse(url="/edit", status_code=303) # ========== Templates ========== MAIN_TEMPLATE = Template("""
Paket | Version |
---|---|
{{ p }} | {{ v }} |