feat: Add spotify ascii curl page
This commit is contained in:
70
ascii_art.py
Normal file
70
ascii_art.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import requests
|
||||
from PIL import Image
|
||||
from io import BytesIO
|
||||
|
||||
ASCII_CHARS = ["@", "#", "S", "%", "?", "*", "+", ";", ":", ",", "."]
|
||||
|
||||
|
||||
def resized_gray_image(image, new_width=40):
|
||||
"""
|
||||
Resize and convert image to grayscale.
|
||||
"""
|
||||
width, height = image.size
|
||||
aspect_ratio = height / width
|
||||
# 0.55 is a correction factor as terminal characters are taller than they are wide
|
||||
new_height = int(aspect_ratio * new_width * 0.55)
|
||||
img = image.resize((new_width, new_height))
|
||||
return img.convert("L")
|
||||
|
||||
|
||||
def pixels_to_ascii(image):
|
||||
"""
|
||||
Map grayscale pixels to ASCII characters.
|
||||
"""
|
||||
pixels = image.getdata()
|
||||
# 255 / 11 (len(ASCII_CHARS)) ~= 23. Using 25 for safe integer division mapping.
|
||||
characters = "".join([ASCII_CHARS[pixel // 25] for pixel in pixels])
|
||||
return characters
|
||||
|
||||
|
||||
def image_url_to_ascii(url, new_width=40):
|
||||
"""
|
||||
Convert an image URL to a colored ASCII string using ANSI escape codes.
|
||||
"""
|
||||
if not url:
|
||||
return ""
|
||||
|
||||
try:
|
||||
response = requests.get(url, timeout=5)
|
||||
image = Image.open(BytesIO(response.content))
|
||||
except Exception:
|
||||
return ""
|
||||
|
||||
# Resize image
|
||||
width, height = image.size
|
||||
aspect_ratio = height / width
|
||||
# Calculate new height to maintain aspect ratio, considering terminal character dimensions
|
||||
# ASCII chars are taller than they are wide (approx ~2x)
|
||||
# Since we are using '██' (double width), we effectively make each "cell" square.
|
||||
# So we can just scale by aspect ratio directly without additional correction factor.
|
||||
new_height = int(aspect_ratio * new_width)
|
||||
if new_height > 60:
|
||||
new_height = 60
|
||||
new_width = int(new_height / aspect_ratio)
|
||||
|
||||
# Resize and ensure RGB mode
|
||||
img = image.resize((new_width, new_height))
|
||||
img = img.convert("RGB")
|
||||
|
||||
pixels = img.getdata()
|
||||
|
||||
ascii_str = ""
|
||||
for i, pixel in enumerate(pixels):
|
||||
r, g, b = pixel
|
||||
ascii_str += f"\033[38;2;{r};{g};{b}m██\033[0m"
|
||||
|
||||
# Add newline at the end of each row
|
||||
if (i + 1) % new_width == 0:
|
||||
ascii_str += "\n"
|
||||
|
||||
return ascii_str
|
||||
@@ -1,5 +1,6 @@
|
||||
from flask import redirect, render_template, request, Blueprint, url_for
|
||||
from tools import json_response, isCLI
|
||||
from ascii_art import image_url_to_ascii
|
||||
import os
|
||||
import requests
|
||||
import time
|
||||
@@ -106,7 +107,9 @@ def currently_playing():
|
||||
"""Public endpoint showing your current track."""
|
||||
track = get_playing_spotify_track()
|
||||
if isCLI(request):
|
||||
return json_response(request, {"spotify": track}, 200)
|
||||
if "album_art" in track:
|
||||
track["ascii_art"] = image_url_to_ascii(track["album_art"], new_width=40)
|
||||
return render_template("spotify.ascii", track=track)
|
||||
|
||||
# Render a simple HTML page for browsers
|
||||
return render_template("spotify.html", track=track)
|
||||
|
||||
21
templates/spotify.ascii
Normal file
21
templates/spotify.ascii
Normal file
@@ -0,0 +1,21 @@
|
||||
{% include 'header.ascii' %}
|
||||
API [/api/v1]
|
||||
|
||||
[1;36m───────────────────────────────────────────────[0m
|
||||
[1;36m CURRENTLY PLAYING [0m
|
||||
[1;36m───────────────────[0m
|
||||
{% if track.error %}
|
||||
Error: {{ track.error }}
|
||||
{% else %}
|
||||
{% if track.ascii_art %}
|
||||
{{ track.ascii_art }}
|
||||
|
||||
{% endif %}
|
||||
Song: [1m{{ track.song_name }}[0m
|
||||
Artist: {{ track.artist }}
|
||||
Album: {{ track.album_name }}
|
||||
URL: {{ track.url }}
|
||||
|
||||
Progress: {{ track.progress_ms // 60000 }}:{{ '%02d' % ((track.progress_ms // 1000) % 60) }} / {{ track.duration_ms // 60000 }}:{{ '%02d' % ((track.duration_ms // 1000) % 60) }}
|
||||
Status: {{ 'Playing' if track.is_playing else 'Paused' }}
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user