"""Track performer handler.""" from operator import itemgetter from switchboard_consumer.constants import system from switchboard_consumer.constants.track_performer_roles import ( DEFAULT_PERFORMER_ROLE_ID, FEATURED_PERFORMER_ROLES, FEATURED_TYPE, NON_FEATURED_PERFORMER_ROLES, NON_FEATURED_TYPE, PERFORMER_ROLE_MAPPING, PRIMARY_PERFORMER_ROLES, PRIMARY_TYPE) from switchboard_consumer.formatters.artist import format_performer from switchboard_consumer.utils.message import get_system_local_id class TrackPerformerHandler: """"Handle performer finding and formatting.""" def __init__(self, track_data, logger): """Create a TrackPerformerHandler instance. Args: track_data: dict logger: Logger instance """ self.track_data = track_data self.log_fields = {'isrc': self.track_data['isrc']} self.display_artists = track_data.get('displayArtists', []) self.primary_performers = self.filter_participants_by_role_mapping( self.display_artists, PRIMARY_PERFORMER_ROLES) self.featured_performers = self.filter_participants_by_role_mapping( self.display_artists, FEATURED_PERFORMER_ROLES, self.primary_performers) self.non_featured_performers = \ self.filter_participants_by_role_mapping( self.display_artists, NON_FEATURED_PERFORMER_ROLES) self.performance_contributors = \ self.filter_participants_by_role_mapping( track_data.get('contributors', []), list(PERFORMER_ROLE_MAPPING)) self.performers = [] self.logger = logger def process(self): """Process performers from track data.""" self.logger.info('Processing track performers', self.log_fields) for contributor in self.performance_contributors: local_id = get_system_local_id( contributor['participant'], system.SONY) # If contributor exist as display artists with primary role if self.filter_participants_by_local_id( self.primary_performers, local_id): # Remove the # Append participant as primary performer self.primary_performers.append(contributor) continue # If contributor exist as display artists with featured role if self.filter_participants_by_local_id( self.featured_performers, local_id): # Append participant as valid featuring performer self.featured_performers.append(contributor) continue # This participant was not found as a primary or featured self.non_featured_performers.append(contributor) self.performers.extend(self.format_performers( self.primary_performers, PRIMARY_TYPE)) self.performers.extend(self.format_performers( self.featured_performers, FEATURED_TYPE)) self.performers.extend(self.format_performers( self.non_featured_performers, NON_FEATURED_TYPE)) self.performers = self.dedupe_performers() return self.rollup_performers() def filter_participants_by_role_mapping(self, participants, roles, filter_to=[]): """Find participants by roles. Args: participants: list of participants logger: list of role mappings filter_to: optional list to check for dupes and filter into """ filtered_participants = [] for participant in participants: members = participant['participant'].get('members', []) filtered_members = [] for member in members: if member['role'] in roles: local_id = get_system_local_id( member['participant'], system.SONY) if self.filter_participants_by_local_id( filter_to, local_id): filter_to.append(member) else: filtered_members.append(member) if filtered_members: filtered_participants.extend(filtered_members) elif participant['role'] in roles: local_id = get_system_local_id( participant['participant'], system.SONY) if self.filter_participants_by_local_id( filter_to, local_id): filter_to.append(participant) else: filtered_participants.append(participant) return filtered_participants def filter_participants_by_local_id(self, participants, local_id): """Find participants by local id.""" filtered_participants = [] for participant in participants: members = participant['participant'].get('members', []) for member in members: found_local_id = get_system_local_id(member['participant'], system.SONY) if found_local_id['localId'] == local_id['localId']: filtered_participants.append(member) found_local_id = get_system_local_id(participant['participant'], system.SONY) if found_local_id['localId'] == local_id['localId']: filtered_participants.append(participant) return filtered_participants def format_performers(self, performers, performer_type): """Format a list of performers to valid graphql input.""" formatted_performers = [] for performer in performers: formatted_performers.append(format_performer( performer['participant']['name'], PERFORMER_ROLE_MAPPING.get(performer['role'], DEFAULT_PERFORMER_ROLE_ID), performer_type )) return formatted_performers def dedupe_performers(self): """Dedupe performers.""" deduped_performers = [ dict(deduped_performer) for deduped_performer in set( tuple(performer.items()) for performer in self.performers) ] return deduped_performers def rollup_performers(self): """Rollup performers with more specific roles and remove default roles.""" # noqa performers_with_specfic_roles = [ performer['name'] for performer in self.performers if not performer['roleId'] == DEFAULT_PERFORMER_ROLE_ID ] valid_performers = [] for performer in self.performers: if (performer['roleId'] == DEFAULT_PERFORMER_ROLE_ID and # noqa performer['name'] not in performers_with_specfic_roles): valid_performers.append(performer) elif(performer['roleId'] != DEFAULT_PERFORMER_ROLE_ID): valid_performers.append(performer) valid_performers.sort(key=itemgetter('name')) return valid_performers