From 0829517b72c117583c92917c580fd93daf57841e Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sun, 10 Nov 2024 16:57:11 -0600 Subject: [PATCH] Add ability to filter Explore by Frigate+ submission status (#14909) * backend * add is_submitted to query params * add submitted filter to dialog * allow is_submitted filter selection with input --- frigate/api/defs/events_query_parameters.py | 1 + frigate/api/event.py | 7 ++ web/src/components/input/InputWithTags.tsx | 19 ++- .../overlay/dialog/SearchFilterDialog.tsx | 114 ++++++++++++++++-- web/src/pages/Explore.tsx | 2 + web/src/types/search.ts | 1 + web/src/views/search/SearchView.tsx | 4 +- 7 files changed, 135 insertions(+), 13 deletions(-) diff --git a/frigate/api/defs/events_query_parameters.py b/frigate/api/defs/events_query_parameters.py index 4639b7f59..5a2b61d43 100644 --- a/frigate/api/defs/events_query_parameters.py +++ b/frigate/api/defs/events_query_parameters.py @@ -47,6 +47,7 @@ class EventsSearchQueryParams(BaseModel): time_range: Optional[str] = DEFAULT_TIME_RANGE has_clip: Optional[bool] = None has_snapshot: Optional[bool] = None + is_submitted: Optional[bool] = None timezone: Optional[str] = "utc" min_score: Optional[float] = None max_score: Optional[float] = None diff --git a/frigate/api/event.py b/frigate/api/event.py index cf0ac26cc..bff1edc1a 100644 --- a/frigate/api/event.py +++ b/frigate/api/event.py @@ -360,6 +360,7 @@ def events_search(request: Request, params: EventsSearchQueryParams = Depends()) time_range = params.time_range has_clip = params.has_clip has_snapshot = params.has_snapshot + is_submitted = params.is_submitted # for similarity search event_id = params.event_id @@ -441,6 +442,12 @@ def events_search(request: Request, params: EventsSearchQueryParams = Depends()) if has_snapshot is not None: event_filters.append((Event.has_snapshot == has_snapshot)) + if is_submitted is not None: + if is_submitted == 0: + event_filters.append((Event.plus_id.is_null())) + elif is_submitted > 0: + event_filters.append((Event.plus_id != "")) + if min_score is not None and max_score is not None: event_filters.append((Event.data["score"].between(min_score, max_score))) else: diff --git a/web/src/components/input/InputWithTags.tsx b/web/src/components/input/InputWithTags.tsx index e5b492bcc..8f60bb73e 100644 --- a/web/src/components/input/InputWithTags.tsx +++ b/web/src/components/input/InputWithTags.tsx @@ -194,6 +194,11 @@ export default function InputWithTags({ if (newFilters[filterType] === filterValue) { delete newFilters[filterType]; } + } else if (filterType === "has_snapshot") { + if (newFilters[filterType] === filterValue) { + delete newFilters[filterType]; + delete newFilters["is_submitted"]; + } } else { delete newFilters[filterType]; } @@ -307,6 +312,10 @@ export default function InputWithTags({ if (!newFilters.has_snapshot) newFilters.has_snapshot = undefined; newFilters.has_snapshot = value == "yes" ? 1 : 0; break; + case "is_submitted": + if (!newFilters.is_submitted) newFilters.is_submitted = undefined; + newFilters.is_submitted = value == "yes" ? 1 : 0; + break; case "has_clip": if (!newFilters.has_clip) newFilters.has_clip = undefined; newFilters.has_clip = value == "yes" ? 1 : 0; @@ -356,7 +365,11 @@ export default function InputWithTags({ }`; } else if (filterType === "min_score" || filterType === "max_score") { return Math.round(Number(filterValues) * 100).toString() + "%"; - } else if (filterType === "has_clip" || filterType === "has_snapshot") { + } else if ( + filterType === "has_clip" || + filterType === "has_snapshot" || + filterType === "is_submitted" + ) { return filterValues ? "Yes" : "No"; } else { return filterValues as string; @@ -774,7 +787,9 @@ export default function InputWithTags({ > {filterType === "event_id" ? "Tracked Object ID" - : filterType.replaceAll("_", " ")} + : filterType === "is_submitted" + ? "Submitted to Frigate+" + : filterType.replaceAll("_", " ")} : {formatFilterValues(filterType, filterValues)}