Site is as functional as before (resolves #47)
Finished setting up graphs app and getting data from API app. Only issue now is this branch is behind a few commits from other branches.
This commit is contained in:
23
api/views.py
23
api/views.py
@@ -14,6 +14,7 @@ from django.db.models import Count, Q
|
|||||||
from .utils import *
|
from .utils import *
|
||||||
from .models import *
|
from .models import *
|
||||||
from login.models import User
|
from login.models import User
|
||||||
|
from login.utils import get_user_context
|
||||||
|
|
||||||
# }}} imports #
|
# }}} imports #
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ ARTIST_LIMIT = 50
|
|||||||
FEATURES_LIMIT = 100
|
FEATURES_LIMIT = 100
|
||||||
# ARTIST_LIMIT = 25
|
# ARTIST_LIMIT = 25
|
||||||
# FEATURES_LIMIT = 25
|
# FEATURES_LIMIT = 25
|
||||||
TRACKS_TO_QUERY = 200
|
TRACKS_TO_QUERY = 100
|
||||||
|
|
||||||
console_logging = True
|
console_logging = True
|
||||||
|
|
||||||
@@ -114,17 +115,12 @@ def parse_library(request, user_secret):
|
|||||||
|
|
||||||
update_track_genres(user_obj)
|
update_track_genres(user_obj)
|
||||||
|
|
||||||
context = {
|
return render(request, 'graphs/logged_in.html', get_user_context(user_obj))
|
||||||
'user_id': user_obj.id,
|
|
||||||
'user_secret': user_obj.secret,
|
|
||||||
}
|
|
||||||
return render(request, 'api/logged_in.html', context)
|
|
||||||
|
|
||||||
# }}} parse_library #
|
# }}} parse_library #
|
||||||
|
|
||||||
# get_artist_data {{{ #
|
# get_artist_data {{{ #
|
||||||
|
|
||||||
|
|
||||||
def get_artist_data(request, user_secret):
|
def get_artist_data(request, user_secret):
|
||||||
"""Returns artist data as a JSON serialized list of dictionaries
|
"""Returns artist data as a JSON serialized list of dictionaries
|
||||||
The (key, value) pairs are (artist name, song count for said artist)
|
The (key, value) pairs are (artist name, song count for said artist)
|
||||||
@@ -133,11 +129,12 @@ def get_artist_data(request, user_secret):
|
|||||||
:param user_secret: the user secret used for identification
|
:param user_secret: the user secret used for identification
|
||||||
:return: a JsonResponse
|
:return: a JsonResponse
|
||||||
"""
|
"""
|
||||||
user = User.objects.get(user_secret=user_secret)
|
user = User.objects.get(secret=user_secret)
|
||||||
artist_counts = Artist.objects.annotate(num_songs=Count('track',
|
artist_counts = Artist.objects.annotate(num_songs=Count('track',
|
||||||
filter=Q(track__users=user)))
|
filter=Q(track__users=user)))
|
||||||
processed_artist_counts = [{'name': artist.name,
|
processed_artist_counts = [{'name': artist.name, 'num_songs': artist.num_songs}
|
||||||
'num_songs': artist.num_songs} for artist in artist_counts]
|
for artist in artist_counts]
|
||||||
|
pprint.pprint(processed_artist_counts)
|
||||||
return JsonResponse(data=processed_artist_counts, safe=False)
|
return JsonResponse(data=processed_artist_counts, safe=False)
|
||||||
|
|
||||||
# }}} get_artist_data #
|
# }}} get_artist_data #
|
||||||
@@ -152,7 +149,7 @@ def get_audio_feature_data(request, audio_feature, user_secret):
|
|||||||
audio_feature: The audio feature to be queried
|
audio_feature: The audio feature to be queried
|
||||||
user_secret: client secret, used to identify the user
|
user_secret: client secret, used to identify the user
|
||||||
"""
|
"""
|
||||||
user = User.objects.get(user_secret=user_secret)
|
user = User.objects.get(secret=user_secret)
|
||||||
user_tracks = Track.objects.filter(users=user)
|
user_tracks = Track.objects.filter(users=user)
|
||||||
response_payload = {
|
response_payload = {
|
||||||
'data_points': [],
|
'data_points': [],
|
||||||
@@ -173,7 +170,7 @@ def get_genre_data(request, user_secret):
|
|||||||
"""Return genre data needed to create the graph user.
|
"""Return genre data needed to create the graph user.
|
||||||
TODO
|
TODO
|
||||||
"""
|
"""
|
||||||
user = User.objects.get(user_secret=user_secret)
|
user = User.objects.get(secret=user_secret)
|
||||||
genre_counts = (Track.objects.filter(users__exact=user)
|
genre_counts = (Track.objects.filter(users__exact=user)
|
||||||
.values('genre')
|
.values('genre')
|
||||||
.order_by('genre')
|
.order_by('genre')
|
||||||
|
|||||||
@@ -6,11 +6,10 @@
|
|||||||
<title>Artist Graphs</title>
|
<title>Artist Graphs</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<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/artist_graph.js" %}"></script>
|
<script src="{% static "graphs/scripts/artist_graph.js" %}"></script>
|
||||||
<script>
|
<script>
|
||||||
d3.json("{% url "get_artist_data" user_secret %}").then(function(data) {
|
d3.json("{% url "api:get_artist_data" user_secret %}").then(function(data) {
|
||||||
for (let index = 0; index < data.length; index++) {
|
for (let index = 0; index < data.length; index++) {
|
||||||
console.log(data[index].name);
|
console.log(data[index].name);
|
||||||
console.log(data[index].num_songs);
|
console.log(data[index].num_songs);
|
||||||
@@ -24,4 +23,4 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
<!--[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 {{ user_id }}</p>
|
|
||||||
<script src="https://d3js.org/d3.v5.js"></script>
|
<script src="https://d3js.org/d3.v5.js"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<title>Test DB Page</title>
|
<title>Test DB Page</title>
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="stylesheet" href="{% static 'spotifyvis/css/dark_bg.css' %}">
|
<link rel="stylesheet" href="{% static 'css/dark_bg.css' %}">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<!-- }}} header -->
|
<!-- }}} header -->
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
<script src="https://d3js.org/d3.v5.min.js"></script>
|
<script src="https://d3js.org/d3.v5.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/randomcolor/0.5.2/randomColor.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/randomcolor/0.5.2/randomColor.min.js"></script>
|
||||||
{% load static %}
|
{% load static %}
|
||||||
<script src="{% static "spotifyvis/scripts/genre_graph.js" %}"></script>
|
<script src="{% static "graphs/scripts/genre_graph.js" %}"></script>
|
||||||
|
|
||||||
<svg width="1920" height="740"></svg>
|
<svg width="1920" height="740"></svg>
|
||||||
<script>
|
<script>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
var y = d3.scaleLinear()
|
var y = d3.scaleLinear()
|
||||||
.rangeRound([height, 0]);
|
.rangeRound([height, 0]);
|
||||||
|
|
||||||
d3.json("{% url "get_genre_data" user_secret %}").then(create_genre_graph);
|
d3.json("{% url "api:get_genre_data" user_secret %}").then(create_genre_graph);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -9,11 +9,11 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>{{ user_id }}'s Graphs</h1>
|
<h1>{{ user_id }}'s Graphs</h1>
|
||||||
<a class="btn btn-primary" href=""
|
<a class="btn btn-primary" href="{% url "graphs:display_audio_features" user_secret %}"
|
||||||
role="button">Audio Features</a>
|
role="button">Audio Features</a>
|
||||||
<a class="btn btn-primary" href=""
|
<a class="btn btn-primary" href="{% url "graphs:display_genre_graph" user_secret %}"
|
||||||
role="button">Genres</a>
|
role="button">Genres</a>
|
||||||
<a class="btn btn-primary" href="" role="button">
|
<a class="btn btn-primary" href="{% url "graphs:display_artist_graph" user_secret %}" role="button">
|
||||||
Artists
|
Artists
|
||||||
</a>
|
</a>
|
||||||
</body>
|
</body>
|
||||||
@@ -4,10 +4,10 @@ from .views import *
|
|||||||
|
|
||||||
app_name = 'graphs'
|
app_name = 'graphs'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('artists/<str:user_secret>', artist_data,
|
path('artists/<str:user_secret>', display_artist_graph,
|
||||||
name='display_artist_graph'),
|
name='display_artist_graph'),
|
||||||
path('genre/<str:user_secret>', display_genre_graph,
|
path('genre/<str:user_secret>', display_genre_graph,
|
||||||
name='display_genre_graph'),
|
name='display_genre_graph'),
|
||||||
path('audio_features/<str:user_secret>', audio_features,
|
path('audio_features/<str:user_secret>', display_features_graphs,
|
||||||
name='display_audio_features'),
|
name='display_audio_features'),
|
||||||
]
|
]
|
||||||
|
|||||||
8
graphs/utils.py
Normal file
8
graphs/utils.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
def get_secret_context(user_secret):
|
||||||
|
"""Return user_secret in context for graph pages.
|
||||||
|
|
||||||
|
:user_secret: User secret to put in context.
|
||||||
|
:returns: context with user secret.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return { 'user_secret': user_secret, }
|
||||||
@@ -11,41 +11,32 @@ import string
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
|
from .utils import *
|
||||||
|
|
||||||
# }}} imports #
|
# }}} imports #
|
||||||
|
|
||||||
def artist_data(request, user_secret):
|
def display_artist_graph(request, user_secret):
|
||||||
"""Renders the artist data graph display page
|
"""Renders the artist data graph display page
|
||||||
|
|
||||||
:param request: the HTTP request
|
:param request: the HTTP request
|
||||||
:param user_secret: the user secret used for identification
|
:param user_secret: the user secret used for identification
|
||||||
:return: render the artist data graph display page
|
:return: render the artist data graph display page
|
||||||
"""
|
"""
|
||||||
user = User.objects.get(user_secret=user_secret)
|
return render(request, "graphs/artist_graph.html",
|
||||||
context = {
|
get_secret_context(user_secret))
|
||||||
'user_id': user.user_id,
|
|
||||||
'user_secret': user_secret,
|
|
||||||
}
|
|
||||||
return render(request, "spotifyvis/artist_graph.html", context)
|
|
||||||
|
|
||||||
def display_genre_graph(request, user_secret):
|
def display_genre_graph(request, user_secret):
|
||||||
user = User.objects.get(user_secret=user_secret)
|
return render(request, "graphs/genre_graph.html",
|
||||||
context = {
|
get_secret_context(user_secret))
|
||||||
'user_secret': user_secret,
|
|
||||||
}
|
|
||||||
return render(request, "spotifyvis/genre_graph.html", context)
|
|
||||||
|
|
||||||
|
|
||||||
def audio_features(request, user_secret):
|
def display_features_graphs(request, user_secret):
|
||||||
"""Renders the audio features page
|
"""Renders the audio features page
|
||||||
|
|
||||||
:param request: the HTTP request
|
:param request: the HTTP request
|
||||||
:param user_secret: user secret used for identification
|
:param user_secret: user secret used for identification
|
||||||
:return: renders the audio features page
|
:return: renders the audio features page
|
||||||
"""
|
"""
|
||||||
user = User.objects.get(user_secret=user_secret)
|
return render(request, "graphs/features_graphs.html",
|
||||||
context = {
|
get_secret_context(user_secret))
|
||||||
'user_id': user.user_id,
|
|
||||||
'user_secret': user_secret,
|
|
||||||
}
|
|
||||||
return render(request, "spotifyvis/audio_features.html", context)
|
|
||||||
|
|||||||
10
login/utils.py
Normal file
10
login/utils.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
from .models import User
|
||||||
|
|
||||||
|
def get_user_context(user_obj):
|
||||||
|
"""Get context for rendering with User's ID and secret.
|
||||||
|
|
||||||
|
:user_obj: User object to make context for.
|
||||||
|
:returns: context to pass back to HTML file.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return { 'user_id': user_obj.id, 'user_secret': user_obj.secret, }
|
||||||
@@ -13,6 +13,7 @@ from datetime import datetime
|
|||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
from django.http import HttpResponseBadRequest
|
from django.http import HttpResponseBadRequest
|
||||||
from .models import *
|
from .models import *
|
||||||
|
from .utils import *
|
||||||
|
|
||||||
# }}} imports #
|
# }}} imports #
|
||||||
|
|
||||||
@@ -94,11 +95,7 @@ def callback(request):
|
|||||||
token_response['access_token'],
|
token_response['access_token'],
|
||||||
token_response['expires_in'])
|
token_response['expires_in'])
|
||||||
|
|
||||||
context = {
|
return render(request, 'login/scan.html', get_user_context(user_obj))
|
||||||
'user_id': user_obj.id,
|
|
||||||
'user_secret': user_obj.secret,
|
|
||||||
}
|
|
||||||
return render(request, 'login/scan.html', context)
|
|
||||||
# return redirect('user/' + user_obj.secret)
|
# return redirect('user/' + user_obj.secret)
|
||||||
|
|
||||||
|
|
||||||
@@ -139,12 +136,7 @@ def admin_graphs(request):
|
|||||||
"""
|
"""
|
||||||
user_id = "polarbier"
|
user_id = "polarbier"
|
||||||
# user_id = "chrisshyi13"
|
# user_id = "chrisshyi13"
|
||||||
user_obj = User.objects.get(user_id=user_id)
|
user_obj = User.objects.get(id=user_id)
|
||||||
context = {
|
return render(request, 'graphs/logged_in.html', get_user_context(user_obj))
|
||||||
'user_id': user_id,
|
|
||||||
'user_secret': user_obj.user_secret,
|
|
||||||
}
|
|
||||||
update_track_genres(user_obj)
|
|
||||||
return render(request, 'login/logged_in.html', context)
|
|
||||||
|
|
||||||
# }}} admin_graphs #
|
# }}} admin_graphs #
|
||||||
|
|||||||
Reference in New Issue
Block a user