"""Review queue item utils.""" from datetime import datetime, timezone from flask import g from owsresponse import status as owsresponse_status from sqlalchemy.exc import OperationalError from product_review.constants.error import ( ERROR_CODE_REVIEW_QUEUE_ITEM_UPDATE_IN_PROGRESS, ERROR_CODE_NOT_FOUND, ERROR_CODE_REVIEW_QUEUE_ITEM_LOCKED, ERROR_CODE_REVIEW_QUEUE_ITEM_STATUS_NOT_NEW, ERROR_MESSAGE_REVIEW_QUEUE_ITEM_UPDATE_IN_PROGRESS, ERROR_MESSAGE_NOT_FOUND, ERROR_MESSAGE_REVIEW_QUEUE_ITEM_LOCKED, ERROR_MESSAGE_REVIEW_QUEUE_ITEM_STATUS_NOT_NEW, ) from product_review.models import review_queue as review_queue_model from product_review.util.exception import raise_exception_for_ows_response def get_review_queue_item_for_update(review_queue_id): """Get a review queue item for update if it meets the required conditions.""" try: review_queue_item = review_queue_model.get_item_for_update(review_queue_id) except OperationalError as e: # Handle MySQL lock wait timeout (error 1205) specifically if hasattr(e, 'orig') and getattr(e.orig, 'args', None): err_args = e.orig.args if len(err_args) > 1 and err_args[0] == 1205: # Lock wait timeout exceeded raise_exception_for_ows_response( status=owsresponse_status.CONFLICT, code=ERROR_CODE_REVIEW_QUEUE_ITEM_UPDATE_IN_PROGRESS, message=ERROR_MESSAGE_REVIEW_QUEUE_ITEM_UPDATE_IN_PROGRESS, ) raise if not review_queue_item: raise_exception_for_ows_response( status=owsresponse_status.NOT_FOUND, code=ERROR_CODE_NOT_FOUND, message=ERROR_MESSAGE_NOT_FOUND, ) if review_queue_item.status != review_queue_model.STATUS.NEW: raise raise_exception_for_ows_response( status=owsresponse_status.BAD_REQUEST, code=ERROR_CODE_REVIEW_QUEUE_ITEM_STATUS_NOT_NEW, message=ERROR_MESSAGE_REVIEW_QUEUE_ITEM_STATUS_NOT_NEW, ) check_lock( review_queue_item.locked_by_user_id, review_queue_item.locked_until_datetime, ) return review_queue_item def check_lock(locked_by_user_id, locked_until_datetime): """Check if review_queue_item is locked.""" if not locked_by_user_id or not locked_until_datetime: return if datetime.now(timezone.utc) >= locked_until_datetime.replace(tzinfo=timezone.utc): return if g.request_context.identity_id == locked_by_user_id: return raise_exception_for_ows_response( status=owsresponse_status.FORBIDDEN, code=ERROR_CODE_REVIEW_QUEUE_ITEM_LOCKED, message=ERROR_MESSAGE_REVIEW_QUEUE_ITEM_LOCKED, )