Пример #1
0
    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]
        }
Пример #2
0
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)
Пример #3
0
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
Пример #4
0
           "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,
Пример #5
0
    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}'")
Пример #6
0
    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}'")