"""Logic layer for release correction.""" from oto.response import create_error_response, \ create_not_found_response, Response from product_workflow.connectors import mysql from product_workflow.constants import error, field, \ release_approval_queue_status as raqs, release_correction_status from product_workflow.models import ows_lyrics from product_workflow.models import ows_track from product_workflow.models import release_approval_queue from product_workflow.models import release_correction def create_release_correction_record(product_id, correction_data): """Create a new record in release_correction. Args: product_id (str): unique identifier for the product Returns: response.Response with result of creating a new record """ correction_data.update({'status': 'active'}) correction_data.update({'release_id': int(product_id)}) return release_correction.create(correction_data) def update_release_correction_record(release_correction_id, correction_data): """Update an existing release_correction record. Args: release_correction_id (str): unique identifier for release_correction. correction_data (dict): Dictionary of properties to update. Returns: Response of the release_correction's updated properties. """ return release_correction.update(release_correction_id, correction_data) def get_last_correction(product_id): """Get the last release correction record for the given product id. Args: product_id (str): unique identifier for the product Returns: Response containing the product's last release correction. """ return release_correction.get_last_release_correction(product_id) def get_correction(release_correction_id): """Get a release correction record for the given release correction id. Args: release_correction_id (str): unique identifier for release_correction. Returns: Response containing the release correction. """ correction = release_correction.get_release_correction( release_correction_id) if isinstance(correction, Response): return correction if correction is None: return create_not_found_response( message='No release correction record found') return Response(message=correction.to_dict()) @mysql.wrap_db_errors def delete_release_correction(release_correction_id): """Delete a release correction specified by a release_correction_id. Args: release_correction_id (str): unique identifier for the release correction. Returns: Response indicating if the deletion was successful. """ with mysql.db_session() as session: correction = release_correction.get_correction_object( session, release_correction_id) if correction is None: return create_not_found_response( message='No release correction record found') if correction.status != release_correction_status.ACTIVE: msg = error.ERROR_DELETE_CORRECTION_NOT_ACTIVE.format( correction.status) return create_error_response( status=400, code=error.ERROR_CODE_BAD_REQUEST, message=msg ) # check if correction has a rejected release approval queue approval = release_approval_queue.get_approval_for_correction( session, release_correction_id) if approval: rejected = approval.status == raqs.REJECTED # fail discarding error correction if release approval queue is not # rejected. this should never happen but in case a client tries it. if not rejected: return create_error_response( status=400, code=error.ERROR_CODE_BAD_REQUEST, message=error.ERROR_DELETE_CORRECTION_WITH_APPROVAL ) session.delete(approval) session.delete(correction) return Response( message=dict(message='release correction deleted'), status=202 ) def get_lyrics_by_product_id(product_id): """Get lyrics response for a product. Args: product_id (str): unique identifier for the product Returns: Response containing whether lyrics present for tracks are submitted in correction or in ows-lyrics for a product. """ track_lyrics_data = [] track_ids_in_correction = [] track_ids_with_lyrics = [] track_lyrics_correction_data = get_lyrics_in_correction(product_id) if ( not track_lyrics_correction_data and track_lyrics_correction_data.status != 404 ): return track_lyrics_correction_data if track_lyrics_correction_data: for correction_details in track_lyrics_correction_data: lyrics_data = { 'track_id': correction_details['key_id'], 'has_lyrics': bool(correction_details['key_value']), 'lyrics_corrected': True } track_ids_in_correction.append(correction_details['key_id']) track_lyrics_data.append(lyrics_data) ows_track_response = ows_track.get_tracks_by_product_id(product_id) if not ows_track_response: return ows_track_response track_ids = [ track['tuid'] for track in ows_track_response.message['items']] track_ids_not_in_correction = set(track_ids).difference( set(track_ids_in_correction)) if track_ids_not_in_correction: ows_lyrics_response = ows_lyrics.get_lyrics_by_track_ids( track_ids_not_in_correction) if not ows_lyrics_response and ows_lyrics_response.status != 404: return ows_lyrics_response if ows_lyrics_response: for lyrics_details in ows_lyrics_response.message['items']: lyrics_data = { 'track_id': lyrics_details['track_id'], 'has_lyrics': bool(lyrics_details['lyrics']), 'lyrics_corrected': False } track_lyrics_data.append(lyrics_data) track_ids_with_lyrics.append(lyrics_details['track_id']) track_ids_with_no_lyrics = set(track_ids_not_in_correction).difference( set(track_ids_with_lyrics)) if track_ids_with_no_lyrics: for track_id in track_ids_with_no_lyrics: lyrics_data = { 'track_id': track_id, 'has_lyrics': False, 'lyrics_corrected': False } track_lyrics_data.append(lyrics_data) if not track_lyrics_data: return create_not_found_response( message='No lyrics data found for the product') return Response(message={'tracks': track_lyrics_data}) def get_lyrics_in_correction(product_id, track_id=None): """Get all track lyrics in correction for a product. Args: product_id (str): unique identifier for the product track_id (int): unique identifier for the track Returns: Response containing all track lyrics submitted in correction for a product. """ last_release_correction = release_correction.get_last_release_correction( product_id) if not last_release_correction: return last_release_correction lyrics_correction_data = [] if ( last_release_correction.message['status'] == release_correction_status.SUBMITTED ): for correction_details in last_release_correction.message['items']: if correction_details['field_name'] == field.LYRICS: if not track_id: lyrics_correction_data.append(correction_details) elif track_id and correction_details['key_id'] == track_id: lyrics_correction_data = correction_details break if not lyrics_correction_data: return create_not_found_response( message='No lyrics correction record found') return lyrics_correction_data def get_lyrics_by_track_id(product_id, track_id): """Get lyrics response data for the track. Args: product_id (int): unique identifier for the product track_id (int): unique identifier for the track Returns: Response containing lyrics present for track in correction or in ows-lyrics. """ track_lyrics = None track_lyrics_correction = get_lyrics_in_correction(product_id, track_id) if (not track_lyrics_correction and track_lyrics_correction.status != 404): return track_lyrics_correction if track_lyrics_correction: track_lyrics = { 'track_id': track_lyrics_correction['key_id'], 'lyrics': track_lyrics_correction['key_value'] } if not track_lyrics_correction: ows_lyrics_data = ows_lyrics.get_lyrics_by_track_ids([track_id]) if not ows_lyrics_data and ows_lyrics_data.status != 404: return ows_lyrics_data if ows_lyrics_data: track_lyrics = { 'track_id': ows_lyrics_data.message['items'][0]['track_id'], 'lyrics': ows_lyrics_data.message['items'][0]['lyrics'] } if not track_lyrics: return create_not_found_response( message='No lyrics data found for the track') return Response(message=track_lyrics)