|
69 | 69 | router = APIRouter(tags=[Tags.events]) |
70 | 70 |
|
71 | 71 |
|
| 72 | +def _build_attribute_filter_clause(attributes: str): |
| 73 | + filtered_attributes = [ |
| 74 | + attr.strip() for attr in attributes.split(",") if attr.strip() |
| 75 | + ] |
| 76 | + attribute_clauses = [] |
| 77 | + |
| 78 | + for attr in filtered_attributes: |
| 79 | + attribute_clauses.append(Event.data.cast("text") % f'*:"{attr}"*') |
| 80 | + |
| 81 | + escaped_attr = json.dumps(attr, ensure_ascii=True)[1:-1] |
| 82 | + if escaped_attr != attr: |
| 83 | + attribute_clauses.append(Event.data.cast("text") % f'*:"{escaped_attr}"*') |
| 84 | + |
| 85 | + if not attribute_clauses: |
| 86 | + return None |
| 87 | + |
| 88 | + return reduce(operator.or_, attribute_clauses) |
| 89 | + |
| 90 | + |
72 | 91 | @router.get( |
73 | 92 | "/events", |
74 | 93 | response_model=list[EventResponse], |
@@ -193,14 +212,9 @@ def events( |
193 | 212 |
|
194 | 213 | if attributes != "all": |
195 | 214 | # Custom classification results are stored as data[model_name] = result_value |
196 | | - filtered_attributes = attributes.split(",") |
197 | | - attribute_clauses = [] |
198 | | - |
199 | | - for attr in filtered_attributes: |
200 | | - attribute_clauses.append(Event.data.cast("text") % f'*:"{attr}"*') |
201 | | - |
202 | | - attribute_clause = reduce(operator.or_, attribute_clauses) |
203 | | - clauses.append(attribute_clause) |
| 215 | + attribute_clause = _build_attribute_filter_clause(attributes) |
| 216 | + if attribute_clause is not None: |
| 217 | + clauses.append(attribute_clause) |
204 | 218 |
|
205 | 219 | if recognized_license_plate != "all": |
206 | 220 | filtered_recognized_license_plates = recognized_license_plate.split(",") |
@@ -508,7 +522,7 @@ def events_search( |
508 | 522 | cameras = params.cameras |
509 | 523 | labels = params.labels |
510 | 524 | sub_labels = params.sub_labels |
511 | | - attributes = params.attributes |
| 525 | + attributes = unquote(params.attributes) |
512 | 526 | zones = params.zones |
513 | 527 | after = params.after |
514 | 528 | before = params.before |
@@ -607,13 +621,9 @@ def events_search( |
607 | 621 |
|
608 | 622 | if attributes != "all": |
609 | 623 | # Custom classification results are stored as data[model_name] = result_value |
610 | | - filtered_attributes = attributes.split(",") |
611 | | - attribute_clauses = [] |
612 | | - |
613 | | - for attr in filtered_attributes: |
614 | | - attribute_clauses.append(Event.data.cast("text") % f'*:"{attr}"*') |
615 | | - |
616 | | - event_filters.append(reduce(operator.or_, attribute_clauses)) |
| 624 | + attribute_clause = _build_attribute_filter_clause(attributes) |
| 625 | + if attribute_clause is not None: |
| 626 | + event_filters.append(attribute_clause) |
617 | 627 |
|
618 | 628 | if zones != "all": |
619 | 629 | zone_clauses = [] |
|
0 commit comments