Files
foodlinkk-command-center/cockpit/app/routes/browser.py
T
Aissa 5d60d33db1 Platform bundle: marketing publish, IT ops, packaging, agents mesh.
Volledige Foodlinkk Command Center uitbreiding met social automatisering,
reclamefolder filters, Proxmox monitoring en documentatie.
2026-06-09 00:41:27 +00:00

72 lines
2.6 KiB
Python

from pathlib import Path
from fastapi import APIRouter, Request
from fastapi.templating import Jinja2Templates
from app.db import fetch_all, fetch_one
router = APIRouter(tags=["browser"])
BASE_DIR = Path(__file__).resolve().parent.parent.parent
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
def _iso_rows(rows: list) -> list:
for row in rows:
for key, val in list(row.items()):
if hasattr(val, "isoformat"):
row[key] = val.isoformat()
return rows
def _monitor_context() -> dict:
sites, changes, logs = [], [], []
stats = {"active_sites": 0, "changes_24h": 0}
try:
sites = _iso_rows(fetch_all(
"""SELECT id, url, name, last_hash, last_crawled, is_active
FROM monitored_sites ORDER BY last_crawled DESC NULLS LAST LIMIT 100"""
))
row = fetch_one("SELECT COUNT(*) AS c FROM monitored_sites WHERE is_active = TRUE")
stats["active_sites"] = int(row["c"]) if row else 0
row = fetch_one(
"SELECT COUNT(*) AS c FROM page_changes WHERE changed_at > NOW() - interval '24 hours'"
)
stats["changes_24h"] = int(row["c"]) if row else 0
except Exception:
sites = []
try:
changes = _iso_rows(fetch_all(
"""SELECT pc.id, pc.site_id, pc.old_hash, pc.new_hash, pc.changed_at, ms.url, ms.name
FROM page_changes pc JOIN monitored_sites ms ON pc.site_id = ms.id
ORDER BY pc.changed_at DESC LIMIT 50"""
))
except Exception:
changes = []
try:
logs = _iso_rows(fetch_all(
"""SELECT cl.id, cl.site_id, cl.status, cl.message, cl.logged_at, ms.url, ms.name
FROM crawl_logs cl LEFT JOIN monitored_sites ms ON cl.site_id = ms.id
ORDER BY cl.logged_at DESC LIMIT 50"""
))
except Exception:
logs = []
return {"sites": sites, "page_changes": changes, "crawl_logs": logs, "stats": stats}
@router.get("/browser")
async def browser_page(request: Request):
ctx = _monitor_context()
return templates.TemplateResponse(
"browser.html",
{
"request": request,
"page_title": "Browser & Monitor",
"default_url": "https://www.bidfood.nl/webshop/assortiment/mekkafood/_/N-1z10pje/",
"browser_agent_url": "http://10.4.7.18:7790",
"novnc_url": "http://10.4.7.18:6080/vnc.html?autoconnect=true&resize=scale&path=websockify&password=Foodlinkk2026",
"gradio_url": "http://10.4.7.18:7788",
**ctx,
},
)