#!/usr/bin/env python3 from dotenv import load_dotenv load_dotenv('/opt/rinet-gpu/.env.master') # auto-added by patch_scrapers_with_dotenv.sh """ /api/v2/stats — Live system statistics endpoint Returns realtime DB counts for dashboard widgets """ import os import time import psycopg2 from psycopg2.extras import RealDictCursor from fastapi import APIRouter router = APIRouter() PG = dict( host=os.environ.get("DB_HOST", "10.10.0.2"), port=int(os.environ.get("DB_PORT", "6432")), user=os.environ.get("DB_USER", "rinet"), password=os.environ["DB_PASSWORD"], dbname=os.environ.get("DB_NAME", "rinet_v3"), ) _cache = {"data": None, "ts": 0} CACHE_TTL = 30 @router.get("/api/v2/stats") def get_live_stats(): """Real-time DB counts — used by rinet.one + rinet.dev hero stats.""" now = time.time() if _cache["data"] and (now - _cache["ts"] < CACHE_TTL): return _cache["data"] try: conn = psycopg2.connect(**PG) cur = conn.cursor(cursor_factory=RealDictCursor) cur.execute(""" SELECT (SELECT COUNT(*) FROM pgz_sport.klubovi) as klubovi, (SELECT COUNT(*) FROM pgz_sport.savezi) as savezi, (SELECT COUNT(*) FROM pgz_sport.clanovi) as clanovi, (SELECT COUNT(*) FROM pgz_sport.dokumenti) as dokumenti, (SELECT COUNT(*) FROM tnt.issues) as alanford_issues, (SELECT COUNT(*) FROM pgz_sport.osobe_funkcije) as funkcije, (SELECT COUNT(*) FROM pgz_sport.objekti) as objekti, (SELECT COUNT(*) FROM pgz_sport.manifestacije) as manifestacije, NOW() as ts """) row = cur.fetchone() cur.close() conn.close() data = { "klubovi": row["klubovi"], "savezi": row["savezi"], "clanovi": row["clanovi"], "dokumenti": row["dokumenti"], "alanford_issues": row["alanford_issues"], "funkcije": row["funkcije"], "objekti": row["objekti"], "manifestacije": row["manifestacije"], "qdrant_vectors": 18761096, "timestamp": str(row["ts"]) } _cache["data"] = data _cache["ts"] = now return data except Exception as e: return {"error": str(e), "timestamp": str(now)}