"""Artist Social Profile Model. This model represents the relationship between artist ids and social profile ids. There can be many artist_ids for the same artist. e.g. 'Lil Bob’ might have different artist IDs, on two different albums, but both should point to the same Facebook and Twitter IDs'. """ from itertools import groupby from oto import response from oto import status import sqlalchemy from sqlalchemy.sql import func from social_analytics.connectors import mysql from social_analytics.constants import error from social_analytics.models.social_profile import SocialProfile class ArtistSocialProfile(mysql.BaseModel): """Artist Social Profile model.""" __tablename__ = 'artist_social_profile' artist_id = sqlalchemy.Column(sqlalchemy.BIGINT, primary_key=True) social_profile_id = sqlalchemy.Column(sqlalchemy.BIGINT, primary_key=True) label_id = sqlalchemy.Column(sqlalchemy.BIGINT) created_date = sqlalchemy.Column(sqlalchemy.DateTime, default=func.now()) updated_date = sqlalchemy.Column(sqlalchemy.DateTime, onupdate=func.now()) created_by = sqlalchemy.Column(sqlalchemy.VARCHAR(45)) updated_by = sqlalchemy.Column(sqlalchemy.VARCHAR(45)) def to_dict(self): """Return the object as dictionary.""" return dict( artist_id=self.artist_id, social_profile_id=self.social_profile_id, label_id=self.label_id, created_date=str(self.created_date), updated_date=str(self.updated_date), created_by=self.created_by, updated_by=self.updated_by) @mysql.autosession() def get_artist_social_profiles(session): """ Return all the artist social profiles. Args: session (Session): the mysql session. Returns: response.Response: containing all the artist social profiles. """ rows = session.query(ArtistSocialProfile).all() results = [row.to_dict() for row in rows] if results: return response.Response({'items': results}) return response.create_not_found_response() @mysql.autosession() def get_linked_artist_social_profile_ids(artist_ids, session): """Return all the artist social profiles for given artist ids. Args: artist_ids (list): A list of artist ids. session (Session): The mysql db session. Returns: response.Response: containing a list of artist ids. """ if not artist_ids: return response.create_error_response( status.BAD_REQUEST, error.ERROR_MESSAGE_BAD_PARAMS) rows = session.query( ArtistSocialProfile.artist_id).filter( ArtistSocialProfile.artist_id.in_(artist_ids)).all() if rows: ids = [result.artist_id for result in rows] return response.Response({'items': ids}) return response.create_not_found_response() @mysql.autosession() def get_artist_social_profiles_by_artist_id(artist_id, session): """ Return all the artist social profiles for a given artist_id. Args: artist_id (str): the artist id for which to query artist social profiles. session (Session): the mysql session. Returns: response.Response: containing the artist social profiles with artist_id. """ if not artist_id: return response.create_error_response( status.BAD_REQUEST, error.ERROR_MESSAGE_BAD_PARAMS) rows = session.query( ArtistSocialProfile).filter(ArtistSocialProfile.artist_id == artist_id) results = [row.to_dict() for row in rows] if results: return response.Response({'items': results}) return response.create_not_found_response() @mysql.autosession() def create_artist_social_profile(data, session): """ Create a new Artist Social Profile. Args: data (dict): the data from which to create the artist social profile. session (Session): the mysql session. Returns: response.Response: containing the created artist social profile dict. """ if not data: return response.create_error_response( status.BAD_REQUEST, error.ERROR_MESSAGE_EMPTY_BODY) artist_social_profile = ArtistSocialProfile(**data) session.add(artist_social_profile) session.commit() return response.Response(artist_social_profile.to_dict()) @mysql.autosession() def get_social_profile_ids_by_label_id(label_id, session): """Return all social_profile_ids for a label_id. This function fetches all artist social profiles linked to a label id. Each artist social profile is linked to a social profile. All those social profiles are fetched, and returned grouped by the artist_id to which they correspond. Args: label_id (int): the label id for which to query social profile ids. session (Session): the mysql session. Returns: response.Response: containing a list of artist_ids and the social_profiles for each artist_id. """ if not label_id: return response.create_error_response( status.BAD_REQUEST, error.ERROR_MESSAGE_MISSING_GRASS_HEADERS) rows = ( session.query(ArtistSocialProfile, SocialProfile) .join(SocialProfile, SocialProfile.social_profile_id == ArtistSocialProfile.social_profile_id) .filter(ArtistSocialProfile.label_id == label_id) .order_by(ArtistSocialProfile.artist_id.asc()) .all() ) items = [] for artist_id, artist_profile_group in groupby( rows, lambda row: row[0].artist_id): # group[1] goes for Profile data profiles = [group[1] for group in artist_profile_group] profile_dicts = [profile.to_dict() for profile in profiles] items.append( { 'artist_id': artist_id, 'social_profiles': profile_dicts } ) if items: return response.Response({'items': items}) return response.create_not_found_response() @mysql.autosession() def update_artist_social_profile(data, session): """ Update a Artist Social Profile. Args: data (dict): the data with which to create the artist social profile. session (Session): the mysql session. Returns: response.Response: containing the updated artist social profile dict. """ if not data: return response.create_error_response( status.BAD_REQUEST, error.ERROR_MESSAGE_EMPTY_BODY) artist_social_profile = ArtistSocialProfile(**data) updated = (session.query( ArtistSocialProfile).filter_by( social_profile_id=artist_social_profile.social_profile_id, artist_id=artist_social_profile.artist_id) .update(data)) return response.Response({'updated': updated}) @mysql.autosession() def get_artist_social_profile_by_artist_id_and_social_profile_id( artist_id, social_profile_id, session): """Get an artist social profile with artist_id and social_profile_id. Args: artist_id (int): the artist id social_profile_id (int): the social_profile_id session (Session): the mysql session. Returns: response.Response: containing the artist social profile. """ if not artist_id and not social_profile_id: return response.create_error_response( status.BAD_REQUEST, error.ERROR_MESSAGE_BAD_PARAMS) artist_social_profile = session.query(ArtistSocialProfile).filter_by( artist_id=artist_id, social_profile_id=social_profile_id).first() if artist_social_profile is not None: return response.Response(artist_social_profile.to_dict()) return response.create_not_found_response() @mysql.autosession() def delete_artist_social_profiles_by_social_profile_id( social_profile_id, session): """Delete an artist social profile by social profile id. Args: social_profile_id (int): the social profile id. session (Session): the mysql session. Returns: response.Response: containing a list of deleted artist social profiles dicts, not found if no profiles were deleted or Bad Params if no id was provided. """ if not social_profile_id: return response.create_error_response( status.BAD_REQUEST, error.ERROR_MESSAGE_BAD_PARAMS) query = session.query( ArtistSocialProfile).filter_by( social_profile_id=social_profile_id) rows = query.all() results = [row.to_dict() for row in rows] if len(results) == 0: return response.create_not_found_response() query.delete(synchronize_session=False) session.commit() return response.Response({'items': results}) @mysql.autosession() def delete_artist_social_profile(social_profile_id, artist_id, session): """Delete an artist social profile. Args: social_profile_id (int): The social_profile_id. artist_id (int): The artist_id. session (Session): the mysql session. Returns: response.Response: containing the deleted artist social profile dict, not found if no profile was deleted or Bad Params. """ if not social_profile_id or not artist_id: return response.create_error_response( status.BAD_REQUEST, error.ERROR_MESSAGE_BAD_PARAMS) query = session.query( ArtistSocialProfile).filter_by( social_profile_id=social_profile_id, artist_id=artist_id) rows = query.all() results = [row.to_dict() for row in rows] if len(results) == 0: return response.create_not_found_response() query.delete(synchronize_session=False) session.commit() return response.Response({'items': results})