From 5756642521119841ed19fecc752d386630584989 Mon Sep 17 00:00:00 2001 From: Kevin Mok Date: Thu, 28 Jun 2018 12:28:12 -0400 Subject: [PATCH] Added complete console logging for parsing library Specifically, when making API calls for genres/features and updating genres for tracks in db. --- recreate-db.txt | 6 ++---- spotifyvis/migrations/__init__.py | 0 spotifyvis/models.py | 3 +-- spotifyvis/utils.py | 32 ++++++++++++++++++++++--------- spotifyvis/views.py | 24 ++++++++++++++++++++--- 5 files changed, 47 insertions(+), 18 deletions(-) delete mode 100644 spotifyvis/migrations/__init__.py diff --git a/recreate-db.txt b/recreate-db.txt index 5c1e574..cb082e7 100644 --- a/recreate-db.txt +++ b/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 diff --git a/spotifyvis/migrations/__init__.py b/spotifyvis/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/spotifyvis/models.py b/spotifyvis/models.py index 7419443..09a9ec7 100644 --- a/spotifyvis/models.py +++ b/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): diff --git a/spotifyvis/utils.py b/spotifyvis/utils.py index 668c274..dd0b087 100644 --- a/spotifyvis/utils.py +++ b/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 {{{ # diff --git a/spotifyvis/views.py b/spotifyvis/views.py index d48acef..dc2d708 100644 --- a/spotifyvis/views.py +++ b/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):