Parse listening history and add Track objects
This commit is contained in:
@@ -47,7 +47,7 @@ class Track(models.Model):
|
||||
id = models.CharField(primary_key=True, max_length=MAX_ID)
|
||||
# artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
|
||||
artists = models.ManyToManyField(Artist, blank=True)
|
||||
year = models.PositiveSmallIntegerField()
|
||||
year = models.PositiveSmallIntegerField(null=True)
|
||||
popularity = models.PositiveSmallIntegerField()
|
||||
runtime = models.PositiveSmallIntegerField()
|
||||
name = models.CharField(max_length=200)
|
||||
|
||||
@@ -4,8 +4,10 @@ from .views import *
|
||||
|
||||
app_name = 'api'
|
||||
urlpatterns = [
|
||||
path('scan/<str:user_secret>', parse_library,
|
||||
name='scan'),
|
||||
path('scan/library/<str:user_secret>', parse_library,
|
||||
name='scan_library'),
|
||||
path('scan/history/<str:user_secret>', parse_history,
|
||||
name='scan_history'),
|
||||
path('user_artists/<str:user_secret>', get_artist_data,
|
||||
name='get_artist_data'),
|
||||
path('user_genres/<str:user_secret>', get_genre_data,
|
||||
|
||||
43
api/utils.py
43
api/utils.py
@@ -14,8 +14,8 @@ from login.models import User
|
||||
|
||||
# }}} imports #
|
||||
|
||||
console_logging = True
|
||||
# console_logging = False
|
||||
# console_logging = True
|
||||
console_logging = False
|
||||
artists_genre_processed = 0
|
||||
features_processed = 0
|
||||
|
||||
@@ -74,19 +74,32 @@ def save_track_obj(track_dict, artists, user_obj):
|
||||
if len(track_query) != 0:
|
||||
return track_query[0], False
|
||||
else:
|
||||
new_track = Track.objects.create(
|
||||
id=track_dict['id'],
|
||||
year=track_dict['album']['release_date'].split('-')[0],
|
||||
popularity=int(track_dict['popularity']),
|
||||
runtime=int(float(track_dict['duration_ms']) / 1000),
|
||||
name=track_dict['name'],
|
||||
)
|
||||
# check if track is simple or full, simple Track object won't have year
|
||||
# if 'album' in track_dict:
|
||||
try:
|
||||
new_track = Track.objects.create(
|
||||
id=track_dict['id'],
|
||||
year=track_dict['album']['release_date'].split('-')[0],
|
||||
popularity=int(track_dict['popularity']),
|
||||
runtime=int(float(track_dict['duration_ms']) / 1000),
|
||||
name=track_dict['name'],
|
||||
)
|
||||
# else:
|
||||
except KeyError:
|
||||
new_track = Track.objects.create(
|
||||
id=track_dict['id'],
|
||||
popularity=int(track_dict['popularity']),
|
||||
runtime=int(float(track_dict['duration_ms']) / 1000),
|
||||
name=track_dict['name'],
|
||||
)
|
||||
|
||||
# have to add artists and user_obj after saving object since track needs to
|
||||
# have ID before filling in m2m field
|
||||
for artist in artists:
|
||||
new_track.artists.add(artist)
|
||||
new_track.users.add(user_obj)
|
||||
# print(new_track.name, artist.name)
|
||||
if user_obj != None:
|
||||
new_track.users.add(user_obj)
|
||||
new_track.save()
|
||||
return new_track, True
|
||||
|
||||
@@ -178,6 +191,7 @@ def add_artist_genres(headers, artist_objs):
|
||||
else:
|
||||
for genre in artists_response[i]['genres']:
|
||||
process_artist_genre(genre, artist_objs[i])
|
||||
# print(artist_objs[i].name, genre)
|
||||
|
||||
if console_logging:
|
||||
global artists_genre_processed
|
||||
@@ -221,6 +235,15 @@ def get_artists_in_genre(user, genre, max_songs):
|
||||
|
||||
# }}} get_artists_in_genre #
|
||||
|
||||
def create_artist_for_track(artist_dict):
|
||||
"""TODO: Docstring for create_artist_for_track.
|
||||
|
||||
:artist_dict: TODO
|
||||
:returns: None
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_user_header(user_obj):
|
||||
"""Returns the authorization string needed to make an API call.
|
||||
|
||||
|
||||
68
api/views.py
68
api/views.py
@@ -19,13 +19,16 @@ from login.utils import get_user_context
|
||||
# }}} imports #
|
||||
|
||||
USER_TRACKS_LIMIT = 50
|
||||
HISTORY_LIMIT = 50
|
||||
ARTIST_LIMIT = 50
|
||||
FEATURES_LIMIT = 100
|
||||
# ARTIST_LIMIT = 25
|
||||
# FEATURES_LIMIT = 25
|
||||
TRACKS_TO_QUERY = 100
|
||||
HISTORY_ENDPOINT = 'https://api.spotify.com/v1/me/player/recently-played'
|
||||
|
||||
console_logging = True
|
||||
# console_logging = False
|
||||
|
||||
# parse_library {{{ #
|
||||
|
||||
@@ -119,6 +122,71 @@ def parse_library(request, user_secret):
|
||||
|
||||
# }}} parse_library #
|
||||
|
||||
# parse_history {{{ #
|
||||
|
||||
def parse_history(request, user_secret):
|
||||
"""Scans user's listening history and stores the information in a
|
||||
database.
|
||||
|
||||
:user_secret: secret for User object who's library is being scanned.
|
||||
:returns: None
|
||||
"""
|
||||
|
||||
payload = {'limit': str(USER_TRACKS_LIMIT)}
|
||||
artist_genre_queue = []
|
||||
user_obj = User.objects.get(secret=user_secret)
|
||||
user_headers = get_user_header(user_obj)
|
||||
|
||||
history_response = requests.get(HISTORY_ENDPOINT,
|
||||
headers=user_headers,
|
||||
params=payload).json()['items']
|
||||
|
||||
if console_logging:
|
||||
tracks_processed = 0
|
||||
|
||||
for track_dict in history_response:
|
||||
# add artists {{{ #
|
||||
|
||||
# update artist info before track so that Track object can reference
|
||||
# Artist object
|
||||
track_artists = []
|
||||
for artist_dict in track_dict['track']['artists']:
|
||||
artist_obj, artist_created = Artist.objects.get_or_create(
|
||||
id=artist_dict['id'],
|
||||
name=artist_dict['name'],)
|
||||
# only add/tally up artist genres if new
|
||||
if artist_created:
|
||||
artist_genre_queue.append(artist_obj)
|
||||
if len(artist_genre_queue) == ARTIST_LIMIT:
|
||||
add_artist_genres(user_headers, artist_genre_queue)
|
||||
artist_genre_queue = []
|
||||
track_artists.append(artist_obj)
|
||||
|
||||
# }}} add artists #
|
||||
|
||||
# don't associate history track with User, not necessarily in their
|
||||
# library
|
||||
track_obj, track_created = save_track_obj(track_dict['track'],
|
||||
track_artists, None)
|
||||
|
||||
if console_logging:
|
||||
tracks_processed += 1
|
||||
print("Added track #{}: {} - {}".format(
|
||||
tracks_processed,
|
||||
track_obj.artists.first(),
|
||||
track_obj.name,
|
||||
))
|
||||
|
||||
if len(artist_genre_queue) > 0:
|
||||
add_artist_genres(user_headers, artist_genre_queue)
|
||||
|
||||
# TODO: update track genres from History relation
|
||||
# update_track_genres(user_obj)
|
||||
|
||||
return render(request, 'graphs/logged_in.html', get_user_context(user_obj))
|
||||
|
||||
# }}} get_history #
|
||||
|
||||
# get_artist_data {{{ #
|
||||
|
||||
def get_artist_data(request, user_secret):
|
||||
|
||||
Reference in New Issue
Block a user