-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
179 lines (150 loc) · 5.33 KB
/
app.py
File metadata and controls
179 lines (150 loc) · 5.33 KB
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
174
175
176
177
178
179
import os
import spotipy
import time
from datetime import datetime
from dotenv import load_dotenv
from flask import Flask, jsonify, redirect, request, session, render_template
from generate import create_songlist, cut_playlist, generate_playlist, get_dates, set_default_art
from spotipy.oauth2 import SpotifyOAuth
load_dotenv()
# Configure application
app = Flask(__name__)
app.secret_key = os.getenv("FLASK_SECRET_KEY")
client_id=os.getenv('SPOTIFY_CLIENT_ID')
client_secret=os.getenv('SPOTIFY_CLIENT_SECRET')
redirect_uri=os.getenv('SPOTIFY_REDIRECT_URI')
scope=os.getenv('SPOTIFY_SCOPE')
chart_dict = {
"Hot 100": {
"name": "hot100.csv"
},
"Billboard 200": {
"name": "billboard200.csv"
},
"Digital Songs": {
"name": "digital_songs.csv"
},
"Radio": {
"name": "radio.csv"
},
"Streaming Songs": {
"name": "streaming_songs.csv"
}
}
for key in chart_dict:
chart = chart_dict[key]
dates = get_dates(chart["name"])
chart["min"], chart["max"] = dates[0], dates[1]
@app.route("/")
def index():
username = session.get('username')
return render_template("index.html", chart_dict=chart_dict, username=username)
@app.route("/generate", methods=["POST"])
def generate():
# Receive form info from JS
data = request.get_json()
try:
csv = chart_dict[data['chart']]
except KeyError:
return jsonify({"success": False, "error": "Invalid Chart. Try Again."}), 400
chart = csv['name']
start = data['start']
end = data['end']
name = data['name']
amount = data['amount']
omit = data['omit']
if not name:
name = f"Top {amount} songs from Billboard's {data['chart']} chart from {start} to {end}"
try:
start_date = datetime.strptime(start, "%Y-%m-%d")
except ValueError:
return jsonify({"success": False, "error": "Invalid Start Date. Try Again."}), 400
try:
end_date = datetime.strptime(end, "%Y-%m-%d")
except ValueError:
return jsonify({"success": False, "error": "Invalid End Date. Try Again."}), 400
date_min = datetime.strptime(csv['min'], "%Y-%m-%d")
date_max = datetime.strptime(csv['max'], "%Y-%m-%d")
if start is None or start_date < date_min or start_date > date_max:
return jsonify({"success": False, "error": "Invalid Start Date. Try Again."}), 400
if end is None or end_date < date_min or end_date > date_max:
return jsonify({"success": False, "error": "Invalid End Date. Try Again."}), 400
if start_date > end_date:
return jsonify({"success": False, "error": "Invalid Date Range. Try Again."}), 400
if amount is None or isinstance(amount, float) or amount <= 0:
return jsonify({"success": False, "error": "Invalid Song Amount. Try Again."}), 400
print(omit)
songs = create_songlist(start, end, chart, amount, omit)
if len(songs) > amount:
print("Playlist too large, cutting process starting")
cut_playlist(songs, amount)
set_default_art(songs)
return jsonify({
"success": True,
"chart": chart,
"startDate": start,
"endDate": end,
"playlistName": name,
"songAmount": amount,
"songs": songs
})
@app.route("/add", methods=["POST"])
def add():
data = request.get_json()
songs = data['songs']
name = data['name']
omit = data['omit']
token_info = get_token()
if not token_info:
return jsonify({"success": False, "error": "Not logged in"}), 401
sp = spotipy.Spotify(auth=token_info["access_token"])
gp = generate_playlist(songs, sp, omit)
uri, failed = gp[0], gp[1]
username = session['username']
playlist = sp.user_playlist_create(username, name, public=False)
for i in range(0, len(uri), 100):
sp.playlist_add_items(playlist["id"], uri[i:i+100])
return jsonify({"success": True, "failed": failed})
def get_spotify_oauth():
return SpotifyOAuth(
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
scope=scope,
cache_path=None,
show_dialog=True
)
def get_token():
token_info = session.get("token_info", None)
if not token_info:
return None # user not logged in
now = int(time.time())
# If expired, refresh it
if token_info["expires_at"] - now < 60: # expires in <60 sec
sp_oauth = get_spotify_oauth()
token_info = sp_oauth.refresh_access_token(token_info["refresh_token"])
session["token_info"] = token_info # save updated token
return token_info
@app.route("/login")
def login():
sp_oauth = get_spotify_oauth()
url = sp_oauth.get_authorize_url()
return redirect(url)
@app.route("/logout")
def logout():
session.clear()
return redirect("/")
@app.route("/callback")
def callback():
sp_oauth = get_spotify_oauth()
code = request.args.get("code")
if code is None:
return redirect("/?error=access_denied")
token_info = sp_oauth.get_access_token(code, as_dict=True)
session["token_info"] = token_info
sp = spotipy.Spotify(auth=token_info["access_token"])
profile = sp.current_user()
session["username"] = profile["display_name"]
session["user_id"] = profile["id"]
session["profile_pic"] = profile["images"][0]["url"] if profile["images"] else None
return redirect("/")