"""Rights Attributes persister. Handles doing CRUD operations on the track_rights_attributes table. """ from oto import response from backend.connectors import mysql from backend.constants import error from backend.models.rights_attribute import TrackRightsAttributes from backend.models.rights_attribute import TrackRightsAttributesEdits from backend.models.rights_attribute import TrackRightsAttributesChangelog from backend.models.rights_attribute import TrackRightsAttributeSuggestions class TrackRightsAttributePersister(object): """Handles high level operations for track rights attributes.""" @classmethod @mysql.db_session_wrap def sync_track_rights_attributes(cls, tracks, orchard_identity_id, session): """Sync track rights attributes. Args: tracks: The list of tuid / rights attribute combinations to set orchard_identity_id: The orchard identity id session (object): SQLAlchemy database session (optional) Returns: response.Response: success message or database error """ try: for track in tracks: existing_rights_attributes = cls._get_rights_attributes_by_tuid( track['tuid'], session).with_for_update().all() cls._sync_rights_attributes( track['tuid'], existing_rights_attributes, track['track_attributes'], orchard_identity_id, session, change_source=track.get('change_source')) session.commit() return response.Response(status=200, message='success') except Exception as e: session.rollback() return response.create_error_response( code=error.TRACK_AUDIO_ATTRIBUTE_MODEL_ERROR, message=str(e)) @classmethod @mysql.db_session_wrap def sync_track_rights_attributes_edits(cls, tracks, session): """Sync track rights attributes edits. Args: tracks: The list of tuid / rights attribute combinations to set session (object): SQLAlchemy database session (optional) Returns: response.Response: success message or database error """ try: for track in tracks: existing_rights_attributes = cls._get_rights_attributes_edits_by_tuid( track['tuid'], session).with_for_update().all() cls._sync_rights_attributes_edits( track['tuid'], existing_rights_attributes, track['track_attributes'], session) session.commit() return response.Response(status=200, message='success') except Exception as e: session.rollback() return response.create_error_response( code=error.TRACK_RIGHTS_ATTRIBUTE_EDITS_MODEL_ERROR, message=str(e)) @classmethod def _get_rights_attributes_by_tuid(cls, tuid, session): return session.query(TrackRightsAttributes) \ .filter(TrackRightsAttributes.unique_track_id == tuid) \ .order_by(TrackRightsAttributes.rights_attribute_id) @classmethod def _get_rights_attributes_edits_by_tuid(cls, tuid, session): return session.query(TrackRightsAttributesEdits) \ .filter(TrackRightsAttributesEdits.unique_track_id == tuid) \ .order_by(TrackRightsAttributesEdits.rights_attribute_id) @classmethod def _sync_rights_attributes( cls, tuid, existing_rights_attributes, new_rights_attribute_ids, orchard_identity_id, session, change_source=None): """Sync rights attributes for a track. Args: tuid (int): The track primary key. existing_rights_attributes (list): Currently set rights attributes for this track new_rights_attribute_ids (list): List of rights attribute IDs to set the track to orchard_identity_id: The orchard identity id session (object): SQLAlchemy database session change_source: The source of the change (optional) """ models_to_delete = [ existing_rights_attribute for existing_rights_attribute in existing_rights_attributes if existing_rights_attribute.rights_attribute_id not in new_rights_attribute_ids] existing_rights_attribute_ids = [ existing_rights_attribute.rights_attribute_id for existing_rights_attribute in existing_rights_attributes] rights_attribute_ids_to_create = [ new_rights_attribute_id for new_rights_attribute_id in new_rights_attribute_ids if new_rights_attribute_id not in existing_rights_attribute_ids] for rights_attribute_id_to_create in rights_attribute_ids_to_create: new_model = TrackRightsAttributes( unique_track_id=tuid, rights_attribute_id=rights_attribute_id_to_create) log_entry = TrackRightsAttributesChangelog( unique_track_id=tuid, rights_attribute_id=rights_attribute_id_to_create, user_uuid=orchard_identity_id, change_source=change_source, action='insert') session.add(new_model) session.add(log_entry) for model_to_delete in models_to_delete: log_entry = TrackRightsAttributesChangelog( unique_track_id=tuid, rights_attribute_id=model_to_delete.rights_attribute_id, user_uuid=orchard_identity_id, change_source=change_source, action='delete') session.delete(model_to_delete) session.add(log_entry) @classmethod def _sync_rights_attributes_edits( cls, tuid, existing_rights_attributes, new_rights_attribute_ids, session): """Sync rights attributes edits for a track. Args: tuid (int): The track primary key. existing_rights_attributes (list): Currently set rights attributes for this track new_rights_attribute_ids (list): List of rights attribute IDs to set the track to session (object): SQLAlchemy database session """ models_to_delete = [ existing_rights_attribute for existing_rights_attribute in existing_rights_attributes if existing_rights_attribute.rights_attribute_id not in new_rights_attribute_ids] existing_rights_attribute_ids = [ existing_rights_attribute.rights_attribute_id for existing_rights_attribute in existing_rights_attributes] rights_attribute_ids_to_create = [ new_rights_attribute_id for new_rights_attribute_id in new_rights_attribute_ids if new_rights_attribute_id not in existing_rights_attribute_ids] for rights_attribute_id_to_create in rights_attribute_ids_to_create: new_model = TrackRightsAttributesEdits( unique_track_id=tuid, rights_attribute_id=rights_attribute_id_to_create) session.add(new_model) for model_to_delete in models_to_delete: session.delete(model_to_delete) @classmethod @mysql.db_session_wrap def write_rights_attribute_suggestions( cls, unique_track_id, suggestions, user_uuid, review_queue_id, session=None ): """Insert a suggestion record for a track's suggested rights attributes. Args: unique_track_id (int): The track primary key. suggestions (list): The full suggestion items from the model. user_uuid (str): The user UUID from Orchard-Identity-Id header. review_queue_id (int): The review queue ID from the request. session (object): SQLAlchemy database session (optional) """ session.add(TrackRightsAttributeSuggestions( unique_track_id=unique_track_id, suggestions=suggestions, user_uuid=user_uuid, review_queue_id=review_queue_id, )) @classmethod @mysql.db_session_wrap def bulk_delete_track_rights_attributes(cls, tuids, session): """Delete track rights attributes for multiple tracks. Args: tuids (list): The track primary keys. session (object): SQLAlchemy database session """ rows_to_delete = session.query( TrackRightsAttributeSuggestions ).filter( TrackRightsAttributeSuggestions.unique_track_id.in_(tuids) ).all() for row in rows_to_delete: session.delete(row) rows_to_delete = session.query( TrackRightsAttributesEdits ).filter( TrackRightsAttributesEdits.unique_track_id.in_(tuids) ).all() for row in rows_to_delete: session.delete(row) rows_to_delete = session.query( TrackRightsAttributesChangelog ).filter( TrackRightsAttributesChangelog.unique_track_id.in_(tuids) ).all() for row in rows_to_delete: session.delete(row) rows_to_delete = session.query( TrackRightsAttributes ).filter( TrackRightsAttributes.unique_track_id.in_(tuids) ).all() for row in rows_to_delete: session.delete(row)