Dynamic realtime profile ReadMe linked with spotify
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
3.1 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. from flask import Flask, Response, jsonify, render_template
  2. from base64 import b64encode
  3. from dotenv import load_dotenv, find_dotenv
  4. load_dotenv(find_dotenv())
  5. import requests
  6. import json
  7. import os
  8. import random
  9. SPOTIFY_CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID")
  10. SPOTIFY_SECRET_ID = os.getenv("SPOTIFY_SECRET_ID")
  11. SPOTIFY_REFRESH_TOKEN = os.getenv("SPOTIFY_REFRESH_TOKEN")
  12. # scope user-read-currently-playing/user-read-recently-played
  13. SPOTIFY_URL_REFRESH_TOKEN = "https://accounts.spotify.com/api/token"
  14. SPOTIFY_URL_NOW_PLAYING = "https://api.spotify.com/v1/me/player/currently-playing"
  15. SPOTIFY_URL_RECENTLY_PLAY = "https://api.spotify.com/v1/me/player/recently-played?limit=10"
  16. app = Flask(__name__)
  17. def getAuth():
  18. return b64encode(f"{SPOTIFY_CLIENT_ID}:{SPOTIFY_SECRET_ID}".encode()).decode("ascii")
  19. def refreshToken():
  20. data = {
  21. "grant_type": "refresh_token",
  22. "refresh_token": SPOTIFY_REFRESH_TOKEN,
  23. }
  24. headers = {"Authorization": "Basic {}".format(getAuth())}
  25. response = requests.post(SPOTIFY_URL_REFRESH_TOKEN, data=data, headers=headers)
  26. return response.json()["access_token"]
  27. def recentlyPlayed():
  28. token = refreshToken()
  29. headers = {"Authorization": f"Bearer {token}"}
  30. response = requests.get(SPOTIFY_URL_RECENTLY_PLAY, headers=headers)
  31. if response.status_code == 204:
  32. return {}
  33. return response.json()
  34. def nowPlaying():
  35. token = refreshToken()
  36. headers = {"Authorization": f"Bearer {token}"}
  37. response = requests.get(SPOTIFY_URL_NOW_PLAYING, headers=headers)
  38. if response.status_code == 204:
  39. return {}
  40. return response.json()
  41. def barGen(barCount):
  42. barCSS = ""
  43. left = 1
  44. for i in range(1, barCount + 1):
  45. anim = random.randint(1000, 1350)
  46. barCSS += ".bar:nth-child({}) {{ left: {}px; animation-duration: {}ms; }}".format(
  47. i, left, anim
  48. )
  49. left += 4
  50. return barCSS
  51. def loadImageB64(url):
  52. resposne = requests.get(url)
  53. return b64encode(resposne.content).decode("ascii")
  54. def makeSVG(data):
  55. barCount = 85
  56. contentBar = "".join(["<div class='bar'></div>" for i in range(barCount)])
  57. barCSS = barGen(barCount)
  58. if data == {}:
  59. content_bar = ""
  60. recent_plays = recentlyPlayed()
  61. size_recent_play = len(recent_plays["items"])
  62. idx = random.randint(0, size_recent_play - 1)
  63. item = recent_plays["items"][idx]["track"]
  64. else:
  65. item = data["item"]
  66. img = loadImageB64(item["album"]["images"][1]["url"])
  67. artistName = item["artists"][0]["name"].replace("&", "&amp;")
  68. songName = item["name"].replace("&", "&amp;")
  69. dataDict = {
  70. "content_bar": contentBar,
  71. "css_bar": barCSS,
  72. "artist_name": artistName,
  73. "song_name": songName,
  74. "img": img,
  75. }
  76. return render_template("spotify.html.j2", **dataDict)
  77. @app.route("/", defaults={"path": ""})
  78. @app.route("/<path:path>")
  79. def catch_all(path):
  80. data = nowPlaying()
  81. svg = makeSVG(data)
  82. resp = Response(svg, mimetype="image/svg+xml")
  83. resp.headers["Cache-Control"] = "s-maxage=1"
  84. return resp
  85. if __name__ == "__main__":
  86. app.run(debug=True)