Add scripts for rofi to play music on spotify

This commit is contained in:
Antonin Ruan
2025-08-18 22:36:05 +02:00
parent 7512b36ba4
commit 61ffaffeee
4 changed files with 116 additions and 3 deletions

View File

@@ -0,0 +1,2 @@
joblib==1.5.1
spotipy==2.25.1

107
.config/rofi/scripts/spotify.py Executable file
View File

@@ -0,0 +1,107 @@
#!/home/womax/.config/rofi/scripts/.env/bin/python
import joblib
from joblib import expires_after
import os
import os.path as path
import shutil
import spotipy
from spotipy.oauth2 import SpotifyPKCE
import sys
import time
# Get client from env variables or default to spotify web player if missing
# Using a custom spotify client should be better to avoir rate limiting
SPOTIFY_CLIENT_ID = os.getenv(
"SPOTIFY_CLIENT_ID",
"65b708073fc0480ea92a077233ca87bd")
cache_dir = path.join(
os.getenv("XDG_CACHE_HOME",
path.join(os.getenv("HOME"), ".cache")),
"rofi-spotify")
if path.exists(cache_dir) and not path.isdir(cache_dir):
shutil.rmtree(cache_dir)
if not path.exists(cache_dir):
os.makedirs(cache_dir, mode=0o755)
memory = joblib.Memory(cache_dir, verbose=0)
scopes = ["user-top-read", "user-modify-playback-state"]
sp = spotipy.Spotify(
auth_manager=SpotifyPKCE(
client_id=SPOTIFY_CLIENT_ID,
redirect_uri="http://127.0.0.1:9090/login",
scope=scopes,
cache_handler=spotipy.CacheFileHandler(
cache_path=path.join(cache_dir, "credentials"))
))
@memory.cache(cache_validation_callback=expires_after(days=30))
def get_top_tracks(limit=200):
offset = 0
tracks = []
while offset < limit:
reading = min(50, limit-offset)
tracks += sp.current_user_top_tracks(
limit=reading,
offset=offset)["items"]
offset += reading
return tracks
def format_track(track):
track_format = "{title} - {artist}\0info\x1f{track_id}\n"
return track_format.format(
title=track["name"],
artist=track["artists"][0]["name"],
track_id=track["id"]
)
def display_default():
liked_tracks = get_top_tracks()
for item in liked_tracks:
print(format_track(item), end="")
def play_track(track_id: str):
try:
sp.add_to_queue(f"spotify:track:{track_id}")
except spotipy.SpotifyException as err:
print(f"\0message\x1f{err.msg}")
return
time.sleep(0.1)
sp.next_track()
@memory.cache(cache_validation_callback=expires_after(seconds=180))
def search_track(query: str):
try:
query_res = sp.search(query, limit=30, type='track')["tracks"]["items"]
if len(query_res) == 0:
print("\0message\x1fNo result in search")
return
for result in query_res:
print(format_track(result), end="")
except spotipy.SpotifyException as err:
print(f"\0message\x1f{err.msg}")
return
def main():
match int(os.getenv("ROFI_RETV", default=-1)):
case 0:
# Initial call
display_default()
case 1:
# Selected entry
play_track(os.getenv("ROFI_INFO", ""))
exit(0)
case 2:
# Custom entry
track = sys.argv[1]
search_track(track)
memory.reduce_size(bytes_limit="10M")
case _:
exit(1)
if __name__=="__main__":
main()