diff --git a/frigate/api/event.py b/frigate/api/event.py index c2f7e1eb30..23e4cd9847 100644 --- a/frigate/api/event.py +++ b/frigate/api/event.py @@ -474,22 +474,18 @@ async def event_ids(ids: str, request: Request): status_code=400, ) - for event_id in ids: - try: - event = Event.get(Event.id == event_id) - await require_camera_access(event.camera, request=request) - except DoesNotExist: - # we should not fail the entire request if an event is not found - continue - try: - events = Event.select().where(Event.id << ids).dicts().iterator() - return JSONResponse(list(events)) + events = list(Event.select().where(Event.id << ids).dicts().iterator()) except Exception: return JSONResponse( content=({"success": False, "message": "Events not found"}), status_code=400 ) + for event in events: + await require_camera_access(event["camera"], request=request) + + return JSONResponse(events) + @router.get( "/events/search", diff --git a/frigate/api/review.py b/frigate/api/review.py index cb114db2a0..ae0f85f889 100644 --- a/frigate/api/review.py +++ b/frigate/api/review.py @@ -172,11 +172,17 @@ async def review_ids(request: Request, ids: str): status_code=400, ) + try: + reviews = list(ReviewSegment.select().where(ReviewSegment.id << ids).dicts().iterator()) + except Exception: + return JSONResponse( + content=({"success": False, "message": "Review segments not found"}), + status_code=400, + ) + + found_ids = {r["id"] for r in reviews} for review_id in ids: - try: - review = ReviewSegment.get(ReviewSegment.id == review_id) - await require_camera_access(review.camera, request=request) - except DoesNotExist: + if review_id not in found_ids: return JSONResponse( content=( {"success": False, "message": f"Review {review_id} not found"} @@ -184,16 +190,10 @@ async def review_ids(request: Request, ids: str): status_code=404, ) - try: - reviews = ( - ReviewSegment.select().where(ReviewSegment.id << ids).dicts().iterator() - ) - return JSONResponse(list(reviews)) - except Exception: - return JSONResponse( - content=({"success": False, "message": "Review segments not found"}), - status_code=400, - ) + for review in reviews: + await require_camera_access(review["camera"], request=request) + + return JSONResponse(reviews) @router.get( @@ -490,27 +490,54 @@ async def set_multiple_reviewed( user_id = current_user["username"] - for review_id in body.ids: - try: - review = ReviewSegment.get(ReviewSegment.id == review_id) - await require_camera_access(review.camera, request=request) - review_status = UserReviewStatus.get( - UserReviewStatus.user_id == user_id, - UserReviewStatus.review_segment == review_id, - ) - # Update based on the reviewed parameter - if review_status.has_been_reviewed != body.reviewed: - review_status.has_been_reviewed = body.reviewed - review_status.save() - except DoesNotExist: - try: - UserReviewStatus.create( - user_id=user_id, - review_segment=ReviewSegment.get(id=review_id), - has_been_reviewed=body.reviewed, - ) - except (DoesNotExist, IntegrityError): - pass + reviews = list(ReviewSegment.select(ReviewSegment.id, ReviewSegment.camera).where(ReviewSegment.id << body.ids)) + + for review in reviews: + await require_camera_access(review.camera, request=request) + + found_ids = [r.id for r in reviews] + + if not found_ids: + return JSONResponse( + content=( + { + "success": True, + "message": f"Marked multiple items as {'reviewed' if body.reviewed else 'unreviewed'}", + } + ), + status_code=200, + ) + + existing_statuses = list( + UserReviewStatus.select().where( + (UserReviewStatus.user_id == user_id) & + (UserReviewStatus.review_segment << found_ids) + ) + ) + + status_by_review = {s.review_segment_id: s for s in existing_statuses} + + to_update = [] + to_create = [] + + for review_id in found_ids: + if review_id in status_by_review: + status = status_by_review[review_id] + if status.has_been_reviewed != body.reviewed: + status.has_been_reviewed = body.reviewed + to_update.append(status) + else: + to_create.append({ + "user_id": user_id, + "review_segment_id": review_id, + "has_been_reviewed": body.reviewed, + }) + + if to_update: + UserReviewStatus.bulk_update(to_update, fields=[UserReviewStatus.has_been_reviewed], batch_size=100) + + if to_create: + UserReviewStatus.insert_many(to_create).execute() return JSONResponse( content=(