mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-17 08:35:21 +03:00
add bulk deletion to backend api
This commit is contained in:
parent
fd173e998b
commit
c86db67838
@ -1,4 +1,4 @@
|
|||||||
from typing import Optional, Union
|
from typing import List, Optional, Union
|
||||||
|
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
@ -27,5 +27,9 @@ class EventsEndBody(BaseModel):
|
|||||||
end_time: Optional[float] = None
|
end_time: Optional[float] = None
|
||||||
|
|
||||||
|
|
||||||
|
class EventsDeleteBody(BaseModel):
|
||||||
|
event_ids: List[str] = Field(title="The event IDs to delete")
|
||||||
|
|
||||||
|
|
||||||
class SubmitPlusBody(BaseModel):
|
class SubmitPlusBody(BaseModel):
|
||||||
include_annotation: int = Field(default=1)
|
include_annotation: int = Field(default=1)
|
||||||
|
|||||||
@ -16,6 +16,7 @@ from playhouse.shortcuts import model_to_dict
|
|||||||
|
|
||||||
from frigate.api.defs.events_body import (
|
from frigate.api.defs.events_body import (
|
||||||
EventsCreateBody,
|
EventsCreateBody,
|
||||||
|
EventsDeleteBody,
|
||||||
EventsDescriptionBody,
|
EventsDescriptionBody,
|
||||||
EventsEndBody,
|
EventsEndBody,
|
||||||
EventsSubLabelBody,
|
EventsSubLabelBody,
|
||||||
@ -1036,34 +1037,64 @@ def regenerate_description(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@router.delete("/events/{event_id}")
|
def delete_single_event(event_id: str, request: Request) -> dict:
|
||||||
def delete_event(request: Request, event_id: str):
|
|
||||||
try:
|
try:
|
||||||
event = Event.get(Event.id == event_id)
|
event = Event.get(Event.id == event_id)
|
||||||
except DoesNotExist:
|
except DoesNotExist:
|
||||||
return JSONResponse(
|
return {"success": False, "message": f"Event {event_id} not found"}
|
||||||
content=({"success": False, "message": "Event " + event_id + " not found"}),
|
|
||||||
status_code=404,
|
|
||||||
)
|
|
||||||
|
|
||||||
media_name = f"{event.camera}-{event.id}"
|
media_name = f"{event.camera}-{event.id}"
|
||||||
if event.has_snapshot:
|
if event.has_snapshot:
|
||||||
media = Path(f"{os.path.join(CLIPS_DIR, media_name)}.jpg")
|
snapshot_paths = [
|
||||||
media.unlink(missing_ok=True)
|
Path(f"{os.path.join(CLIPS_DIR, media_name)}.jpg"),
|
||||||
media = Path(f"{os.path.join(CLIPS_DIR, media_name)}-clean.png")
|
Path(f"{os.path.join(CLIPS_DIR, media_name)}-clean.png"),
|
||||||
media.unlink(missing_ok=True)
|
]
|
||||||
|
for media in snapshot_paths:
|
||||||
|
media.unlink(missing_ok=True)
|
||||||
|
|
||||||
event.delete_instance()
|
event.delete_instance()
|
||||||
Timeline.delete().where(Timeline.source_id == event_id).execute()
|
Timeline.delete().where(Timeline.source_id == event_id).execute()
|
||||||
|
|
||||||
# If semantic search is enabled, update the index
|
# If semantic search is enabled, update the index
|
||||||
if request.app.frigate_config.semantic_search.enabled:
|
if request.app.frigate_config.semantic_search.enabled:
|
||||||
context: EmbeddingsContext = request.app.embeddings
|
context: EmbeddingsContext = request.app.embeddings
|
||||||
context.db.delete_embeddings_thumbnail(event_ids=[event_id])
|
context.db.delete_embeddings_thumbnail(event_ids=[event_id])
|
||||||
context.db.delete_embeddings_description(event_ids=[event_id])
|
context.db.delete_embeddings_description(event_ids=[event_id])
|
||||||
return JSONResponse(
|
|
||||||
content=({"success": True, "message": "Event " + event_id + " deleted"}),
|
return {"success": True, "message": f"Event {event_id} deleted"}
|
||||||
status_code=200,
|
|
||||||
)
|
|
||||||
|
@router.delete("/events/{event_id}")
|
||||||
|
def delete_event(request: Request, event_id: str):
|
||||||
|
result = delete_single_event(event_id, request)
|
||||||
|
status_code = 200 if result["success"] else 404
|
||||||
|
return JSONResponse(content=result, status_code=status_code)
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("/events/")
|
||||||
|
def delete_events(request: Request, body: EventsDeleteBody):
|
||||||
|
if not body.event_ids:
|
||||||
|
return JSONResponse(
|
||||||
|
content=({"success": False, "message": "No event IDs provided."}),
|
||||||
|
status_code=404,
|
||||||
|
)
|
||||||
|
|
||||||
|
deleted_events = []
|
||||||
|
not_found_events = []
|
||||||
|
|
||||||
|
for event_id in body.event_ids:
|
||||||
|
result = delete_single_event(event_id, request)
|
||||||
|
if result["success"]:
|
||||||
|
deleted_events.append(event_id)
|
||||||
|
else:
|
||||||
|
not_found_events.append(event_id)
|
||||||
|
|
||||||
|
response = {
|
||||||
|
"success": True,
|
||||||
|
"deleted_events": deleted_events,
|
||||||
|
"not_found_events": not_found_events,
|
||||||
|
}
|
||||||
|
return JSONResponse(content=response, status_code=200)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/events/{camera_name}/{label}/create")
|
@router.post("/events/{camera_name}/{label}/create")
|
||||||
|
|||||||
@ -32,8 +32,9 @@ export default function SearchActionGroup({
|
|||||||
|
|
||||||
const onDelete = useCallback(async () => {
|
const onDelete = useCallback(async () => {
|
||||||
await axios
|
await axios
|
||||||
// TODO: fix for multiple event deletion
|
.delete(`events/`, {
|
||||||
.delete(`events/${selectedObjects.id}`)
|
data: { event_ids: selectedObjects },
|
||||||
|
})
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
if (resp.status == 200) {
|
if (resp.status == 200) {
|
||||||
toast.success("Tracked objects deleted successfully.", {
|
toast.success("Tracked objects deleted successfully.", {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user