@ -13,12 +13,12 @@ import json
# parse_library {{{ #
# parse_library {{{ #
def parse_library ( headers , tracks , library_stats , user ) :
def parse_library ( headers , tracks , user ) :
""" Scans user ' s library for certain number of tracks to update library_stats with.
""" Scans user ' s library for certain number of tracks to update library_stats with.
: headers : For API call .
: headers : For API call .
: tracks : Number of tracks to get from user ' s library.
: tracks : Number of tracks to get from user ' s library.
: library_stats : Dictionary containing the data mined from user ' s library
: user : a User object representing the user whose library we are parsing
: user : a User object representing the user whose library we are parsing
: returns : None
: returns : None
@ -30,8 +30,6 @@ def parse_library(headers, tracks, library_stats, user):
# keeps track of point to get songs from
# keeps track of point to get songs from
offset = 0
offset = 0
payload = { ' limit ' : str ( limit ) }
payload = { ' limit ' : str ( limit ) }
# use two separate variables to track, because the average popularity also requires num_samples
num_samples = 0 # number of actual track samples
# iterate until hit requested num of tracks
# iterate until hit requested num of tracks
for _ in range ( 0 , tracks , limit ) :
for _ in range ( 0 , tracks , limit ) :
@ -51,11 +49,14 @@ def parse_library(headers, tracks, library_stats, user):
name = artist_dict [ ' name ' ] ,
name = artist_dict [ ' name ' ] ,
)
)
update_artist_genre ( headers , artist_obj )
# update_artist_genre(headers, artist_obj)
# get_or_create() returns a tuple (obj, created)
# get_or_create() returns a tuple (obj, created)
track_artists . append ( artist_obj )
track_artists . append ( artist_obj )
track_obj , track_created = save_track_obj ( track_dict [ ' track ' ] , track_artists , user )
top_genre = get_top_genre ( headers ,
track_dict [ ' track ' ] [ ' artists ' ] [ 0 ] [ ' id ' ] )
track_obj , track_created = save_track_obj ( track_dict [ ' track ' ] ,
track_artists , top_genre , user )
# if a new track is not created, the associated audio feature does not need to be created again
# if a new track is not created, the associated audio feature does not need to be created again
if track_created :
if track_created :
@ -73,23 +74,22 @@ def parse_library(headers, tracks, library_stats, user):
"""
"""
# calculates num_songs with offset + songs retrieved
# calculates num_songs with offset + songs retrieved
offset + = limit
offset + = limit
# calculate_genres_from_artists(headers, library_stats)
# pprint.pprint(library_stats)
# pprint.pprint(library_stats)
# }}} parse_library #
# }}} parse_library #
# save_track_obj {{{ #
# save_track_obj {{{ #
def save_track_obj ( track_dict , artists , user ) :
def save_track_obj ( track_dict , artists , top_genre , user ) :
""" Make an entry in the database for this track if it doesn ' t exist already.
""" Make an entry in the database for this track if it doesn ' t exist already.
: track_dict : dictionary from the API call containing track information.
: track_dict : dictionary from the API call containing track information.
: artists : artists of the song , passed in as a list of Artist objects .
: artists : artists of the song , passed in as a list of Artist objects .
: top_genre : top genre associated with this track ( see get_top_genre ) .
: user : User object for which this Track is to be associated with .
: user : User object for which this Track is to be associated with .
: returns : ( The created / retrieved Track object , created )
: returns : ( The created / retrieved Track object , created )
"""
"""
print ( track_dict [ ' name ' ] )
track_query = Track . objects . filter ( track_id__exact = track_dict [ ' id ' ] )
track_query = Track . objects . filter ( track_id__exact = track_dict [ ' id ' ] )
if len ( track_query ) != 0 :
if len ( track_query ) != 0 :
return track_query [ 0 ] , False
return track_query [ 0 ] , False
@ -100,6 +100,7 @@ def save_track_obj(track_dict, artists, user):
popularity = int ( track_dict [ ' popularity ' ] ) ,
popularity = int ( track_dict [ ' popularity ' ] ) ,
runtime = int ( float ( track_dict [ ' duration_ms ' ] ) / 1000 ) ,
runtime = int ( float ( track_dict [ ' duration_ms ' ] ) / 1000 ) ,
name = track_dict [ ' name ' ] ,
name = track_dict [ ' name ' ] ,
genre = top_genre ,
)
)
# have to add artists and user after saving object since track needs to
# have to add artists and user after saving object since track needs to
@ -127,7 +128,6 @@ def save_audio_features(headers, track_id, track):
response = requests . get ( " https://api.spotify.com/v1/audio-features/{} " . format ( track_id ) , headers = headers ) . json ( )
response = requests . get ( " https://api.spotify.com/v1/audio-features/{} " . format ( track_id ) , headers = headers ) . json ( )
if ' error ' in response :
if ' error ' in response :
return { }
return { }
features_dict = { }
# Data that we don't need
# Data that we don't need
useless_keys = [
useless_keys = [
@ -137,7 +137,6 @@ def save_audio_features(headers, track_id, track):
audio_features_entry . track = track
audio_features_entry . track = track
for key , val in response . items ( ) :
for key , val in response . items ( ) :
if key not in useless_keys :
if key not in useless_keys :
features_dict [ key ] = val
setattr ( audio_features_entry , key , val )
setattr ( audio_features_entry , key , val )
audio_features_entry . save ( )
audio_features_entry . save ( )
@ -299,8 +298,7 @@ def get_track_info(track_dict, library_stats, sample_size):
# }}} get_track_info #
# }}} get_track_info #
# update_genres_from_artists {{{ #
# update_artist_genre {{{ #
def update_artist_genre ( headers , artist_obj ) :
def update_artist_genre ( headers , artist_obj ) :
""" Updates the top genre for an artist by querying the Spotify API
""" Updates the top genre for an artist by querying the Spotify API
@ -313,10 +311,31 @@ def update_artist_genre(headers, artist_obj):
"""
"""
artist_response = requests . get ( ' https://api.spotify.com/v1/artists/ ' + artist_obj . artist_id , headers = headers ) . json ( )
artist_response = requests . get ( ' https://api.spotify.com/v1/artists/ ' + artist_obj . artist_id , headers = headers ) . json ( )
# update genre for artist in database with top genre
# update genre for artist in database with top genre
if len ( artist_response [ ' genres ' ] ) > 0 :
artist_obj . genre = artist_response [ ' genres ' ] [ 0 ]
artist_obj . genre = artist_response [ ' genres ' ] [ 0 ]
artist_obj . save ( )
artist_obj . save ( )
# }}} calculate_genres_from_artists #
# }}} #
# {{{ #
def get_top_genre ( headers , top_artist_id ) :
""" Updates the top genre for a track by querying the Spotify API
: headers : For making the API call .
: top_artist : The first artist ' s (listed in the track) Spotify ID.
: returns : The first genre listed for the top_artist .
"""
artist_response = requests . get ( ' https://api.spotify.com/v1/artists/ ' +
top_artist_id , headers = headers ) . json ( )
if len ( artist_response [ ' genres ' ] ) > 0 :
return artist_response [ ' genres ' ] [ 0 ]
else :
return " undefined "
# }}} #
# process_library_stats {{{ #
# process_library_stats {{{ #
@ -374,14 +393,3 @@ def process_library_stats(library_stats):
# }}} process_library_stats #
# }}} process_library_stats #
def get_genre_data ( user ) :
""" Return genre data needed to create the graph user.
: user : User object for which to return the data for .
: returns : List of dicts containing counts for each genre .
"""
pass
# user_tracks = Track.objects.filter(users__exact=user)
# for track in user_tracks:
# print(track.name)