"""Participant Handlers.""" from flask import g as flask_g from flask import request from marshmallow import ValidationError from owsrequest import request as owsrequest from owsresponse import response from owsresponse.adaptors.flask import flaskify from participant.api import app from participant.constants import error from participant.constants import service as service_constants from participant.logic import email, label_participant from participant.schemas.input.contact import Contact from participant.schemas.input.create_label_participant import ( CreateLabelParticipantSchema, ) from participant.schemas.input.create_relationship import CreateRelationship from participant.schemas.input.delete_relationship import DeleteRelationship from participant.schemas.input.lookup_label_participants import LookupByUuids from participant.schemas.input.search_label_participant import ( SearchLabelParticipantSchema, ) from participant.schemas.input.update_artist_name import ( UpdateArtistName, UpdateLabelParticipantAndArtistName, MergeLabelParticipantsAndArtists, ) from participant.schemas.input.update_relationship import UpdateRelationship from participant.utils import exception, json_encoder from participant.utils.handler import validate_request_data # TODO remove/modify this route once GraphQL is updated to point to # the new label-participant route @app.route('/participants/', methods=['GET']) @app.route('/label-participants/', methods=['GET']) def get_label_participant_by_id(label_participant_id): """Find Label Participant by id. Args: label_participant_id (int): The ID of the label participant. """ return flaskify( label_participant.get_label_participant_by_id(label_participant_id), encoder=json_encoder.JSONNeo4jEncoder, ) @app.route('/participants/search', methods=['GET']) @app.route('/label-participants/search', methods=['GET']) def search_label_participant(): """Find Label Participant by name or name substring. Args: name (str): Name to search for. vendor_id (int): vendor_id to filter by. subaccount_id (int): subaccount_id to filter by. Returns: flask.Response: Response containing all matching participant nodes. """ name = request.args.get('name') vendor_id = request.args.get('vendor_id') subaccount_id = request.args.get('subaccount_id') role = request.args.get('role') params = dict(name=name, vendor_id=vendor_id, subaccount_id=subaccount_id) try: cleaned = SearchLabelParticipantSchema().load(params) except ValidationError as err: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=err.messages ) ) return flaskify( label_participant.search_label_participant(cleaned, role), encoder=json_encoder.JSONNeo4jEncoder, ) @app.route('/participants', methods=['POST']) @app.route('/label-participants', methods=['POST']) @validate_request_data(schema=CreateLabelParticipantSchema()) def create_label_participant(): """Create a new Label Participant record. Args: name (str): Label Participant name. vendor_id (int): Label Participant's vendor id. subaccount_id (int): Label Participant subaccount id. spotify_id (str): Spotify identifier. Optional. apple_music_id (str): Apple Music identifier. Optional. """ data = request.get_json() cleaned = CreateLabelParticipantSchema().load(data) return flaskify( label_participant.create_label_participant(**cleaned), encoder=json_encoder.JSONNeo4jEncoder, ) @app.route('/label-participants/relationship', methods=['POST']) def create_relationship(): """Create relationship.""" data = request.get_json() try: cleaned = CreateRelationship().load(data) except ValidationError as err: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=err.messages ) ) return flaskify( label_participant.create_relationship( cleaned['from_node'], cleaned['to_node'], cleaned['relationship'] ), encoder=json_encoder.JSONNeo4jEncoder, ) @app.route('/label-participants/relationship', methods=['PUT']) def update_relationship(): """Update relationship.""" data = request.get_json() try: cleaned = UpdateRelationship().load(data) except ValidationError as err: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=err.messages ) ) return flaskify( label_participant.update_relationship( cleaned['from_node'], cleaned['to_node'], cleaned['relationship'] ), encoder=json_encoder.JSONNeo4jEncoder, ) @app.route('/label-participants/relationship', methods=['DELETE']) def delete_relationship(): """Delete relationship.""" data = request.get_json() try: cleaned = DeleteRelationship().load(data) except ValidationError as err: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=err.messages ) ) return flaskify( label_participant.delete_relationship( cleaned['from_node'], cleaned['to_node'], cleaned['relationship'] ), encoder=json_encoder.JSONNeo4jEncoder, ) @app.route('/contact', methods=['POST']) def contact(): """Report an issue.""" ows_account_response = owsrequest.get( service_constants.OWS_ACCOUNT, service_constants.OWS_ACCOUNT_VENDOR_DOCUMENT_RESOURCE.format( vendor_id=flask_g.vendor_id ), ) if ows_account_response.status_code != 200: exception.raise_exception(Exception, ows_account_response.status_code) return label_manager_email = ows_account_response.json().get('assigned_to_email') data = Contact().load(request.json) participant_id = data.get('participant_id') participant_name = data.get('participant_name') product_id = data.get('product_id') product_name = data.get('product_name') upc = data.get('upc') message = data.get('message') current_artist_name = data.get('current_artist_name') new_artist_name = data.get('new_artist_name') email.send( notification_email=label_manager_email, participant_id=participant_id, participant_name=participant_name, vendor_id=flask_g.vendor_id, subaccount_id=flask_g.subaccount_id, message=message, product_id=product_id, product_name=product_name, upc=upc, current_artist_name=current_artist_name, new_artist_name=new_artist_name, ) return '', 200 @app.route('/artist-info//rename', methods=['PUT']) def update_artist_name(artist_id): """Update artist name.""" data = request.get_json() try: artist_data = UpdateArtistName().load(data) return flaskify(label_participant.update_artist_name(artist_id, artist_data)) except ValidationError as err: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=err.messages ) ) @app.route('/lookup/label-participants/uuids/tenant-hierarchy/', methods=['POST']) def lookup_label_participants_by_uuids(): """Dataloader-style endpoint for looking up label participants by uuids.""" request_payload = LookupByUuids().load(request.get_json()) uuids = request_payload['uuids'] if not uuids: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=error.ERROR_MESSAGE_INVALID_USAGE, ) ) return flaskify(label_participant.lookup_participants_hierarchy_by_uuids(uuids)) @app.route('/label-participant//rename', methods=['PUT']) def update_label_participant_and_artist_name(label_participant_uuid): """Update label participant and artist info artist name.""" data = request.get_json() try: artist_data = UpdateLabelParticipantAndArtistName().load(data) return flaskify( label_participant.update_lp_and_artist_name( label_participant_uuid, artist_data ) ) except ValidationError as err: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=err.messages ) ) @app.route( '/label-participant//product-tracks', methods=['GET'] ) def get_products_and_tracks_for_label_participant(label_participant_uuid): """GET products and tracks for label participant.""" try: return flaskify( label_participant.get_products_and_tracks_for_lp(label_participant_uuid) ) except ValidationError as err: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=err.messages ) ) @app.route('/label-participant/merge', methods=['PUT']) def merge_label_participants_and_artists(): """Merge label participants and artists.""" data = request.get_json() try: artist_data = MergeLabelParticipantsAndArtists().load(data) return flaskify(label_participant.merge_lp_and_artist_name(artist_data)) except ValidationError as err: return flaskify( response.create_error_response( code=error.ERROR_CODE_INVALID_USAGE, message=err.messages ) )