thay dỏi cong
This commit is contained in:
+32
-4
@@ -2,9 +2,11 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
import httpx
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
@@ -26,6 +28,8 @@ def _cors_origins() -> list[str]:
|
||||
raw = os.getenv("CORS_ORIGINS", "http://localhost:5173")
|
||||
return [x.strip() for x in raw.split(",") if x.strip()]
|
||||
|
||||
logger = logging.getLogger("ipcam_dashboard")
|
||||
|
||||
|
||||
app = FastAPI(title="IPCam Dashboard API")
|
||||
app.add_middleware(
|
||||
@@ -61,9 +65,21 @@ async def _scheduler_loop() -> None:
|
||||
try:
|
||||
cfg = await store.load()
|
||||
await scheduler.tick(cfg.schedule)
|
||||
except Exception:
|
||||
logger.exception("scheduler_tick_failed")
|
||||
finally:
|
||||
await asyncio.sleep(60)
|
||||
|
||||
def _raise_mediamtx_http_error(err: httpx.HTTPError) -> None:
|
||||
if isinstance(err, httpx.HTTPStatusError):
|
||||
code = err.response.status_code
|
||||
if code == 401:
|
||||
raise HTTPException(status_code=502, detail="mediamtx_unauthorized")
|
||||
if code == 403:
|
||||
raise HTTPException(status_code=502, detail="mediamtx_forbidden")
|
||||
raise HTTPException(status_code=502, detail=f"mediamtx_http_{code}")
|
||||
raise HTTPException(status_code=502, detail="mediamtx_unreachable")
|
||||
|
||||
|
||||
@app.on_event("startup")
|
||||
async def _startup() -> None:
|
||||
@@ -98,7 +114,10 @@ async def add_camera(camera: Camera) -> AppConfig:
|
||||
username=os.getenv("MEDIAMTX_API_USER"),
|
||||
password=os.getenv("MEDIAMTX_API_PASS"),
|
||||
)
|
||||
await client.upsert_paths_sources_bulk({camera.name: camera.rtsp_url})
|
||||
try:
|
||||
await client.upsert_paths_sources_bulk({camera.name: camera.rtsp_url})
|
||||
except httpx.HTTPError as e:
|
||||
_raise_mediamtx_http_error(e)
|
||||
return cfg
|
||||
|
||||
|
||||
@@ -116,7 +135,10 @@ async def delete_camera(name: str) -> AppConfig:
|
||||
username=os.getenv("MEDIAMTX_API_USER"),
|
||||
password=os.getenv("MEDIAMTX_API_PASS"),
|
||||
)
|
||||
await client.delete_path(name)
|
||||
try:
|
||||
await client.delete_path(name)
|
||||
except httpx.HTTPError as e:
|
||||
_raise_mediamtx_http_error(e)
|
||||
return cfg
|
||||
|
||||
|
||||
@@ -128,12 +150,18 @@ async def list_paths() -> dict:
|
||||
username=os.getenv("MEDIAMTX_API_USER"),
|
||||
password=os.getenv("MEDIAMTX_API_PASS"),
|
||||
)
|
||||
return await client.list_paths_status()
|
||||
try:
|
||||
return await client.list_paths_status()
|
||||
except httpx.HTTPError as e:
|
||||
_raise_mediamtx_http_error(e)
|
||||
|
||||
|
||||
@app.post("/api/recording")
|
||||
async def toggle_recording(data: RecordingToggle) -> dict:
|
||||
await _apply_recording(data.enabled)
|
||||
try:
|
||||
await _apply_recording(data.enabled)
|
||||
except httpx.HTTPError as e:
|
||||
_raise_mediamtx_http_error(e)
|
||||
return {"enabled": data.enabled}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user