/
api.py
174 lines (135 loc) · 4.64 KB
/
api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
from flask import Flask, request, json, jsonify
from knapsack import knapsack
import requests
from base64 import b64encode
from crossdomain import crossdomain
from random import shuffle
import apikeys as keys
PLAYLISTS = [
{
'playlist_name': "Feel Good Indie Rock",
'playlist_id': "0XUlpafP8eIlIWt3VHSd7q",
'user_id': "spotify",
},
{
'playlist_name': "Have a Great Day!",
'playlist_id': "2PXdUld4Ueio2pHcB6sM8j",
'user_id': "spotify",
},
{
'playlist_name': "Teen Pop!",
'playlist_id': "445ES7sgFV8zJHebmbUW0L",
'user_id': "spotify",
},
{
'playlist_name': "Epic Party",
'playlist_id': "5cdgwETxybr7tWcr7RTiCO",
'user_id': "spotify",
},
{
'playlist_name': "Afternoon Acoustic",
'playlist_id': "16BpjqQV1Ey0HeDueNDSYz",
'user_id': "spotify",
},
{
'playlist_name': "Good Vibes",
'playlist_id': "3xgbBiNc7mh3erYsCl8Fwg",
'user_id': "spotify",
},
{
'playlist_name': "Schubert",
'playlist_id': "0GaR6RZtSLpnbuLEbHwlwt",
'user_id': "1210136629",
},
]
app = Flask(__name__)
def find_userID(playlist_id):
user_id = "spotify"
for playlist in PLAYLISTS: # look up user id
if playlist['playlist_id'] == playlist_id:
user_id = playlist['user_id']
return user_id
""" Authorizes session with Spotify
returns: Spotify access token
"""
def authorize_spotify():
apiKeys = keys.keysObject()
url = "https://accounts.spotify.com/api/token"
payload = {
'grant_type': 'client_credentials',
}
client = b64encode(apiKeys.clientID + ':' + apiKeys.secretID)
headers = {
'Authorization': 'Basic %s' % client,
}
response = requests.post(url=url, data=payload, headers=headers)
return response.json()['access_token']
def call_spotify_api_get(url, access_token=None):
access_token = access_token or authorize_spotify()
headers = {
'Authorization': 'Bearer %s' % access_token,
}
return requests.get(url=url, headers=headers)
def get_tracks(playlist_id, user_id):
url_base = "https://api.spotify.com/v1/users/%s/playlists/%s/tracks"
response = call_spotify_api_get(url_base % (user_id, playlist_id))
try:
tracks = response.json()['items']
except:
raise Exception("Spotify error: %s" % response.status_code)
return tracks
""" Run knapsack algorithm for list of tracks
Parameters:
tracks: total pool of tracks to choose songs from
returns: serialized json of desired tracklist
"""
def knapsack_from_tracks(tracks, duration):
shuffle(tracks)
lengths = [item['track']['duration_ms'] / 1000 for item in tracks]
tracks_to_play = []
if sum(lengths) <= int(duration): # Trivial case
tracks_to_play = tracks
else:
indices_to_play = knapsack(lengths, lengths, len(lengths), int(duration))
tracks_to_play = [tracks[i] for i in indices_to_play]
play_length = sum(lengths[i] for i in indices_to_play)
print "target: %s\nachieved: %s\n" % (duration, play_length)
shuffle(tracks_to_play)
return jsonify(tracklist=tracks_to_play)
@app.route('/')
@crossdomain(origin='*')
def index():
return 'This is the API server for <a href="http://playinti.me">inTime</a>! Check out our documentation <a href="https://github.com/play-in-time/backend/blob/master/README.md">here</a>.'
@app.route('/tracks_for_duration')
@crossdomain(origin='*')
def tracks_for_duration():
playlist_id = request.args.get('playlist_id')
user_id = find_userID(playlist_id)
duration = request.args.get('duration')
tracks = get_tracks(playlist_id, user_id)
return knapsack_from_tracks(tracks, duration)
@app.route('/update_tracklist', methods=['POST'])
@crossdomain(origin='*')
def update_tracklist():
post_info = request.get_json(force=True)
playlist_id = post_info['id']
user_id = find_userID(playlist_id)
time_left = post_info['duration']
songs_played = post_info['played']
tracks = get_tracks(playlist_id, user_id)
tracks_not_used = [item for item in tracks if item not in songs_played]
return knapsack_from_tracks(tracks_not_used, time_left)
@app.route('/just_play')
@crossdomain(origin='*')
def just_play():
duration = request.args.get('duration')
tracks = []
for playlist in PLAYLISTS:
tracks.extend(get_tracks(playlist['playlist_id'], playlist['user_id']))
return knapsack_from_tracks(tracks, duration)
@app.route('/playlists')
@crossdomain(origin='*')
def playlists():
return jsonify({'playlists': PLAYLISTS})
if __name__ == '__main__':
app.run(debug=True)