def get(self, userid, song_count): """Get the top N genres of the user.""" client = influx.create_client(app.config['INFLUX_HOST'], app.config['INFLUX_PORT']) recent_songs = influx.get_songs(client, userid) if not recent_songs: api.abort(404, message=f"No history found for '{userid}'") songids = [song['songid'] for song in recent_songs] result = models.Song.get_songs_with_mood(songids) counted_songs = sorted([((song, songmood), songids.count(song.songid)) for song, songmood in result], key=lambda val: val[1], reverse=True) top_x = counted_songs[:int(song_count)] return { 'userid': userid, 'songs': [{ **song.__dict__, **songmood.__dict__ } for (song, songmood), count in top_x] }
def index(): if "json_info" not in session: return render_template("index.html", **locals()) else: client = influx.create_client(app.config['INFLUX_HOST'], app.config['INFLUX_PORT']) userid = session['json_info']['id'] access_token = spotify.get_access_token(session['json_info']['refresh_token']) all_songs = set([Song.get_song_name(song['songid']) for song in influx.get_songs(client, userid)]) return render_template("dashboard.html", **locals(), text=session['json_info']['display_name'], id=session['json_info']['id'], song_history=all_songs)
def get_history(userid, song_count, return_songids=False, calc_mood=True): """ Get the latest song_count tracks for userid. :param userid: Unique identifier for a user. :param song_count: How many songs should be returned. :return_songids: Return list of songids instead of history with features. :param calc_mood: Calculate the average excitedness and happiness. :return: Average of happiness and happiness, list of dictionary containing songs. """ client = influx.create_client(app.config['INFLUX_HOST'], app.config['INFLUX_PORT']) recent_songs = influx.get_songs(client, userid, song_count) if recent_songs: history = [] # Remove duplicates songs songids = [song['songid'] for song in recent_songs] songids = songids[:song_count] if song_count > 0 else songids songmoods = models.Songmood.get_moods(songids) excitedness = 0 happiness = 0 count = 1 for i, songmood in enumerate(songmoods): if calc_mood and songmood.excitedness and songmood.happiness: excitedness += songmood.excitedness happiness += songmood.happiness count += 1 if count != 1 else 0 if not return_songids: song = { 'songid': songmood.songid, 'excitedness': songmood.excitedness, 'happiness': songmood.happiness, 'time': recent_songs[i]['time'], 'name': models.Song.get_song_name(songmood.songid) } history.append(song) if calc_mood: excitedness /= count happiness /= count if return_songids: return excitedness, happiness, songids return excitedness, happiness, history return None, None, None
"Mounir El Kirafi", "Esmeralda Knaap", "Youri Reijne", "Siwa Sardjoemissier", "Barry de Vries", "Jelle Witsen Elias" """ from app import app from app import db from app.utils import influx from app.utils.models import Song, Songmood from moodanalysis.moodAnalysis import analyse_mood if __name__ == "__main__": client = influx.create_client(app.config['INFLUX_HOST'], app.config['INFLUX_PORT']) client.switch_database('songs') all_data = client.query('select "songid" from /.*/').raw['series'] all_values = [data['values'] for data in all_data] flattened_data = [x for sublist in all_values for x in sublist] data = [x[1] for x in flattened_data] types = [ "acousticness", "danceability", "duration_ms", "energy", "instrumentalness", "key", "liveness", "loudness", "mode", "songid", "speechiness", "tempo", "time_signature", "valence" ] features = db.session.query(Song).filter(Song.songid.in_(data)).all() tracks = [] for f in features: tracks.append({ 'songid': f.songid,
def get(self=None, userid="snipy12", day_count=5): """ Obtain average metrics and mood per day of user, going back day_count days. """ client = influx.create_client(app.config['INFLUX_HOST'], app.config['INFLUX_PORT']) songs = influx.get_songs(client, userid) if songs: # Create a dictionary of lists to store the songid's per hour # Thus {"Time":[songids,....]} resultDict = defaultdict(list) # For each {songid,time} in the list for song in songs: mood_time = song['time'].split(".")[0][:10] resultDict[mood_time].append(song['songid']) results = [] # With the list of IDs with corresponding hour and features. for time, songid_list in list(resultDict.items())[:day_count]: # Obtain the metrics for each song inside a list of songs. songs = models.Song.get_songs_with_mood(songid_list) tempresults = [] for song in songs: # We want both the mood and metrics thus we convert the object to a dictionary and combine them # Then we pop the keys of said dictionary. temp1 = ((song[0].__dict__)) temp2 = ((song[1].__dict__)) combineddict = {**temp1, **temp2} combineddict.pop("name") combineddict.pop("_sa_instance_state") combineddict.pop("songid") # Add the metrics of a SINGLE song to the temporary result tempresults.append(combineddict) # As we are interested in the average we store the count of this list count = len(tempresults) # Remove the first element, which will be used for addition A = Counter(tempresults.pop(0)) A = convert_none(A) # Now iterate over each song's metrics within the results and add the values using counter. for B in tempresults: B = Counter(B) B = convert_none(B) try: A = A + B except TypeError: count -= 1 # Convert these to averages by dividing each key if possible for key, value in A.items(): if value: A[key] = value / count else: A[key] = 0 # Add hour key for correct output format and append to results A['date'] = time results.append(A) return {"userid": userid, "dates": results} else: api.abort(404, msg=f"No moods found for '{userid}'")
def get(self=None, userid="snipy12", start=3, end=24, endoftime=False): """ Obtain moods of a user within a given time frame as averages per hour. """ if start > end: api.abort(400, msg="Timeframe incorrect: start > end") if start > 23 or start < 0: api.abort(400, msg="Timeframe incorrect: start time not between 0 - 23") if end > 24 or end < 1: api.abort(400, msg="Timeframe incorrect: end time not between 1 - 24") client = influx.create_client(app.config['INFLUX_HOST'], app.config['INFLUX_PORT']) songs = influx.get_songs(client, userid) if songs: # Extract all songs that fit within the time-frame specified. relevantSongs = [ val for val in songs if valid_hour(val['time'], start, end) ] # Create a dictionary of lists to store the songid's per hour # Thus {"Time":[songids,....]} resultDict = defaultdict(list) # For each {songid,time} in the list for song in relevantSongs: mood_time = song['time'].split(".")[0] mood_time = datetime.datetime.strptime(mood_time[:-1], '%Y-%m-%dT%H:%M:%S') mood_hour = mood_time.hour if start <= mood_hour <= end: # Add the songid to the dictionary resultDict[mood_hour].append(song['songid']) results = [] # With the list of IDs with corresponding hour and features. for time, songid_list in resultDict.items(): # Obtain the metrics for each song inside a list of songs. songs = models.Song.get_songs_with_mood(songid_list) tempresults = [] for song in songs: # We want both the mood and metrics thus we convert the object to a dictionary and combine them # Then we pop the keys of said dictionary. temp1 = ((song[0].__dict__)) temp2 = ((song[1].__dict__)) combineddict = {**temp1, **temp2} combineddict.pop("name") combineddict.pop("_sa_instance_state") combineddict.pop("songid") # Add the metrics of a SINGLE song to the temporary result tempresults.append(combineddict) # As we are interested in the average we store the count of this list count = len(tempresults) # Remove the first element, which will be used for addition A = Counter(tempresults.pop(0)) A = convert_none(A) # Now iterate over each song's metrics within the results and add the values using counter. for B in tempresults: B = Counter(B) B = convert_none(B) try: A = A + B except TypeError: count -= 1 # Convert these to averages by dividing each key if possible for key, value in A.items(): if value: A[key] = value / count else: A[key] = 0 # Add hour key for correct output format and append to results A['hour'] = time results.append(A) return {"userid": userid, "hours": results} else: api.abort(404, msg=f"No moods found for '{userid}'")