-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
136 lines (120 loc) · 4.16 KB
/
main.py
File metadata and controls
136 lines (120 loc) · 4.16 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
# forked from albumcovers/spotify
import os
from flask import Flask, render_template, jsonify, redirect, request
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from spotipy.cache_handler import CacheHandler
class CustomCacheHandler(CacheHandler):
def get_cached_token(self):
return None
def save_token_to_cache(self, token_info):
pass
# load configuration from environment for security
USERNAME = os.getenv('SPOTIFY_USERNAME')
SCOPE = 'user-read-currently-playing'
REDIRECT_URI = os.getenv('SPOTIFY_REDIRECT_URI')
CLIENT_ID = os.getenv('SPOTIFY_CLIENT_ID')
CLIENT_SECRET = os.getenv('SPOTIFY_CLIENT_SECRET')
REFRESH_TOKEN = os.getenv('SPOTIFY_REFRESH_TOKEN')
app = Flask(__name__)
# add cors headers after every request for /api/*
@app.after_request
def add_cors_headers(response):
if request.path.startswith('/api/'):
response.headers['access-control-allow-origin'] = '*'
response.headers['access-control-allow-methods'] = 'GET, OPTIONS'
response.headers['access-control-allow-headers'] = 'Content-Type'
return response
def get_access_token():
"""
exchange stored REFRESH_TOKEN for a fresh access token.
returns the access token string, or None on failure.
"""
if not all([CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, REDIRECT_URI]):
return None
oauth = SpotifyOAuth(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
scope=SCOPE,
show_dialog=False,
cache_handler=CustomCacheHandler()
)
token_info = oauth.refresh_access_token(REFRESH_TOKEN)
return token_info.get('access_token')
def fetch_currently_playing():
"""
fetch user’s currently playing item with fresh token.
returns the JSON dict or None if nothing playing or error.
"""
access_token = get_access_token()
if not access_token:
return None
spotify = spotipy.Spotify(auth=access_token)
try:
playing = spotify.currently_playing()
except Exception:
return None
if not playing or not playing.get('item'):
return None
return playing['item']
@app.route('/')
def index():
"""
main page: shows user’s current track.
anyone visiting sees the same info.
"""
item = fetch_currently_playing()
if not item:
return render_template(
'index.html',
title='nothing playing',
artist='no one',
final_image_url='https://i.pinimg.com/564x/46/46/dd/4646dd0ebb3f008253e4deea38d233de--emoji-emoticons-emojis.jpg'
)
artist = item['artists'][0]['name']
track = item['name']
image_url = item['album']['images'][0]['url']
return render_template(
'index.html',
title=track,
artist=artist,
final_image_url=image_url
)
def make_simple_api(field_path):
"""
returns a view that drills into item via field_path.
"""
def view():
item = fetch_currently_playing()
if not item:
return jsonify(error='nothing playing'), 204
data = item
for key in field_path:
data = data[key]
return data
return view
# public API routes for title, artist, image
app.add_url_rule('/api/title', 'api_title', make_simple_api(['name']), methods=['GET'])
app.add_url_rule('/api/artist', 'api_artist', make_simple_api(['artists',0,'name']), methods=['GET'])
app.add_url_rule('/api/image', 'api_image', make_simple_api(['album','images',0,'url']), methods=['GET'])
@app.errorhandler(500)
def internal_error(error):
ep = request.endpoint
if ep == 'api_title':
return 'nothing', 200
if ep == 'api_artist':
return 'no one', 200
if ep == 'api_image':
return jsonify(error='no image'), 200
return render_template(
'index.html',
title='nothing',
artist='no one',
final_image_url='https://i.pinimg.com/564x/46/46/dd/4646dd0ebb3f008253e4deea38d233de--emoji-emoticons-emojis.jpg'
), 200
@app.errorhandler(404)
def not_found(error):
return redirect('/'), 302
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)