mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-10 02:29:19 +03:00
consolidate attribute filtering to match non-english and url encoded values (#22002)
Some checks failed
CI / AMD64 Build (push) Has been cancelled
CI / ARM Build (push) Has been cancelled
CI / Jetson Jetpack 6 (push) Has been cancelled
CI / AMD64 Extra Build (push) Has been cancelled
CI / ARM Extra Build (push) Has been cancelled
CI / Synaptics Build (push) Has been cancelled
CI / Assemble and push default build (push) Has been cancelled
Some checks failed
CI / AMD64 Build (push) Has been cancelled
CI / ARM Build (push) Has been cancelled
CI / Jetson Jetpack 6 (push) Has been cancelled
CI / AMD64 Extra Build (push) Has been cancelled
CI / ARM Extra Build (push) Has been cancelled
CI / Synaptics Build (push) Has been cancelled
CI / Assemble and push default build (push) Has been cancelled
This commit is contained in:
parent
73c1e12faf
commit
4dcd2968b3
@ -69,6 +69,25 @@ logger = logging.getLogger(__name__)
|
|||||||
router = APIRouter(tags=[Tags.events])
|
router = APIRouter(tags=[Tags.events])
|
||||||
|
|
||||||
|
|
||||||
|
def _build_attribute_filter_clause(attributes: str):
|
||||||
|
filtered_attributes = [
|
||||||
|
attr.strip() for attr in attributes.split(",") if attr.strip()
|
||||||
|
]
|
||||||
|
attribute_clauses = []
|
||||||
|
|
||||||
|
for attr in filtered_attributes:
|
||||||
|
attribute_clauses.append(Event.data.cast("text") % f'*:"{attr}"*')
|
||||||
|
|
||||||
|
escaped_attr = json.dumps(attr, ensure_ascii=True)[1:-1]
|
||||||
|
if escaped_attr != attr:
|
||||||
|
attribute_clauses.append(Event.data.cast("text") % f'*:"{escaped_attr}"*')
|
||||||
|
|
||||||
|
if not attribute_clauses:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return reduce(operator.or_, attribute_clauses)
|
||||||
|
|
||||||
|
|
||||||
@router.get(
|
@router.get(
|
||||||
"/events",
|
"/events",
|
||||||
response_model=list[EventResponse],
|
response_model=list[EventResponse],
|
||||||
@ -193,14 +212,9 @@ def events(
|
|||||||
|
|
||||||
if attributes != "all":
|
if attributes != "all":
|
||||||
# Custom classification results are stored as data[model_name] = result_value
|
# Custom classification results are stored as data[model_name] = result_value
|
||||||
filtered_attributes = attributes.split(",")
|
attribute_clause = _build_attribute_filter_clause(attributes)
|
||||||
attribute_clauses = []
|
if attribute_clause is not None:
|
||||||
|
clauses.append(attribute_clause)
|
||||||
for attr in filtered_attributes:
|
|
||||||
attribute_clauses.append(Event.data.cast("text") % f'*:"{attr}"*')
|
|
||||||
|
|
||||||
attribute_clause = reduce(operator.or_, attribute_clauses)
|
|
||||||
clauses.append(attribute_clause)
|
|
||||||
|
|
||||||
if recognized_license_plate != "all":
|
if recognized_license_plate != "all":
|
||||||
filtered_recognized_license_plates = recognized_license_plate.split(",")
|
filtered_recognized_license_plates = recognized_license_plate.split(",")
|
||||||
@ -508,7 +522,7 @@ def events_search(
|
|||||||
cameras = params.cameras
|
cameras = params.cameras
|
||||||
labels = params.labels
|
labels = params.labels
|
||||||
sub_labels = params.sub_labels
|
sub_labels = params.sub_labels
|
||||||
attributes = params.attributes
|
attributes = unquote(params.attributes)
|
||||||
zones = params.zones
|
zones = params.zones
|
||||||
after = params.after
|
after = params.after
|
||||||
before = params.before
|
before = params.before
|
||||||
@ -607,13 +621,9 @@ def events_search(
|
|||||||
|
|
||||||
if attributes != "all":
|
if attributes != "all":
|
||||||
# Custom classification results are stored as data[model_name] = result_value
|
# Custom classification results are stored as data[model_name] = result_value
|
||||||
filtered_attributes = attributes.split(",")
|
attribute_clause = _build_attribute_filter_clause(attributes)
|
||||||
attribute_clauses = []
|
if attribute_clause is not None:
|
||||||
|
event_filters.append(attribute_clause)
|
||||||
for attr in filtered_attributes:
|
|
||||||
attribute_clauses.append(Event.data.cast("text") % f'*:"{attr}"*')
|
|
||||||
|
|
||||||
event_filters.append(reduce(operator.or_, attribute_clauses))
|
|
||||||
|
|
||||||
if zones != "all":
|
if zones != "all":
|
||||||
zone_clauses = []
|
zone_clauses = []
|
||||||
|
|||||||
@ -168,6 +168,57 @@ class TestHttpApp(BaseTestHttp):
|
|||||||
assert events[0]["id"] == id
|
assert events[0]["id"] == id
|
||||||
assert events[1]["id"] == id2
|
assert events[1]["id"] == id2
|
||||||
|
|
||||||
|
def test_get_event_list_match_multilingual_attribute(self):
|
||||||
|
event_id = "123456.zh"
|
||||||
|
attribute = "中文标签"
|
||||||
|
|
||||||
|
with AuthTestClient(self.app) as client:
|
||||||
|
super().insert_mock_event(event_id, data={"custom_attr": attribute})
|
||||||
|
|
||||||
|
events = client.get("/events", params={"attributes": attribute}).json()
|
||||||
|
assert len(events) == 1
|
||||||
|
assert events[0]["id"] == event_id
|
||||||
|
|
||||||
|
events = client.get(
|
||||||
|
"/events", params={"attributes": "%E4%B8%AD%E6%96%87%E6%A0%87%E7%AD%BE"}
|
||||||
|
).json()
|
||||||
|
assert len(events) == 1
|
||||||
|
assert events[0]["id"] == event_id
|
||||||
|
|
||||||
|
def test_events_search_match_multilingual_attribute(self):
|
||||||
|
event_id = "123456.zh.search"
|
||||||
|
attribute = "中文标签"
|
||||||
|
mock_embeddings = Mock()
|
||||||
|
mock_embeddings.search_thumbnail.return_value = [(event_id, 0.05)]
|
||||||
|
|
||||||
|
self.app.frigate_config.semantic_search.enabled = True
|
||||||
|
self.app.embeddings = mock_embeddings
|
||||||
|
|
||||||
|
with AuthTestClient(self.app) as client:
|
||||||
|
super().insert_mock_event(event_id, data={"custom_attr": attribute})
|
||||||
|
|
||||||
|
events = client.get(
|
||||||
|
"/events/search",
|
||||||
|
params={
|
||||||
|
"search_type": "similarity",
|
||||||
|
"event_id": event_id,
|
||||||
|
"attributes": attribute,
|
||||||
|
},
|
||||||
|
).json()
|
||||||
|
assert len(events) == 1
|
||||||
|
assert events[0]["id"] == event_id
|
||||||
|
|
||||||
|
events = client.get(
|
||||||
|
"/events/search",
|
||||||
|
params={
|
||||||
|
"search_type": "similarity",
|
||||||
|
"event_id": event_id,
|
||||||
|
"attributes": "%E4%B8%AD%E6%96%87%E6%A0%87%E7%AD%BE",
|
||||||
|
},
|
||||||
|
).json()
|
||||||
|
assert len(events) == 1
|
||||||
|
assert events[0]["id"] == event_id
|
||||||
|
|
||||||
def test_get_good_event(self):
|
def test_get_good_event(self):
|
||||||
id = "123456.random"
|
id = "123456.random"
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user