Browse Source
Merge pull request #27 from chrisshyi/master
Merge pull request #27 from chrisshyi/master
Merging bug fix for missing audio features in Spotify databasemaster
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 254 additions and 20 deletions
-
3.gitignore
-
8musicvis/settings.py
-
1requirements.txt
-
85spotifyvis/migrations/0001_initial.py
-
65spotifyvis/models.py
-
42spotifyvis/static/spotifyvis/scripts/index.js
-
0spotifyvis/static/spotifyvis/scripts/user_data.js
-
14spotifyvis/templates/spotifyvis/index.html
-
8spotifyvis/templates/spotifyvis/user_data.html
-
25spotifyvis/utils.py
-
21spotifyvis/views.py
@ -0,0 +1,85 @@ |
|||||
|
# Generated by Django 2.0.5 on 2018-06-03 23:01 |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
import django.db.models.deletion |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
initial = True |
||||
|
|
||||
|
dependencies = [ |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.CreateModel( |
||||
|
name='Artist', |
||||
|
fields=[ |
||||
|
('artist_id', models.CharField(max_length=30, primary_key=True, serialize=False)), |
||||
|
('name', models.CharField(max_length=50, unique=True)), |
||||
|
('genre', models.CharField(max_length=20)), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Artist', |
||||
|
'verbose_name_plural': 'Artists', |
||||
|
}, |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='Track', |
||||
|
fields=[ |
||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
||||
|
('track_id', models.CharField(max_length=30)), |
||||
|
('year', models.PositiveSmallIntegerField()), |
||||
|
('popularity', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
('runtime', models.PositiveSmallIntegerField()), |
||||
|
('name', models.CharField(max_length=75)), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'Track', |
||||
|
'verbose_name_plural': 'Tracks', |
||||
|
}, |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='User', |
||||
|
fields=[ |
||||
|
('user_id', models.CharField(max_length=30, primary_key=True, serialize=False)), |
||||
|
('username', models.CharField(max_length=30)), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'User', |
||||
|
'verbose_name_plural': 'Users', |
||||
|
}, |
||||
|
), |
||||
|
migrations.CreateModel( |
||||
|
name='AudioFeatures', |
||||
|
fields=[ |
||||
|
('track', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='spotifyvis.Track')), |
||||
|
('danceability', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
('energy', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
('loudness', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
('speechiness', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
('acousticness', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
('instrumentalness', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
('valence', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
('tempo', models.DecimalField(decimal_places=2, max_digits=2)), |
||||
|
], |
||||
|
options={ |
||||
|
'verbose_name': 'AudioFeatures', |
||||
|
'verbose_name_plural': 'AudioFeatures', |
||||
|
}, |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='track', |
||||
|
name='artist', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='spotifyvis.Artist'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='track', |
||||
|
name='users', |
||||
|
field=models.ManyToManyField(to='spotifyvis.User'), |
||||
|
), |
||||
|
migrations.AlterUniqueTogether( |
||||
|
name='track', |
||||
|
unique_together={('track_id', 'artist')}, |
||||
|
), |
||||
|
] |
@ -1,3 +1,66 @@ |
|||||
from django.db import models |
from django.db import models |
||||
|
|
||||
# Create your models here. |
|
||||
|
|
||||
|
class Artist(models.Model): |
||||
|
class Meta: |
||||
|
verbose_name = "Artist" |
||||
|
verbose_name_plural = "Artists" |
||||
|
|
||||
|
artist_id = models.CharField(primary_key=True, max_length=30) |
||||
|
# unique since only storing one genre per artist right now |
||||
|
name = models.CharField(unique=True, max_length=50) |
||||
|
genre = models.CharField(max_length=20) |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.name |
||||
|
|
||||
|
|
||||
|
class User(models.Model): |
||||
|
class Meta: |
||||
|
verbose_name = "User" |
||||
|
verbose_name_plural = "Users" |
||||
|
|
||||
|
user_id = models.CharField(primary_key=True, max_length=30) # the user's Spotify ID |
||||
|
username = models.CharField(max_length=30) # User's Spotify user name, if set |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.username |
||||
|
|
||||
|
|
||||
|
class Track(models.Model): |
||||
|
|
||||
|
class Meta: |
||||
|
verbose_name = "Track" |
||||
|
verbose_name_plural = "Tracks" |
||||
|
unique_together = ('track_id', 'artist',) |
||||
|
|
||||
|
track_id = models.CharField(max_length=30) |
||||
|
artist = models.ForeignKey(Artist, on_delete=models.CASCADE) |
||||
|
year = models.PositiveSmallIntegerField() |
||||
|
popularity = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
runtime = models.PositiveSmallIntegerField() |
||||
|
name = models.CharField(max_length=75) |
||||
|
users = models.ManyToManyField(User) |
||||
|
|
||||
|
def __str__(self): |
||||
|
return self.name |
||||
|
|
||||
|
|
||||
|
class AudioFeatures(models.Model): |
||||
|
|
||||
|
class Meta: |
||||
|
verbose_name = "AudioFeatures" |
||||
|
verbose_name_plural = "AudioFeatures" |
||||
|
|
||||
|
track = models.OneToOneField(Track, on_delete=models.CASCADE, primary_key=True,) |
||||
|
danceability = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
energy = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
loudness = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
speechiness = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
acousticness = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
instrumentalness = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
valence = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
tempo = models.DecimalField(decimal_places=2, max_digits=2) |
||||
|
|
||||
|
def __str__(self): |
||||
|
return super(AudioFeatures, self).__str__() |
@ -0,0 +1,42 @@ |
|||||
|
document.getElementById("login-btn").addEventListener("click", function() { |
||||
|
let httpRequest = new XMLHttpRequest(); |
||||
|
|
||||
|
/* |
||||
|
* Handler for the response |
||||
|
*/ |
||||
|
httpRequest.onreadystatechange = function() { |
||||
|
if (httpRequest.readyState === XMLHttpRequest.DONE) { |
||||
|
if (httpRequest.status === 200) { |
||||
|
// hide the login button
|
||||
|
document.getElementById('login').setAttribute("display", "none"); |
||||
|
|
||||
|
let responseData = JSON.parse(httpRequest.responseText); |
||||
|
let dataList = document.getElementById("data-list"); |
||||
|
|
||||
|
|
||||
|
for (let key in responseData) { |
||||
|
let newLi = document.createElement("li"); |
||||
|
let innerList = document.createElement("ul"); |
||||
|
|
||||
|
let dataLabel = document.createElement("li"); |
||||
|
dataLabel.innerText = key; |
||||
|
|
||||
|
let dataValue = document.createElement("li"); |
||||
|
dataValue.innerText = responseData[key]; |
||||
|
|
||||
|
innerList.appendChild(dataLabel); |
||||
|
innerList.appendChild(dataValue); |
||||
|
|
||||
|
newLi.appendChild(innerList); |
||||
|
dataList.appendChild(newLi); |
||||
|
} |
||||
|
} else { |
||||
|
alert("There was a problem with the login request, please try again!"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
httpRequest.open('GET', '/login', true); |
||||
|
httpRequest.send(); |
||||
|
}); |
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue