From 8a1f4197f20564e50fb7c97102d4fcf9b292aad0 Mon Sep 17 00:00:00 2001 From: novatorem Date: Sat, 18 Jul 2020 10:16:03 -0400 Subject: [PATCH] Adding spotify --- README.md | 17 +--- api/date.py | 11 +++ api/requirements.txt | 3 + api/spotify-playing.py | 216 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+), 16 deletions(-) create mode 100644 api/date.py create mode 100644 api/requirements.txt create mode 100644 api/spotify-playing.py diff --git a/README.md b/README.md index b6850ec..934ecb6 100644 --- a/README.md +++ b/README.md @@ -1,16 +1 @@ -### Hi there šŸ‘‹ - - +[Spotify](https://novatorem.vercel.app/api/spotify-playing) \ No newline at end of file diff --git a/api/date.py b/api/date.py new file mode 100644 index 0000000..c142a84 --- /dev/null +++ b/api/date.py @@ -0,0 +1,11 @@ +from http.server import BaseHTTPRequestHandler +from datetime import datetime + +class handler(BaseHTTPRequestHandler): + + def do_GET(self): + self.send_response(200) + self.send_header('Content-type', 'text/plain') + self.end_headers() + self.wfile.write(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')).encode()) + return \ No newline at end of file diff --git a/api/requirements.txt b/api/requirements.txt new file mode 100644 index 0000000..4b21b4d --- /dev/null +++ b/api/requirements.txt @@ -0,0 +1,3 @@ +flask==1.1.2 +requests==2.24.0 +python-dotenv==0.14.0 \ No newline at end of file diff --git a/api/spotify-playing.py b/api/spotify-playing.py new file mode 100644 index 0000000..8440756 --- /dev/null +++ b/api/spotify-playing.py @@ -0,0 +1,216 @@ +from flask import Flask, Response, jsonify +from base64 import b64encode + +from dotenv import load_dotenv, find_dotenv + +load_dotenv(find_dotenv()) + +import requests +import json +import os +import random + +""" +Inspired from https://github.com/natemoo-re +""" + +print("Starting Server") + + +SPOTIFY_CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID") +SPOTIFY_SECRET_ID = os.getenv("SPOTIFY_SECRET_ID") +SPOTIFY_REFRESH_TOKEN = os.getenv("SPOTIFY_REFRESH_TOKEN") + +SPOTIFY_URL_REFRESH_TOKEN = "https://accounts.spotify.com/api/token" +SPOTIFY_URL_NOW_PLAYING = "https://api.spotify.com/v1/me/player/currently-playing" + +LATEST_PLAY = None +app = Flask(__name__) + + +def get_authorization(): + + return b64encode(f"{SPOTIFY_CLIENT_ID}:{SPOTIFY_SECRET_ID}".encode()).decode("ascii") + + +def refresh_token(): + + data = { + "grant_type": "refresh_token", + "refresh_token": SPOTIFY_REFRESH_TOKEN, + } + + headers = {"Authorization": "Basic {}".format(get_authorization())} + + response = requests.post(SPOTIFY_URL_REFRESH_TOKEN, data=data, headers=headers) + repsonse_json = response.json() + + return repsonse_json["access_token"] + + +def get_now_playing(): + + token = refresh_token() + + headers = {"Authorization": f"Bearer {token}"} + + response = requests.get(SPOTIFY_URL_NOW_PLAYING, headers=headers) + + if response.status_code == 204: + return {} + + repsonse_json = response.json() + return repsonse_json + + +def get_svg_template(): + + css_bar = "" + left = 1 + for i in range(1, 76): + + anim = random.randint(350, 500) + css_bar += ".bar:nth-child({}) {{{{ left: {}px; animation-duration: {}ms; }}}}".format( + i, left, anim + ) + left += 4 + + svg = ( + """ + + +
+ + {} +
+
+
+ """ + ) + return svg + + +def load_image_b64(url): + + resposne = requests.get(url) + return b64encode(resposne.content).decode("ascii") + + +def make_svg(data): + global LATEST_PLAY + + template = get_svg_template() + + text = "Now playing" + content_bar = "".join(["
" for i in range(75)]) + if data == {} and LATEST_PLAY is not None: + data = LATEST_PLAY + text = "Latest play" + content_bar = "" + elif data == {}: + content = """ +
Nothing playing on Spotify
+ """ + return template.format(content) + + content = """ +
{} on
+
{}
+
{}
+
+ {} +
+ +
+ +
+
+ """ + + item = data["item"] + + """ + print(json.dumps(item)) + print(item["artists"][0]["name"]) + print(item["external_urls"]["spotify"]) + print(item["album"]["images"][0]["url"]) + """ + + img = load_image_b64(item["album"]["images"][1]["url"]) + artist_name = item["artists"][0]["name"].replace("&", "&") + song_name = item["name"].replace("&", "&") + content_rendered = content.format( + text, + artist_name, + song_name, + content_bar, + item["external_urls"]["spotify"], + img, + ) + + return template.format(content_rendered) + + +@app.route("/", defaults={"path": ""}) +@app.route("/") +def catch_all(path): + global LATEST_PLAY + + # TODO: caching + + data = get_now_playing() + svg = make_svg(data) + + # cache lastest data + if data != {}: + LATEST_PLAY = data + + + resp = Response(svg, mimetype="image/svg+xml") + resp.headers["Cache-Control"] = "s-maxage=1" + + return resp + + +if __name__ == "__main__": + app.run(debug=True)