Create separate page for audio features
An additional page where the user will be directed after logging in was created. A link to the audio features display page was added to the aforementioned page. Changes were made to the audio features graphing function so that the categories are displayed in ascending order (was random before).
This commit is contained in:
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Retrieves data for a specific audio feature for a certain user
|
|
||||||
* @param audioFeature: the audio feature for which data will be retrieved
|
|
||||||
* @param clientSecret: the client secret, needed for security
|
|
||||||
* @param chartElement: the SVG element in which the data will be plotted
|
|
||||||
*/
|
|
||||||
function plotAudioFeatureData(audioFeature, userSecret, chartElement) {
|
|
||||||
let httpRequest = new XMLHttpRequest();
|
|
||||||
/*
|
|
||||||
* Handler for the response
|
|
||||||
*/
|
|
||||||
httpRequest.onreadystatechange = function() {
|
|
||||||
if (httpRequest.readyState === XMLHttpRequest.DONE) {
|
|
||||||
if (httpRequest.status === 200) {
|
|
||||||
let responseData = JSON.parse(httpRequest.responseText);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
alert("There was a problem with the login request, please try again!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let queryString = `/audio_features/${audioFeature}/${userSecret}`;
|
|
||||||
httpRequest.open('GET', queryString, true);
|
|
||||||
httpRequest.send();
|
|
||||||
}
|
|
||||||
@@ -20,9 +20,8 @@
|
|||||||
<!--[if lt IE 7]>
|
<!--[if lt IE 7]>
|
||||||
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
|
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
<p>Logged in as {{ id }}</p>
|
<p>Logged in as {{ user_id }}</p>
|
||||||
<script src="https://d3js.org/d3.v5.js"></script>
|
<script src="https://d3js.org/d3.v5.js"></script>
|
||||||
<script src="{% static "spotifyvis/scripts/user_data.js" %}"></script>
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
/** Queries the backend for audio feature data, draws the bar chart
|
/** Queries the backend for audio feature data, draws the bar chart
|
||||||
@@ -43,10 +42,14 @@
|
|||||||
height = 270 - margin.top - margin.bottom;
|
height = 270 - margin.top - margin.bottom;
|
||||||
|
|
||||||
let featureData = {};
|
let featureData = {};
|
||||||
|
// Create the keys first in order
|
||||||
|
for (let index = 0; index < intervalEndPoints.length - 1; index++) {
|
||||||
|
let key = `${intervalEndPoints[index]} ~ ${intervalEndPoints[index + 1]}`;
|
||||||
|
featureData[key] = 0;
|
||||||
|
}
|
||||||
// define the vertical scaling function
|
// define the vertical scaling function
|
||||||
let vScale = d3.scaleLinear().range([height, 0]);
|
let vScale = d3.scaleLinear().range([height, 0]);
|
||||||
|
|
||||||
// getAudioFeatureData('instrumentalness', sessionStorage.getItem('user_secret'));
|
|
||||||
d3.json(`/audio_features/${audioFeature}/{{ user_secret }}`)
|
d3.json(`/audio_features/${audioFeature}/{{ user_secret }}`)
|
||||||
.then(function(response) {
|
.then(function(response) {
|
||||||
// categorize the data points
|
// categorize the data points
|
||||||
@@ -57,10 +60,7 @@
|
|||||||
while (dataPoint < intervalEndPoints[index]) {
|
while (dataPoint < intervalEndPoints[index]) {
|
||||||
index -= 1;
|
index -= 1;
|
||||||
}
|
}
|
||||||
let key = `${intervalEndPoints[index]}-${intervalEndPoints[index + 1]}`;
|
let key = `${intervalEndPoints[index]} ~ ${intervalEndPoints[index + 1]}`;
|
||||||
if (!featureData.hasOwnProperty(key)) {
|
|
||||||
featureData[key] = 0;
|
|
||||||
}
|
|
||||||
featureData[key] += 1;
|
featureData[key] += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,9 +132,10 @@
|
|||||||
drawAudioFeatGraph("valence", [0, 0.25, 0.5, 0.75, 1.0], 'body');
|
drawAudioFeatGraph("valence", [0, 0.25, 0.5, 0.75, 1.0], 'body');
|
||||||
drawAudioFeatGraph("energy", [0, 0.25, 0.5, 0.75, 1.0], 'body');
|
drawAudioFeatGraph("energy", [0, 0.25, 0.5, 0.75, 1.0], 'body');
|
||||||
drawAudioFeatGraph("tempo", [40, 80, 120, 160, 200], 'body');
|
drawAudioFeatGraph("tempo", [40, 80, 120, 160, 200], 'body');
|
||||||
|
drawAudioFeatGraph("danceability", [0, 0.25, 0.5, 0.75, 1.0], 'body');
|
||||||
|
drawAudioFeatGraph("acousticness", [0, 0.25, 0.5, 0.75, 1.0], 'body');
|
||||||
|
drawAudioFeatGraph("loudness", [-60, -45, -30, -15, 0], 'body');
|
||||||
|
drawAudioFeatGraph("speechiness", [0, 0.25, 0.5, 0.75, 1.0], 'body');
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
12
spotifyvis/templates/spotifyvis/logged_in.html
Normal file
12
spotifyvis/templates/spotifyvis/logged_in.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
{% load static %}
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Logged In</title>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a class="btn btn-primary" href="/audio_features/{{ user_secret }}" role="button">Audio Features</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -11,6 +11,7 @@ urlpatterns = [
|
|||||||
path('test_db', test_db, name='test_db'),
|
path('test_db', test_db, name='test_db'),
|
||||||
path('user_artists/<str:user_id>', get_artist_data, name='get_artist_data'),
|
path('user_artists/<str:user_id>', get_artist_data, name='get_artist_data'),
|
||||||
path('user_genres/<str:user_secret>', get_genre_data, name='get_genre_data'),
|
path('user_genres/<str:user_secret>', get_genre_data, name='get_genre_data'),
|
||||||
|
path('audio_features/<str:client_secret>', audio_features, name='audio_features'),
|
||||||
path('audio_features/<str:audio_feature>/<str:client_secret>',
|
path('audio_features/<str:audio_feature>/<str:client_secret>',
|
||||||
get_audio_feature_data, name='get_audio_feature_data'),
|
get_audio_feature_data, name='get_audio_feature_data'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ def index(request):
|
|||||||
|
|
||||||
# login {{{ #
|
# login {{{ #
|
||||||
|
|
||||||
|
|
||||||
def login(request):
|
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
|
||||||
@@ -118,6 +119,7 @@ def callback(request):
|
|||||||
|
|
||||||
# user_data {{{ #
|
# user_data {{{ #
|
||||||
|
|
||||||
|
|
||||||
def user_data(request):
|
def user_data(request):
|
||||||
token_obtained_at = datetime.strptime(request.session['token_obtained_at'], TIME_FORMAT)
|
token_obtained_at = datetime.strptime(request.session['token_obtained_at'], TIME_FORMAT)
|
||||||
valid_for = int(request.session['valid_for'])
|
valid_for = int(request.session['valid_for'])
|
||||||
@@ -130,7 +132,7 @@ def user_data(request):
|
|||||||
'client_secret': os.environ['SPOTIFY_CLIENT_SECRET']
|
'client_secret': os.environ['SPOTIFY_CLIENT_SECRET']
|
||||||
}
|
}
|
||||||
|
|
||||||
refresh_token_response = requests.post('https://accounts.spotify.com/api/token', data = req_body).json()
|
refresh_token_response = requests.post('https://accounts.spotify.com/api/token', data=req_body).json()
|
||||||
request.session['access_token'] = refresh_token_response['access_token']
|
request.session['access_token'] = refresh_token_response['access_token']
|
||||||
request.session['valid_for'] = refresh_token_response['expires_in']
|
request.session['valid_for'] = refresh_token_response['expires_in']
|
||||||
|
|
||||||
@@ -139,7 +141,7 @@ def user_data(request):
|
|||||||
'Authorization': auth_token_str
|
'Authorization': auth_token_str
|
||||||
}
|
}
|
||||||
|
|
||||||
user_data_response = requests.get('https://api.spotify.com/v1/me', headers = headers).json()
|
user_data_response = requests.get('https://api.spotify.com/v1/me', headers=headers).json()
|
||||||
request.session['user_id'] = user_data_response['id'] # store the user_id so it may be used to create model
|
request.session['user_id'] = user_data_response['id'] # store the user_id so it may be used to create model
|
||||||
# request.session['user_name'] = user_data_response['display_name']
|
# request.session['user_name'] = user_data_response['display_name']
|
||||||
|
|
||||||
@@ -148,15 +150,15 @@ def user_data(request):
|
|||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
# Python docs recommends 32 bytes of randomness against brute force attacks
|
# Python docs recommends 32 bytes of randomness against brute force attacks
|
||||||
user = User(user_id=user_data_response['id'], user_secret=secrets.token_urlsafe(32))
|
user = User(user_id=user_data_response['id'], user_secret=secrets.token_urlsafe(32))
|
||||||
|
request.session['user_secret'] = user.user_secret
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'id': user_data_response['id'],
|
|
||||||
'user_secret': user.user_secret,
|
'user_secret': user.user_secret,
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_library(headers, TRACKS_TO_QUERY, user)
|
parse_library(headers, TRACKS_TO_QUERY, user)
|
||||||
return render(request, 'spotifyvis/user_data.html', context)
|
return render(request, 'spotifyvis/logged_in.html', context)
|
||||||
|
|
||||||
# }}} user_data #
|
# }}} user_data #
|
||||||
|
|
||||||
@@ -188,6 +190,16 @@ def get_artist_data(request, user_secret):
|
|||||||
|
|
||||||
# }}} get_artist_data #
|
# }}} get_artist_data #
|
||||||
|
|
||||||
|
|
||||||
|
def audio_features(request, client_secret):
|
||||||
|
user = User.objects.get(user_secret=client_secret)
|
||||||
|
context = {
|
||||||
|
'user_id': user.user_id,
|
||||||
|
'user_secret': client_secret,
|
||||||
|
}
|
||||||
|
return render(request, "spotifyvis/audio_features.html", context)
|
||||||
|
|
||||||
|
|
||||||
# get_audio_feature_data {{{ #
|
# get_audio_feature_data {{{ #
|
||||||
|
|
||||||
def get_audio_feature_data(request, audio_feature, client_secret):
|
def get_audio_feature_data(request, audio_feature, client_secret):
|
||||||
|
|||||||
Reference in New Issue
Block a user