mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-09-28 10:56:52 +03:00
* Notice and status bar improvements Status bar problems added in the same pass got the same `Date.now()` id and overwrote each other, so usually only one showed. Messages now fall back to their text as the id. The desktop status bar shows the most severe message with a count of the rest that opens a popover listing all of them, and the mobile drawer stacks them vertically instead of placing them side by side. Dismissing a notice hid it for good, so a detector that restarted again after a dismissal was never shown. Dismiss is replaced by acknowledge, which hides a notice until it happens again, and mute, which hides it permanently. Kinds that never repeat (config and stream checks, the update notice) can only be muted. `reopen_at_count` is removed since acknowledge covers the failed login case. * move camera CPU warnings to notices High ffmpeg and detect CPU warnings sat in the status bar with no way to dismiss them. They're now `ffmpeg_high_cpu` and `detect_high_cpu` notices, raised per episode by the same tracker as skipped detections. Also stop failed login attempts held from before an acknowledgement from reopening the notice. * fix mypy and handle missing cpu stats in notices
99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
"""Notice APIs."""
|
|
|
|
import logging
|
|
|
|
from fastapi import APIRouter, Depends, Request
|
|
from fastapi.responses import JSONResponse
|
|
|
|
from frigate.api.auth import require_role
|
|
from frigate.api.defs.tags import Tags
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter(tags=[Tags.notices])
|
|
|
|
|
|
@router.get("/notices", dependencies=[Depends(require_role(["admin"]))])
|
|
def get_notices(request: Request, include_hidden: bool = False) -> JSONResponse:
|
|
"""Get notices, most severe first.
|
|
|
|
Args:
|
|
include_hidden: Also return acknowledged and muted notices, for the
|
|
hidden list
|
|
|
|
Returns:
|
|
The notices
|
|
"""
|
|
return JSONResponse(
|
|
content=request.app.notice_registry.active(include_hidden=include_hidden)
|
|
)
|
|
|
|
|
|
@router.get("/notices/stats", dependencies=[Depends(require_role(["admin"]))])
|
|
def get_notice_stats(request: Request) -> JSONResponse:
|
|
"""Get lifetime occurrence counts per notice kind."""
|
|
return JSONResponse(content=request.app.notice_registry.stats())
|
|
|
|
|
|
@router.get("/notices/muted_checks", dependencies=[Depends(require_role(["admin"]))])
|
|
def get_muted_checks(request: Request) -> JSONResponse:
|
|
"""Get the muted config and stream check rows, newest first."""
|
|
return JSONResponse(content=request.app.notice_registry.muted_checks())
|
|
|
|
|
|
@router.delete("/notices/hidden", dependencies=[Depends(require_role(["admin"]))])
|
|
def unhide_all_notices(request: Request) -> JSONResponse:
|
|
"""Show every acknowledged and muted notice and check row again."""
|
|
request.app.notice_registry.unhide_all()
|
|
return JSONResponse(content={"success": True, "message": "Notices shown again"})
|
|
|
|
|
|
# model notice ids contain a slash, so the id is a path parameter
|
|
@router.post(
|
|
"/notices/{notice_id:path}/acknowledge",
|
|
dependencies=[Depends(require_role(["admin"]))],
|
|
)
|
|
def acknowledge_notice(request: Request, notice_id: str) -> JSONResponse:
|
|
"""Hide a notice until it happens again.
|
|
|
|
Config and stream check rows and the update notice never repeat, so they
|
|
can only be muted.
|
|
"""
|
|
if not request.app.notice_registry.acknowledge(notice_id):
|
|
return JSONResponse(
|
|
content={"success": False, "message": "Notice not found"},
|
|
status_code=404,
|
|
)
|
|
|
|
return JSONResponse(content={"success": True, "message": "Notice acknowledged"})
|
|
|
|
|
|
@router.post(
|
|
"/notices/{notice_id:path}/mute",
|
|
dependencies=[Depends(require_role(["admin"]))],
|
|
)
|
|
def mute_notice(request: Request, notice_id: str) -> JSONResponse:
|
|
"""Hide a notice or a config or stream check row for good."""
|
|
if not request.app.notice_registry.mute(notice_id):
|
|
return JSONResponse(
|
|
content={"success": False, "message": "Notice not found"},
|
|
status_code=404,
|
|
)
|
|
|
|
return JSONResponse(content={"success": True, "message": "Notice muted"})
|
|
|
|
|
|
@router.delete(
|
|
"/notices/{notice_id:path}/hidden",
|
|
dependencies=[Depends(require_role(["admin"]))],
|
|
)
|
|
def unhide_notice(request: Request, notice_id: str) -> JSONResponse:
|
|
"""Show an acknowledged or muted notice or check row again."""
|
|
if not request.app.notice_registry.unhide(notice_id):
|
|
return JSONResponse(
|
|
content={"success": False, "message": "Notice not found"},
|
|
status_code=404,
|
|
)
|
|
|
|
return JSONResponse(content={"success": True, "message": "Notice shown again"})
|