"""Settings and stats API endpoints for frigate-notify v2.""" import logging from datetime import date from fastapi import APIRouter from config import config from database import get_connection from models import StatsResponse logger = logging.getLogger(__name__) router = APIRouter(prefix="/api", tags=["settings"]) @router.get("/settings") async def get_settings(): """Return all settings from DB plus runtime config values.""" conn = get_connection() cursor = conn.execute("SELECT key, value FROM settings") db_settings = {row["key"]: row["value"] for row in cursor.fetchall()} # Merge with runtime config values return { **db_settings, "recognition_threshold_high": config.RECOGNITION_THRESHOLD_HIGH, "recognition_threshold_low": config.RECOGNITION_THRESHOLD_LOW, "rate_limit_seconds": config.RATE_LIMIT_SECONDS, "allowed_labels": list(config.ALLOWED_LABELS), "min_score": config.MIN_SCORE, } @router.put("/settings") async def update_settings(body: dict): """Accept dict body, upsert each key/value into settings table.""" conn = get_connection() for key, value in body.items(): conn.execute( "INSERT INTO settings (key, value) VALUES (?, ?) " "ON CONFLICT(key) DO UPDATE SET value = excluded.value", (key, str(value)), ) conn.commit() return {"status": "ok"} @router.get("/stats", response_model=StatsResponse) async def get_stats(): """Return event and object counts.""" conn = get_connection() total = conn.execute("SELECT COUNT(*) FROM events").fetchone()[0] known = conn.execute( "SELECT COUNT(*) FROM events WHERE match_status = 'known'" ).fetchone()[0] unknown = conn.execute( "SELECT COUNT(*) FROM events WHERE match_status = 'unknown'" ).fetchone()[0] unreviewed = conn.execute( "SELECT COUNT(*) FROM events WHERE match_status = 'unreviewed'" ).fetchone()[0] objects_count = conn.execute("SELECT COUNT(*) FROM known_objects").fetchone()[0] today = date.today().isoformat() events_today = conn.execute( "SELECT COUNT(*) FROM events WHERE DATE(created_at) = ?", (today,), ).fetchone()[0] return StatsResponse( total_events=total, known_matches=known, unknown_events=unknown, unreviewed=unreviewed, known_objects_count=objects_count, events_today=events_today, )