Browse Source

Added complete console logging for parsing library

Specifically, when making API calls for genres/features and updating
genres for tracks in db.
master
Kevin Mok 6 years ago
parent
commit
5756642521
  1. 6
      recreate-db.txt
  2. 0
      spotifyvis/migrations/__init__.py
  3. 3
      spotifyvis/models.py
  4. 32
      spotifyvis/utils.py
  5. 24
      spotifyvis/views.py

6
recreate-db.txt

@ -1,8 +1,6 @@
# https://stackoverflow.com/a/34576062/8811872
sudo su postgres
psql
sudo -u postgres psql
drop database spotifyvis;
create database spotifyvis with owner django;
\q
exit

0
spotifyvis/migrations/__init__.py

3
spotifyvis/models.py

@ -28,8 +28,7 @@ class Artist(models.Model):
verbose_name_plural = "Artists"
artist_id = models.CharField(primary_key=True, max_length=MAX_ID)
# unique since only storing one genre per artist right now
name = models.CharField(unique=True, max_length=50)
name = models.CharField(max_length=50)
genres = models.ManyToManyField(Genre, blank=True)
def __str__(self):

32
spotifyvis/utils.py

@ -11,12 +11,16 @@ import json
# }}} imports #
# API limits {{{ #
USER_TRACKS_LIMIT = 50
ARTIST_LIMIT = 50
FEATURES_LIMIT = 100
# ARTIST_LIMIT = 25
# FEATURES_LIMIT = 25
# }}} API limits #
# parse_library {{{ #
def parse_library(headers, tracks, user):
@ -63,10 +67,8 @@ def parse_library(headers, tracks, user):
# }}} add artists #
# TODO: fix this, don't need any more
top_genre = ""
track_obj, track_created = save_track_obj(track_dict['track'],
track_artists, top_genre, user)
track_artists, user)
# add audio features {{{ #
@ -80,8 +82,8 @@ def parse_library(headers, tracks, user):
# }}} add audio features #
# temporary console logging
print("#{}-{}: {} - {}".format(offset + 1,
# console logging
print("Added track #{}-{}: {} - {}".format(offset + 1,
offset + USER_TRACKS_LIMIT,
track_obj.artists.first(),
track_obj.name))
@ -131,13 +133,15 @@ def update_track_genres(user):
track.genre = most_common_genre if most_common_genre is not None \
else undefined_genre_obj
track.save()
# print(track.name, track.genre)
# console logging
print("Added '{}' as genre for song '{}'".format(track.genre, track.name))
# }}} update_track_genres #
# save_track_obj {{{ #
def save_track_obj(track_dict, artists, top_genre, user):
def save_track_obj(track_dict, artists, user):
"""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.
@ -158,7 +162,6 @@ def save_track_obj(track_dict, artists, top_genre, user):
popularity=int(track_dict['popularity']),
runtime=int(float(track_dict['duration_ms']) / 1000),
name=track_dict['name'],
# genre=top_genre,
)
# have to add artists and user after saving object since track needs to
@ -200,8 +203,14 @@ def get_audio_features(headers, track_objs):
setattr(cur_features_obj, key, val)
cur_features_obj.save()
# console logging
print("Added features for song #{} - {}".format(i + 1,
track_objs[i].name))
# }}} get_audio_features #
# process_artist_genre {{{ #
def process_artist_genre(genre_name, artist_obj):
"""Increase count for correspoding Genre object to genre_name and add that
Genre to artist_obj.
@ -219,6 +228,8 @@ def process_artist_genre(genre_name, artist_obj):
artist_obj.genres.add(genre_obj)
artist_obj.save()
# }}} process_artist_genre #
# add_artist_genres {{{ #
def add_artist_genres(headers, artist_objs):
@ -236,7 +247,6 @@ def add_artist_genres(headers, artist_objs):
params = {'ids': artist_ids}
artists_response = requests.get('https://api.spotify.com/v1/artists/',
headers=headers, params=params).json()['artists']
# pprint.pprint(artists_response)
for i in range(len(artist_objs)):
if len(artists_response[i]['genres']) == 0:
process_artist_genre("undefined", artist_objs[i])
@ -244,6 +254,10 @@ def add_artist_genres(headers, artist_objs):
for genre in artists_response[i]['genres']:
process_artist_genre(genre, artist_objs[i])
# console logging
print("Added genres for artist #{} - {}".format(i + 1,
artist_objs[i].name))
# }}} add_artist_genres #
# get_artists_in_genre {{{ #

24
spotifyvis/views.py

@ -18,9 +18,13 @@ from .models import User, Track, AudioFeatures, Artist
# }}} imports #
# global vars {{{ #
TIME_FORMAT = '%Y-%m-%d-%H-%M-%S'
TRACKS_TO_QUERY = 200
# }}} global vars #
# generate_random_string {{{ #
@ -66,7 +70,8 @@ def index(request):
# uses Authorization Code flow
def login(request):
# use a randomly generated state string to prevent cross-site request forgery attacks
# use a randomly generated state string to prevent cross-site request
# forgery attacks
state_str = generate_random_string(16)
request.session['state_string'] = state_str
@ -79,7 +84,8 @@ def login(request):
'show_dialog': False
}
params = urllib.parse.urlencode(payload) # turn the payload dict into a query string
# turn the payload dict into a query string
params = urllib.parse.urlencode(payload)
authorize_url = "https://accounts.spotify.com/authorize/?{}".format(params)
return redirect(authorize_url)
@ -170,8 +176,10 @@ def user_data(request):
# }}} user_data #
# admin_graphs {{{ #
def admin_graphs(request):
"""TODO
"""Redirect to logged in page as ourselves. For testing purposes.
"""
user_id = "polarbier"
# user_id = "chrisshyi13"
@ -183,6 +191,8 @@ def admin_graphs(request):
update_track_genres(user_obj)
return render(request, 'spotifyvis/logged_in.html', context)
# }}} admin_graphs #
# get_artist_data {{{ #
def get_artist_data(request, user_secret):
@ -197,6 +207,8 @@ def get_artist_data(request, user_secret):
# }}} get_artist_data #
# display_genre_graph {{{ #
def display_genre_graph(request, client_secret):
user = User.objects.get(user_secret=client_secret)
context = {
@ -204,6 +216,10 @@ def display_genre_graph(request, client_secret):
}
return render(request, "spotifyvis/genre_graph.html", context)
# }}} display_genre_graph #
# audio_features graph {{{ #
def audio_features(request, client_secret):
user = User.objects.get(user_secret=client_secret)
context = {
@ -212,6 +228,8 @@ def audio_features(request, client_secret):
}
return render(request, "spotifyvis/audio_features.html", context)
# }}} audio_features graph #
# get_audio_feature_data {{{ #
def get_audio_feature_data(request, audio_feature, client_secret):

Loading…
Cancel
Save