"""REST: системная статистика и сводный статус.""" from __future__ import annotations import os from fastapi import APIRouter, HTTPException, Request from ..auth import require_role from ..config import Storage, save_config from ..runtime import runtime from ..services.system import system_stats router = APIRouter(prefix="/api", tags=["system"]) ALLOWED_SEGMENTS = (60, 120, 300, 600, 900) # 1 / 2 / 5 / 10 / 15 минут VERSION_FILE = os.environ.get("NVR_VERSION_FILE", "/app/VERSION") def app_version() -> str: try: with open(VERSION_FILE, "r", encoding="utf-8") as fh: return fh.read().strip() except OSError: return "0.0.0" @router.get("/system") async def get_system() -> dict: stats = system_stats(runtime.config) stats["cameras"] = [s.to_dict() for s in runtime.supervisor.statuses()] stats["archive_size_bytes"] = await runtime.db.total_size() stats["version"] = app_version() return stats @router.get("/health") async def health() -> dict: return {"status": "ok"} @router.post("/storage") async def update_storage(request: Request) -> dict: """Смена размера сегмента записи (1/5/10/15 мин). Перезапускает рекордеры.""" require_role(request, "admin") body = await request.json() try: seg = int(body.get("segment_seconds")) except (TypeError, ValueError): raise HTTPException(400, "segment_seconds должен быть числом") if seg not in ALLOWED_SEGMENTS: raise HTTPException(400, "допустимо 60 / 300 / 600 / 900 секунд") st = runtime.config.storage runtime.config.storage = Storage( path=st.path, quota_gb=st.quota_gb, retention_days=st.retention_days, segment_seconds=seg, ) save_config(runtime.config) await runtime.supervisor.restart_all() return {"segment_seconds": seg}