"""Main Handler. In this document (Legend): - `artist(s)`: represent `participation(s)` in the Graph; `artist(s)` in OA - `artist(s)` occur on a release and a track level. (Track-level only here) - `performer(s)`: represent `performer(s)` in the Graph; `performer(s)` in OA - `performer(s)` are track-level only. - `participants` represents the aggregation of `artists` and `performers` """ from typing import Dict from bulk_metadata_ingester_common.models.bulk_release import ( BulkRelease ) from bulk_metadata_ingester_common.utils.jitter import jitter from bulk_metadata_ingester_common.utils.logging import get_current_logger from bulk_metadata_ingester_common.utils.release_utils import ( get_release_track_list) import config from config import graphql_gateway from ddex_ingester_common.lambda_exceptions import SetTrackMetadataException from lambdacommon.graphql.graphql import GraphQLError from utils.track_utils import ( create_tracks, delete_tracks, format_create_track_data, get_all_roles, get_orchard_tracks, get_track_participants ) def handler(event: Dict, context: object) -> Dict: """Lambda Entrypoint.""" key = event.get('key') bucket = event.get('bucket') item_index = event.get('item_index') correlation_id = event.get('correlation_id') release = event.get('release', {}) track_list = event.get('tracks', {}) logger = get_current_logger( config.ENVIRONMENT, config.LAMBDA_NAME, logging_level=config.LOGGING_LEVEL, correlation_id=correlation_id) # Jitter calls - Sleep for randomness jitter(logger) graphql_gateway.set_headers( { 'Orchard-User-Id': config.OA_USER, 'Correlation-Id': correlation_id } ) # Log lambda begins message logger.info(f'set_tracks received: {event}') # Get single release from JSON release_track_list = get_release_track_list(bucket, key, item_index) # Move JSON to model modeled_release = BulkRelease(json_release_rows=release_track_list) # DEBUG logger.info(f'Modeled release from payload: {modeled_release}') # FIXME remove for debug only for track_key, track_value in modeled_release.tracks.items(): logger.info(f'track_key: {track_key} | tuid: {track_value.tuid}') # Rehydrate passed values modeled_release.rehydrate(release, track_list) # DEBUG logger.info(f'Modeled release after rehydrate: {modeled_release}') # FIXME remove for debug only for track_key, track_value in modeled_release.tracks.items(): logger.info(f'track_key: {track_key} | tuid: {track_value.tuid}') modeled_release = set_tracks(event, logger, modeled_release) # DEBUG logger.info(f'Modeled release after set_tracks(): {modeled_release}') # FIXME remove for debug only for track_key, track_value in modeled_release.tracks.items(): logger.info(f'track_key: {track_key} | tuid: {track_value.tuid}') # Get all passed and updated fields updates = modeled_release.get_modified() result = { **event, 'release': { **updates['release'], }, 'tracks': { **updates['tracks'] } } return result def set_tracks(event, logger, modeled_release): """Set the track metadata.""" # Pull vars for local use upc = modeled_release.upc product_id = modeled_release.product_id product_genre = modeled_release.genre product_subgenre = modeled_release.subgenre track_list = modeled_release.tracks # Get participant list from context all_participants = modeled_release.participants # NOT USED - Kept for label participants / Extended Performer Fields # vendor_id = modeled_release.vendor_id # subaccount_id = modeled_release.subaccount_id or 0 try: # Get list of existing tracks on product orchard_tracks = get_orchard_tracks(upc, logger) tuids_to_delete = [] track_payload = [] # Delete existing tracks for orchard_track in orchard_tracks: orchard_track_tuid = int(orchard_track['tuid']) tuids_to_delete.append(orchard_track_tuid) delete_tracks(product_id, tuids_to_delete, logger) # Loop through tracks and make payload for _, track in track_list.items(): # Get all roles on the track all_track_roles = get_all_roles( track, product_genre, product_subgenre, logger ) participants = get_track_participants( track, all_participants, all_track_roles, logger ) # Format the payload body = format_create_track_data(participants, upc, track) # Add create track payload to track list track_payload.append(body) # Format full create tracklist payload payload = { 'create': { 'productId': product_id, 'tracks': track_payload, } } # Debug payload logger.info(f'Calling saveTracks with payload: {payload}') # Create the product result = create_tracks(event, modeled_release, payload, logger) # Parse track-level results # TODO: Track-level error parsing for output CSV reporting for t in result: track_key = '{}_{}_{}'.format( t['isrc'], t['volumeNumber'], t['trackNumber']) # TODO - DEBUG - This is to troubleshoot the SFN # get some logging try: # Store track id so it can be used later modeled_release.tracks[track_key].tuid = t['tuid'] except AttributeError: tuid = t['tuid'] old_tuid = modeled_release.tracks[track_key].tuid msg = f'Could not set tuid: {tuid} for {track_key}. ' \ f'tuid is already set to "{old_tuid}".' logger.error(msg) except GraphQLError as err: raise SetTrackMetadataException(f'Graphql error: {str(err)}') from err except Exception as exp: raise SetTrackMetadataException( f'Error creating tracks - {exp}') from exp return modeled_release