5d60d33db1
Volledige Foodlinkk Command Center uitbreiding met social automatisering, reclamefolder filters, Proxmox monitoring en documentatie.
72 lines
2.6 KiB
Python
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,
|
|
},
|
|
)
|