"""Artist Updates Model. This model represents an artist name updates models """ from datetime import datetime, timezone from flask import g import participant.constants.label_participant_queries as q import sqlalchemy from owsresponse import response from participant.connectors import mysql from participant.constants import error as error_consts from participant.models import base as base_models from participant.models.ows import ows_artist as ows_artist_model from participant.models.sql import artist_select from sqlalchemy import func, text class ArtistInfo(mysql.BaseModel): """Artist Info model.""" __tablename__ = 'artist_info' artist_id = sqlalchemy.Column( 'artist_id', sqlalchemy.Integer, primary_key=True, autoincrement=True, ) vendor_id = sqlalchemy.Column('vendor_id', sqlalchemy.Integer, nullable=False) name = sqlalchemy.Column('name', sqlalchemy.VARCHAR(255), nullable=False) class ReleaseArtist(mysql.BaseModel): """Release Artist model.""" __tablename__ = 'release_artist' release_artist_id = sqlalchemy.Column( 'release_artist_id', sqlalchemy.Integer, primary_key=True, autoincrement=True, ) artist_name = sqlalchemy.Column( 'artist_name', sqlalchemy.VARCHAR(255), nullable=False ) upc = sqlalchemy.Column('upc', sqlalchemy.BigInteger, nullable=False) release_id = sqlalchemy.Column('release_id', sqlalchemy.Integer, nullable=False) artist_info_id = sqlalchemy.Column( 'artist_info_id', sqlalchemy.Integer, nullable=True ) class TrackArtist(mysql.BaseModel): """Track Artist model.""" __tablename__ = 'track_artist' track_artist_id = sqlalchemy.Column( 'id', sqlalchemy.Integer, primary_key=True, autoincrement=True, ) name = sqlalchemy.Column('name', sqlalchemy.VARCHAR(255), nullable=False) track_id = sqlalchemy.Column('track_id', sqlalchemy.Integer, nullable=False) artist_info_id = sqlalchemy.Column( 'artist_info_id', sqlalchemy.Integer, nullable=True ) class TrackWriter(mysql.BaseModel): """Track Writer model.""" __tablename__ = 'track_writer' track_writer_id = sqlalchemy.Column( 'track_writer_id', sqlalchemy.Integer, primary_key=True, autoincrement=True, ) writer_name = sqlalchemy.Column( 'writer_name', sqlalchemy.VARCHAR(255), nullable=False ) unique_track_id = sqlalchemy.Column( 'unique_track_id', sqlalchemy.Integer, nullable=False ) upc = sqlalchemy.Column('upc', sqlalchemy.BigInteger, nullable=False) artist_info_id = sqlalchemy.Column( 'artist_info_id', sqlalchemy.Integer, nullable=True ) class Releases(mysql.BaseModel): """Releases model.""" __tablename__ = 'releases' release_id = sqlalchemy.Column( 'release_id', sqlalchemy.Integer, primary_key=True, autoincrement=True, ) upc = sqlalchemy.Column('upc', sqlalchemy.BigInteger, nullable=False) artist_id = sqlalchemy.Column('artist_id', sqlalchemy.Integer, nullable=False) project_id = sqlalchemy.Column('project_id', sqlalchemy.Integer, nullable=False) last_updated = sqlalchemy.Column('last_updated', sqlalchemy.DateTime, nullable=True) class Track(mysql.BaseModel): """Track model.""" __tablename__ = 'track' id = sqlalchemy.Column( 'id', sqlalchemy.Integer, primary_key=True, autoincrement=True, ) release_id = sqlalchemy.Column('release_id', sqlalchemy.Integer, nullable=False) class ArtistYoutubeDeliverySettings(mysql.BaseModel): """Artist Youtube delivery settings model.""" __tablename__ = 'artist_yt_delivery_settings' id = sqlalchemy.Column( 'id', sqlalchemy.Integer, primary_key=True, autoincrement=True, ) artist_id = sqlalchemy.Column('artist_id', sqlalchemy.Integer, nullable=False) class Project(mysql.BaseModel): """Project model.""" __tablename__ = 'project' project_id = sqlalchemy.Column( 'project_id', sqlalchemy.Integer, primary_key=True, autoincrement=True, ) vendor_id = sqlalchemy.Column('vendor_id', sqlalchemy.Integer, nullable=False) artist_id = sqlalchemy.Column('artist_id', sqlalchemy.Integer, nullable=False) def get_artist_info_by_artist_name(artist_name, vendor_id): """Get artist record by artist name. Args: artist_name (str): Artist name vendor_id (int): Vendor id Returns: ArtistInfo | None: artist info object """ with mysql.ar_db_session(read_only=True) as session: return ( session.query(ArtistInfo) .filter( ArtistInfo.vendor_id == vendor_id, ArtistInfo.name.collate("utf8mb4_bin") == artist_name, ) .first() ) def update_artist_name(artist_id, new_artist_name): """Update Artist name. Args: artist_id (int): artist info identifier new_artist_name (str): artist name Returns: dict: artist info object """ g.log.info( f'Using update_artist_name with artist_id: {artist_id}, ' f'new_artist_name: {new_artist_name}' ) artist_info_by_id = ows_artist_model.get_artist_info_by_artist_id(artist_id) if not artist_info_by_id: g.log.warning( f'Artist not found in update_artist_name with artist_id: {artist_id}, ' f'new_artist_name: {new_artist_name}' ) return artist_info_by_id current_artist_name = artist_info_by_id.message.get('name') vendor_id = artist_info_by_id.message.get('vendor_id') artist_info_by_name_and_vendor = get_artist_info_by_artist_name( new_artist_name, vendor_id ) if artist_info_by_name_and_vendor: if artist_info_by_name_and_vendor.artist_id != artist_id: g.log.warning( f'Duplicate artist name in update_artist_name with artist_id: ' f'{artist_id}, vendor_id: {vendor_id}, ' f'new_artist_name: {new_artist_name}' ) return response.create_error_response( code=error_consts.ERROR_CODE_DUPLICATE_ARTIST, message=error_consts.ERROR_DUPLICATE_ARTIST_NAME, status=response.status.BAD_REQUEST, ) update_artist_resp = ows_artist_model.update_artist_info_by_artist_id( artist_id, new_artist_name ) if not update_artist_resp: g.log.error( f'Failed update_artist_info_by_artist_id in update_artist_name with ' f'artist_id: {artist_id}, new_artist_name: {new_artist_name}' ) return update_artist_resp rename_release_artist(current_artist_name, vendor_id, new_artist_name, artist_id) g.log.info( f'Using rename_release_artist in update_artist_name with artist_id: ' f'{artist_id}, vendor_id: {vendor_id}' ) rename_track_artist(current_artist_name, vendor_id, new_artist_name, artist_id) g.log.info( f'Using rename_track_artist in update_artist_name with artist_id: ' f'{artist_id}, vendor_id: {vendor_id}' ) rename_track_writer(current_artist_name, vendor_id, new_artist_name, artist_id) g.log.info( f'Using rename_track_writer in update_artist_name with artist_id: ' f'{artist_id}, vendor_id: {vendor_id}' ) rename_lp_node = rename_label_participant(artist_id, vendor_id, new_artist_name) if not rename_lp_node: g.log.error( f'Failed rename_label_participant in update_artist_name with ' f'artist_id: {artist_id}, vendor_id: {vendor_id}, ' f'new_artist_name: {new_artist_name}' ) return rename_lp_node update_last_updated_for_affected_products(artist_id) return response.Response(status=200, message='Artist name is updated successfully.') def rename_release_artist( current_artist_name, vendor_id, new_artist_name, artist_id=None, current_artist_id=None, ): """Update release_artist artist name. Args: current_artist_name (str): current artist name vendor_id (int): vendor id new_artist_name (str): new artist name artist_id (int): artist id current_artist_id (int): current artist id in case of merge request Returns: response.Response: An HTTP response with status code 200. """ params = { 'artist_name': current_artist_name, 'vendor_id': vendor_id, 'new_artist_name': new_artist_name, 'artist_id': artist_id, 'current_artist_id': current_artist_id, } with mysql.ar_db_session() as session: session.execute(text(artist_select.UPDATE_RELEASE_ARTIST), params) session.commit() return response.Response(status=200) def rename_track_artist( current_artist_name, vendor_id, new_artist_name, artist_id=None, current_artist_id=None, ): """Update track_artist artist name.""" params = { 'artist_name': current_artist_name, 'vendor_id': vendor_id, 'new_artist_name': new_artist_name, 'artist_id': artist_id, 'current_artist_id': current_artist_id, } with mysql.ar_db_session() as session: session.execute(text(artist_select.UPDATE_TRACK_ARTIST), params) session.commit() return response.Response(status=200) def rename_track_writer( current_artist_name, vendor_id, new_artist_name, artist_id=None, current_artist_id=None, ): """Update track_writer artist name. Args: current_artist_name (str): artist name before update vendor_id (int): vendor id new_artist_name (str): new artist name artist_id (int): artist id current_artist_id (int): current artist id Returns: response.Response: An HTTP response with status code 200. """ params = { 'artist_name': current_artist_name, 'vendor_id': vendor_id, 'new_artist_name': new_artist_name, 'artist_id': artist_id, 'current_artist_id': current_artist_id, } with mysql.ar_db_session() as session: session.execute(text(artist_select.UPDATE_TRACK_WRITER), params) session.commit() return response.Response(status=200) def merge_artist(current_artist_id, target_artist_id, artist_name): """Merge Artists. Args: current_artist_id (int): artist_id to merge from target_artist_id (int): artist id to merge into artist_name (str): final artist name Returns: response object """ g.log.info( f'Using merge_artist with current_artist_id: {current_artist_id}, ' f'target_artist_id: {target_artist_id}, artist_name: {artist_name}' ) try: artist_info_by_id = ows_artist_model.get_artist_info_by_artist_id( target_artist_id ) if not artist_info_by_id: g.log.warning( f'Target artist not found for merge with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}, ' f'artist_name: {artist_name}' ) return response.create_not_found_response('Target artist not found.') vendor_id = artist_info_by_id.message.get('vendor_id') current_artist_info_by_id = ows_artist_model.get_artist_info_by_artist_id( current_artist_id ) if not current_artist_info_by_id: g.log.warning( f'Current artist not found for merge with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}, ' f'artist_name: {artist_name}' ) return response.create_not_found_response('Current artist not found.') current_artist_name = current_artist_info_by_id.message.get('name') g.log.info( f'Using merge_artist fetched artist info with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}, ' f'vendor_id: {vendor_id}, current_artist_name: {current_artist_name}, ' f'artist_name: {artist_name}' ) rename_release_artist( current_artist_name, vendor_id, artist_name, target_artist_id, current_artist_id, ) g.log.info( f'Using rename_release_artist with current_artist_id: {current_artist_id}, ' f'target_artist_id: {target_artist_id}, vendor_id: {vendor_id}' ) rename_track_artist( current_artist_name, vendor_id, artist_name, target_artist_id, current_artist_id, ) g.log.info( f'Using rename_track_artist with current_artist_id: {current_artist_id}, ' f'target_artist_id: {target_artist_id}, vendor_id: {vendor_id}' ) rename_track_writer( current_artist_name, vendor_id, artist_name, target_artist_id, current_artist_id, ) g.log.info( f'Using rename_track_writer with current_artist_id: {current_artist_id}, ' f'target_artist_id: {target_artist_id}, vendor_id: {vendor_id}' ) reassign_artist_for_project(current_artist_id, target_artist_id) g.log.info( f'Using reassign_artist_for_project with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}' ) reassign_artist_for_product(current_artist_id, target_artist_id) g.log.info( f'Using reassign_artist_for_product with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}' ) merge_lp_resp = merge_label_participant( current_artist_id, target_artist_id, vendor_id, artist_name ) if not merge_lp_resp: g.log.error( f'Failed merge_label_participant with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}, ' f'vendor_id: {vendor_id}' ) return response.create_not_found_response( 'Could not merge label participant nodes.' ) g.log.info( f'Using merge_label_participant with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}, ' f'vendor_id: {vendor_id}' ) remove_all_artist_id_references(current_artist_id) g.log.info( f'Using remove_all_artist_id_references with current_artist_id: ' f'{current_artist_id}' ) update_artist_resp = ows_artist_model.update_artist_info_by_artist_id( target_artist_id, artist_name ) if not update_artist_resp: g.log.error( f'Failed update_artist_info_by_artist_id with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}, ' f'artist_name: {artist_name}' ) return response.create_not_found_response('Could not update target artist.') g.log.info( f'Using update_artist_info_by_artist_id with target_artist_id: ' f'{target_artist_id}, artist_name: {artist_name}' ) update_last_updated_for_affected_products(target_artist_id) g.log.info( f'Using update_last_updated_for_affected_products with ' f'target_artist_id: {target_artist_id}' ) g.log.info( f'Using merge_artist completed successfully with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}, ' f'vendor_id: {vendor_id}, artist_name: {artist_name}' ) return response.Response(status=200, message='Artist is merged successfully.') except Exception: g.log.exception( f'Unexpected error in merge_artist with current_artist_id: ' f'{current_artist_id}, target_artist_id: {target_artist_id}, ' f'artist_name: {artist_name}' ) return response.create_error_response( code=getattr( error_consts, 'ERROR_CODE_INTERNAL_SERVER_ERROR', 'INTERNAL_ERROR' ), message='Failed to merge artist due to an internal error.', status=500, ) def reassign_artist_for_project(current_artist_id, target_artist_id): """Re-assign artist for project. Args: current_artist_id (int): artist_id target_artist_id (int): artist id that has to updated with Returns: response object """ artist_select_param = {'artist_id': current_artist_id} with mysql.ar_db_session() as session: resp = session.execute( text(artist_select.SELECT_PROJECT_WITH_CURRENT_ARTIST_ID), artist_select_param, ).fetchall() if resp: project_ids = [p.project_id for p in resp] ( session.query(Project) .filter(Project.project_id.in_(project_ids)) .update( {Project.artist_id: target_artist_id}, synchronize_session=False ) ) session.commit() g.log.info( f'Updated project rows in reassign_artist_for_project with ' f'affected_count: {len(project_ids)}' ) return response.Response(status=200) g.log.info( f'No project rows found in reassign_artist_for_project with ' f'current_artist_id: {current_artist_id}' ) def reassign_artist_for_product(current_artist_id, target_artist_id): """Re-assign artist for products. Args: current_artist_id (int): artist_id target_artist_id (int): artist id that has to updated with Returns: response object """ artist_select_param = {'artist_id': current_artist_id} with mysql.ar_db_session() as session: resp = session.execute( text(artist_select.SELECT_PRODUCT_WITH_CURRENT_ARTIST_ID), artist_select_param, ).fetchall() if resp: product_ids = [r.release_id for r in resp] ( session.query(Releases) .filter(Releases.release_id.in_(product_ids)) .update( {Releases.artist_id: target_artist_id}, synchronize_session=False ) ) session.commit() g.log.info( f'Updated product rows in reassign_artist_for_product with ' f'affected_count: {len(product_ids)}' ) return response.Response(status=200) g.log.info( f'No product rows found in reassign_artist_for_product with ' f'current_artist_id: {current_artist_id}' ) def rename_label_participant(artist_id, vendor_id, new_artist_name): """Update label participant name. Args: artist_id (int): artist_id vendor_id (int): vendor id new_artist_name (str): new artist name Returns: response object """ search_lp_resp = base_models.get_node( q.get_label_participant_related_by_artist_info, vendor_id=vendor_id, artist_info_id=artist_id, ) if search_lp_resp: lp_uuid = search_lp_resp.get('uuid') normalized_artist_name = new_artist_name.replace(' ', '').lower() update_lp_node_resp = base_models.update_node( q.update_label_participant_name, uuid=lp_uuid, name=new_artist_name, modified_by='ows-participant/update_label_participant_name', modified_at=datetime.now(timezone.utc), normalized_name=normalized_artist_name, ) if not update_lp_node_resp: g.log.error( f'Failed update_node in rename_label_participant with artist_id: ' f'{artist_id}, vendor_id: {vendor_id}, lp_uuid: {lp_uuid}' ) return response.create_not_found_response('Could not update resource.') g.log.info( f'Updated label participant in rename_label_participant with ' f'artist_id: {artist_id}, vendor_id: {vendor_id}, lp_uuid: {lp_uuid}' ) return response.Response(status=200) def remove_all_artist_id_references(artist_id): """Remove all artist_id references. Args: artist_id (int): artist_id Returns: response object """ with mysql.ar_db_session() as session: session.query(ArtistYoutubeDeliverySettings).filter( ArtistYoutubeDeliverySettings.artist_id == artist_id ).delete() session.query(ArtistInfo).filter(ArtistInfo.artist_id == artist_id).delete() g.log.info(f'Completed remove_all_artist_id_references with artist_id: {artist_id}') return response.Response(status=200) def merge_label_participant( current_artist_id, master_artist_id, vendor_id, new_artist_name ): """Merge label participant nodes. Args: current_artist_id (int): current/child artist_id master_artist_id (int): master artist info artist id vendor_id (int): vendor id new_artist_name (str): new artist name Returns: response object """ get_current_artist_lp_node = base_models.get_node( q.get_label_participant_related_by_artist_info, vendor_id=vendor_id, artist_info_id=current_artist_id, ) current_lp_id = None if get_current_artist_lp_node: current_lp_id = get_current_artist_lp_node.get('id') get_master_artist_lp_node = base_models.get_node( q.get_label_participant_related_by_artist_info, vendor_id=vendor_id, artist_info_id=master_artist_id, ) master_lp_id = None master_lp_uuid = None if get_master_artist_lp_node: master_lp_id = get_master_artist_lp_node.get('id') master_lp_uuid = get_master_artist_lp_node.get('uuid') if current_lp_id and master_lp_id: merge_label_participant_node = base_models.update_node( q.merge_artist_nodes, current_lp_id=current_lp_id, master_lp_id=master_lp_id, ) if not merge_label_participant_node: g.log.error( f'Failed merge_artist_nodes in merge_label_participant with ' f'current_lp_id: {current_lp_id}, master_lp_id: {master_lp_id}' ) return response.create_not_found_response( 'Could not merge the artist nodes.' ) g.log.info( f'Merged artist nodes in merge_label_participant with ' f'current_lp_id: {current_lp_id}, master_lp_id: {master_lp_id}' ) if master_lp_id: normalized_artist_name = new_artist_name.replace(' ', '').lower() base_models.update_node( q.update_label_participant_name, uuid=master_lp_uuid, name=new_artist_name, modified_by='ows-participant/update_label_participant_name', modified_at=datetime.now(timezone.utc), normalized_name=normalized_artist_name, ) g.log.info( f'Updated master label participant name in merge_label_participant with ' f'master_lp_uuid: {master_lp_uuid}' ) return response.Response(status=200) def update_last_updated_for_affected_products(artist_id): """Update last_updated in releases table for given artist. Args: artist_id (int): artist info identifier Returns: response.Response object """ artist_select_param = {'artist_id': artist_id} with mysql.ar_db_session() as session: resp = session.execute( text(artist_select.SELECT_PRODUCT_WITH_CURRENT_ARTIST_ID), artist_select_param, ).fetchall() if resp: product_ids = [r.release_id for r in resp] ( session.query(Releases) .filter(Releases.release_id.in_(product_ids)) .update({Releases.last_updated: func.now()}, synchronize_session=False) ) session.commit() g.log.info( f'Updated last_updated rows in ' f'update_last_updated_for_affected_products with ' f'affected_count: {len(product_ids)}' ) return response.Response(status=200) g.log.info( f'No products found in update_last_updated_for_affected_products with ' f'artist_id: {artist_id}' ) def update_lp_and_artist_name(label_participant_uuid, new_artist_name): """Update Artist name in label participant and in art_relations. Args: label_participant_uuid (str): label participant uuid new_artist_name (str): artist name Returns: Response object """ get_artist_lp_node = base_models.get_node( q.get_label_participant_by_uuid, uuid=label_participant_uuid, ) if get_artist_lp_node: current_artist_name = get_artist_lp_node.get('name') vendor_id = get_artist_lp_node.get('vendorId') artist_info_by_name_and_vendor = get_artist_info_by_artist_name( current_artist_name, vendor_id ) if not artist_info_by_name_and_vendor: g.log.info( f'No artist_info found in update_lp_and_artist_name with ' f'label_participant_uuid: {label_participant_uuid}, ' f'current_artist_name: {current_artist_name}, vendor_id: {vendor_id}' ) rename_release_artist(current_artist_name, vendor_id, new_artist_name) rename_track_artist(current_artist_name, vendor_id, new_artist_name) rename_track_writer(current_artist_name, vendor_id, new_artist_name) return rename_label_participant_by_uuid(label_participant_uuid, new_artist_name) artist_info_id = artist_info_by_name_and_vendor.artist_id artist_info_by_new_artist_name = get_artist_info_by_artist_name( new_artist_name, vendor_id ) if artist_info_by_new_artist_name: if artist_info_by_new_artist_name.artist_id != artist_info_id: g.log.warning( f'Duplicate artist name in update_lp_and_artist_name with ' f'label_participant_uuid: {label_participant_uuid}, ' f'artist_info_id: {artist_info_id}, vendor_id: {vendor_id}, ' f'new_artist_name: {new_artist_name}' ) return response.create_error_response( code=error_consts.ERROR_CODE_DUPLICATE_ARTIST, message=error_consts.ERROR_DUPLICATE_ARTIST_NAME, status=response.status.BAD_REQUEST, ) rename_label_participant_by_uuid(label_participant_uuid, new_artist_name) rename_release_artist( current_artist_name, vendor_id, new_artist_name, artist_info_id ) rename_track_artist(current_artist_name, vendor_id, new_artist_name, artist_info_id) rename_track_writer(current_artist_name, vendor_id, new_artist_name, artist_info_id) update_artist_resp = ows_artist_model.update_artist_info_by_artist_id( artist_info_id, new_artist_name ) if not update_artist_resp: g.log.error( f'Failed update_artist_info_by_artist_id in update_lp_and_artist_name ' f'with artist_info_id: {artist_info_id}, ' f'new_artist_name: {new_artist_name}' ) return update_artist_resp update_last_updated_for_affected_products(artist_info_id) g.log.info( f'Using update_last_updated_for_affected_products in ' f'update_lp_and_artist_name with artist_info_id: {artist_info_id}' ) return response.Response(status=200, message='Artist name is updated successfully.') def rename_label_participant_by_uuid(uuid, new_artist_name): """Update label participant name by uuid. Args: uuid (str): uuid of label participant new_artist_name (str): new artist name Returns: response object """ normalized_artist_name = new_artist_name.replace(' ', '').lower() update_lp_node_resp = base_models.update_node( q.update_label_participant_name, uuid=uuid, name=new_artist_name, modified_by='ows-participant/update_label_participant_name', modified_at=datetime.now(timezone.utc), normalized_name=normalized_artist_name, ) if not update_lp_node_resp: g.log.error( f'Failed update_node in rename_label_participant_by_uuid with ' f'uuid: {uuid}, new_artist_name: {new_artist_name}' ) return response.create_not_found_response('Could not update resource.') g.log.info( f'Updated label participant in rename_label_participant_by_uuid with ' f'uuid: {uuid}' ) return response.Response(status=200) def rename_lp_by_name(artist_name, new_artist_name, vendor_id): """Update label participant by name. Args: artist_name (str): name of label participant new_artist_name (str): new artist name vendor_id (int): vendor id Returns: response object """ get_lp_node = base_models.get_node( q.get_label_participant_by_name, lp_name=artist_name, vendor_id=vendor_id ) if get_lp_node: lp_uuid = get_lp_node.get('uuid') normalized_artist_name = new_artist_name.replace(' ', '').lower() base_models.update_node( q.update_label_participant_name, uuid=lp_uuid, name=new_artist_name, modified_by='ows-participant/update_label_participant_name', modified_at=datetime.now(timezone.utc), normalized_name=normalized_artist_name, ) g.log.info( f'Updated label participant in rename_lp_by_name with ' f'artist_name: {artist_name}, lp_uuid: {lp_uuid}' ) return response.Response(status=200) g.log.info( f'No label participant found in rename_lp_by_name with ' f'artist_name: {artist_name}, vendor_id: {vendor_id}' ) def get_products_and_tracks_for_lp(lp_uuid): """Get products and tracks for label participant. Args: lp_uuid (str): label participant uuid. Returns: dict: object containing number of products and tracks """ get_artist_lp_node = base_models.get_node( q.get_label_participant_by_uuid, uuid=lp_uuid, ) if get_artist_lp_node: artist_name = get_artist_lp_node.get('name') vendor_id = get_artist_lp_node.get('vendorId') release_artists = get_products_for_artist(vendor_id, artist_name) track_artists = get_tracks_for_artist(vendor_id, artist_name) g.log.info( f'Completed get_products_and_tracks_for_lp with lp_uuid: {lp_uuid}, ' f'artist_name: {artist_name}, vendor_id: {vendor_id}, ' f'release_count: {release_artists}, track_count: {track_artists}' ) return response.Response( status=200, message={'release': release_artists, 'track': track_artists} ) def get_tracks_for_artist(vendor_id, artist_name): """Get number of tracks for the artist. Args: vendor_id (int): vendor id artist_name (str): artist name Returns: int: number of track records for the artist """ artist_select_param = { 'vendor_id': vendor_id, 'artist_name': artist_name, } tracks_count = 0 with mysql.ar_db_session() as session: tracks_count = len( session.execute( text(artist_select.SELECT_TRACKS_FOR_ARTIST), artist_select_param, ).fetchall() ) g.log.info( f'Completed get_tracks_for_artist with vendor_id: {vendor_id}, ' f'artist_name: {artist_name}, tracks_count: {tracks_count}' ) return tracks_count def get_products_for_artist(vendor_id, artist_name): """Return primary artist for products. Args: vendor_id (int): vendor id artist_name (str): artist name Returns: int: number of product records for the artist """ artist_select_param = { 'vendor_id': vendor_id, 'artist_name': artist_name, } products_count = 0 with mysql.ar_db_session() as session: products_count = len( session.execute( text(artist_select.SELECT_RELEASES_FOR_ARTIST), artist_select_param, ).fetchall() ) g.log.info( f'Completed get_products_for_artist with vendor_id: {vendor_id}, ' f'artist_name: {artist_name}, products_count: {products_count}' ) return products_count def merge_lp_and_artist_names(uuid_1, uuid_2, merged_artist_uuid): """Update Artist name in label participant and in art_relations. Args: uuid_1 (str): label participant uuid for artist 1 uuid_2 (str): label participant uuid for artist 2 merged_artist_uuid (str): merged artist label participant uuid Returns: Response object """ g.log.info( f'Using merge_lp_and_artist_names with uuid_1: {uuid_1}, ' f'uuid_2: {uuid_2}, merged_artist_uuid: {merged_artist_uuid}' ) """Fetch label participant node for merged i.e source artist """ get_merged_artist_lp_node = base_models.get_node( q.get_label_participant_by_uuid, uuid=merged_artist_uuid, ) if get_merged_artist_lp_node: merged_artist_name = get_merged_artist_lp_node.get('name') vendor_id = get_merged_artist_lp_node.get('vendorId') source_lp_id = get_merged_artist_lp_node.get('id') """Fetch artist_info object for merged i.e source artist """ artist_info_by_name_and_vendor = get_artist_info_by_artist_name( merged_artist_name, vendor_id ) if not artist_info_by_name_and_vendor: g.log.warning( f'Merged artist not found in merge_lp_and_artist_names with ' f'merged_artist_uuid: {merged_artist_uuid}, ' f'merged_artist_name: {merged_artist_name}, vendor_id: {vendor_id}' ) return response.create_error_response( code=error_consts.ERROR_CODE_INVALID_ARTIST_NAME, message=error_consts.ERROR_ARTIST_NOT_FOUND, status=response.status.BAD_REQUEST, ) merged_artist_id = artist_info_by_name_and_vendor.artist_id """ Find the Label participant uuid that has to merge """ if merged_artist_uuid != uuid_1: target_artist_uuid = uuid_1 else: target_artist_uuid = uuid_2 """Fetch label participant node for artist to merge i.e target artist """ get_artist_lp_node = base_models.get_node( q.get_label_participant_by_uuid, uuid=target_artist_uuid, ) if get_artist_lp_node: artist_name = get_artist_lp_node.get('name') vendor_id = get_artist_lp_node.get('vendorId') target_lp_id = get_artist_lp_node.get('id') """Fetch artist_info object for artist to merge i.e target artist """ target_artist_info_name_and_vendor = get_artist_info_by_artist_name( artist_name, vendor_id ) if not target_artist_info_name_and_vendor: g.log.warning( f'Target artist not found in merge_lp_and_artist_names with ' f'target_artist_uuid: {target_artist_uuid}, artist_name: {artist_name}, ' f'vendor_id: {vendor_id}' ) return response.create_error_response( code=error_consts.ERROR_CODE_INVALID_ARTIST_NAME, message=error_consts.ERROR_ARTIST_NOT_FOUND, status=response.status.BAD_REQUEST, ) target_artist_name = target_artist_info_name_and_vendor.name target_artist_id = target_artist_info_name_and_vendor.artist_id rename_release_artist( merged_artist_name, vendor_id, target_artist_name, target_artist_id, merged_artist_id, ) rename_track_artist( merged_artist_name, vendor_id, target_artist_name, target_artist_id, merged_artist_id, ) rename_track_writer( merged_artist_name, vendor_id, target_artist_name, target_artist_id, merged_artist_id, ) reassign_artist_for_project(merged_artist_id, target_artist_id) reassign_artist_for_product(merged_artist_id, target_artist_id) merge_nodes_by_id(source_lp_id, target_lp_id) remove_all_artist_id_references(merged_artist_id) update_last_updated_for_affected_products(target_artist_id) g.log.info( f'Completed merge_lp_and_artist_names with merged_artist_id: ' f'{merged_artist_id}, target_artist_id: {target_artist_id}, ' f'target_artist_name: {target_artist_name}' ) return response.Response(status=200, message='Artist is merged successfully.') def merge_nodes_by_id(source_lp_id, target_lp_id): """Merge label participant nodes. Args: source_lp_id (str): label participant uuid for artist to merge target_lp_id (str): label participant uuid for target artist Returns: Response object """ g.log.info( f'Using merge_nodes_by_id with source_lp_id: {source_lp_id}, ' f'target_lp_id: {target_lp_id}' ) merge_label_participant_node = base_models.update_node( q.merge_artist_nodes, current_lp_id=source_lp_id, master_lp_id=target_lp_id, ) if not merge_label_participant_node: g.log.error( f'Failed merge_artist_nodes in merge_nodes_by_id with ' f'source_lp_id: {source_lp_id}, target_lp_id: {target_lp_id}' ) return response.create_not_found_response('Could not merge the artist nodes.') g.log.info( f'Completed merge_nodes_by_id with source_lp_id: {source_lp_id}, ' f'target_lp_id: {target_lp_id}' ) return response.Response(status=200)