187 lines
6.7 KiB
Python
187 lines
6.7 KiB
Python
from flask import Flask, render_template, request, url_for, redirect, send_from_directory
|
|
import requests
|
|
from urllib.parse import urlencode
|
|
import base64
|
|
import os
|
|
import _canvas as SpotifyCanvas
|
|
import time
|
|
import syncedlyrics
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
client_id = '1cb8bc27872c4bcaaad0e95f123b4f7d'
|
|
client_secret = '9893dfb6d9eb43eebf082f9173ce937c'
|
|
redirect_uri = 'http://127.0.0.1:8888/callback'
|
|
encoded_creds = base64.b64encode(client_id.encode() + b':' + client_secret.encode()).decode("utf-8")
|
|
|
|
|
|
headers = {
|
|
"client_id": client_id,
|
|
"response_type": "code",
|
|
"redirect_uri": redirect_uri,
|
|
"scope": "user-read-playback-state,user-modify-playback-state,user-library-read,user-library-modify"
|
|
}
|
|
|
|
token_headers = {
|
|
"Authorization": "Basic " + encoded_creds,
|
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
}
|
|
|
|
data = {
|
|
'name': "Loading...",
|
|
'artist': "",
|
|
'album': "",
|
|
'image': "https://cdn.pixabay.com/animation/2023/05/02/04/29/04-29-03-511_512.gif"
|
|
}
|
|
|
|
@app.route('/')
|
|
def index():
|
|
global code
|
|
if os.path.exists('code'):
|
|
with open('code', 'r') as file:
|
|
code = file.read()
|
|
return redirect(url_for('webapp'))
|
|
else:
|
|
return redirect("https://accounts.spotify.com/authorize?" + urlencode(headers))
|
|
# return render_template('index.html')
|
|
|
|
# @app.route('/update')
|
|
# def update():
|
|
# # Generate new information
|
|
# new_info = generate_new_info()
|
|
|
|
# # Wait for 1 second
|
|
# time.sleep(1)
|
|
|
|
# return new_info
|
|
|
|
@app.route('/webapp', methods=['GET', 'POST'])
|
|
def webapp():
|
|
global access_token
|
|
# NEED TO FIND A BETTER WAY THAT DOESN'T INVOLVE A TRY EXCEPT BLOCK
|
|
if 'code' not in globals() or not code:
|
|
return redirect(url_for('index'))
|
|
token_data = {
|
|
"grant_type": "authorization_code",
|
|
"code": code,
|
|
"redirect_uri": redirect_uri
|
|
}
|
|
|
|
access_object = requests.post("https://accounts.spotify.com/api/token", data=token_data, headers=token_headers)
|
|
if "error" in access_object.json():
|
|
if os.path.exists('code'):
|
|
os.remove('code')
|
|
return redirect(url_for('index'))
|
|
access_token = access_object.json()["access_token"]
|
|
|
|
return render_template('webapp.html', data=data)
|
|
|
|
@app.route('/callback', methods=['GET'])
|
|
def callback():
|
|
global code
|
|
code = request.args.get('code')
|
|
with open('code', 'w') as file:
|
|
file.write(code)
|
|
return redirect(url_for('webapp'))
|
|
|
|
@app.route('/appdata')
|
|
def appdata():
|
|
global access_token
|
|
stime = time.time()
|
|
try:
|
|
user_headers = {
|
|
"Authorization": "Bearer " + access_token,
|
|
"Content-Type": "application/json"
|
|
}
|
|
except NameError:
|
|
return { 'reload': True }
|
|
|
|
currently_playing = requests.get("https://api.spotify.com/v1/me/player/currently-playing", headers=user_headers)
|
|
if currently_playing.content:
|
|
if currently_playing.json()["is_playing"] is True and currently_playing.json()["item"]["id"] == request.args.get('id'):
|
|
print("QUICK" + str(time.time() - stime))
|
|
return { 'progress_ms': currently_playing.json()["progress_ms"],
|
|
}
|
|
elif currently_playing.json()["is_playing"] is True and currently_playing.json()["item"]["id"] != request.args.get('id'):
|
|
print("FULL" + str(time.time() - stime))
|
|
return { 'id': currently_playing.json()["item"]["id"],
|
|
'name': currently_playing.json()["item"]["name"],
|
|
'artist': currently_playing.json()["item"]["artists"][0]["name"],
|
|
'album': currently_playing.json()["item"]["album"]["name"],
|
|
'image': currently_playing.json()["item"]["album"]["images"][0]["url"],
|
|
'is_playing': currently_playing.json()["is_playing"],
|
|
'progress_ms': currently_playing.json()["progress_ms"],
|
|
'duration_ms': currently_playing.json()["item"]["duration_ms"],
|
|
'is_liked': requests.get("https://api.spotify.com/v1/me/tracks/contains?ids=" + currently_playing.json()["item"]["id"], headers=user_headers).json()[0],
|
|
'canvas': False,
|
|
'fetchlyrics': 'fetch'
|
|
}
|
|
elif currently_playing.json()["is_playing"] is False:
|
|
return { 'is_playing': False
|
|
}
|
|
else:
|
|
return { 'name': "Error",
|
|
'artist': "Error"
|
|
}
|
|
else:
|
|
return { 'is_playing': False
|
|
}
|
|
|
|
@app.route('/control', methods=['POST'])
|
|
def control():
|
|
global access_token
|
|
user_headers = {
|
|
"Authorization": "Bearer " + access_token,
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
if request.form.get('command') == "pause":
|
|
requests.put("https://api.spotify.com/v1/me/player/pause", headers=user_headers)
|
|
return { 'is_playing': False }
|
|
elif request.form.get('command') == "play":
|
|
requests.put("https://api.spotify.com/v1/me/player/play", headers=user_headers)
|
|
return { 'is_playing': True }
|
|
elif request.form.get('command') == "next":
|
|
requests.post("https://api.spotify.com/v1/me/player/next", headers=user_headers)
|
|
elif request.form.get('command') == "previous":
|
|
requests.post("https://api.spotify.com/v1/me/player/previous", headers=user_headers)
|
|
elif request.form.get('command') == "restart":
|
|
requests.put("https://api.spotify.com/v1/me/player/seek?position_ms=0", headers=user_headers)
|
|
elif request.form.get('command') == "like":
|
|
requests.put("https://api.spotify.com/v1/me/tracks?ids=" + request.form.get('id'), headers=user_headers)
|
|
return { 'is_liked': True }
|
|
elif request.form.get('command') == "unlike":
|
|
requests.delete("https://api.spotify.com/v1/me/tracks?ids=" + request.form.get('id'), headers=user_headers)
|
|
return { 'is_liked': False }
|
|
|
|
print(request.form.get('command'))
|
|
return ('', 204)
|
|
|
|
@app.route('/icons/<path:filename>')
|
|
def icons(filename):
|
|
return send_from_directory('icons', filename)
|
|
|
|
@app.route('/canvas')
|
|
def canvas():
|
|
print("CANVAS")
|
|
id = request.args.get('id')
|
|
try:
|
|
return { 'canvas_url': SpotifyCanvas.get_canvas_for_track(SpotifyCanvas.get_access_token(), id) }
|
|
except AttributeError:
|
|
return { 'canvas_url': None }
|
|
|
|
@app.route('/lyrics')
|
|
def lyrics():
|
|
name = request.args.get('name')
|
|
artist = request.args.get('artist')
|
|
if name and artist is not None:
|
|
full_lyrics = syncedlyrics.search("[" + name + "] [" + artist + "]")
|
|
else:
|
|
return { 'lyrics': '' }
|
|
if full_lyrics is None:
|
|
return { 'lyrics': "no lyrics" }
|
|
return { 'lyrics': full_lyrics }
|
|
|
|
if __name__ == '__main__':
|
|
app.run(port=8888, debug=True) |