import os import gradio as gr from flask import Flask, request, redirect from spotipy import Spotify, SpotifyOAuth from threading import Thread import random import time # ========== Spotify OAuth Setup ========== CLIENT_ID = os.getenv("SPOTIFY_CLIENT_ID") CLIENT_SECRET = os.getenv("SPOTIFY_CLIENT_SECRET") REDIRECT_URI = REDIRECT_URI = "https://jisaacso219-rng-shuffle.hf.space/callback" SCOPE = "user-read-playback-state user-modify-playback-state playlist-read-private" auth_codes = {} # Store auth tokens per session (not secure for prod) sp_oauth = SpotifyOAuth( client_id=CLIENT_ID, client_secret=CLIENT_SECRET, redirect_uri=REDIRECT_URI, scope=SCOPE ) # ========== Flask Redirect Server ========== app = Flask(__name__) @app.route("/callback") def callback(): code = request.args.get("code") token_info = sp_oauth.get_access_token(code, as_dict=True) auth_codes["user"] = token_info # Single-user session for now return "✅ Spotify login successful! You can return to the app." Thread(target=lambda: app.run(host="0.0.0.0", port=7861)).start() # ========== Gradio UI ========== def login(): return sp_oauth.get_authorize_url() def list_playlists(): if "user" not in auth_codes: return [], "⚠️ Please log in first." sp = Spotify(auth=auth_codes["user"]["access_token"]) pl = sp.current_user_playlists(limit=50) choices = {p['name']: p['id'] for p in pl['items']} return list(choices.keys()), "Select a playlist to shuffle and play." def shuffle_and_play(playlist_name): if "user" not in auth_codes: return "⚠️ Please log in first." sp = Spotify(auth=auth_codes["user"]["access_token"]) pl = sp.current_user_playlists(limit=50) pl_map = {p['name']: p['id'] for p in pl['items']} playlist_id = pl_map[playlist_name] tracks = [] results = sp.playlist_tracks(playlist_id) tracks.extend(results['items']) while results['next']: results = sp.next(results) tracks.extend(results['items']) uris = [t['track']['uri'] for t in tracks if t['track']] random.shuffle(uris) devices = sp.devices() if not devices['devices']: return "⚠️ No active Spotify devices found. Open the Spotify app and try again." device_id = devices['devices'][0]['id'] sp.start_playback(device_id=device_id, uris=uris) return f"▶️ Playing {len(uris)} shuffled tracks from '{playlist_name}'!" with gr.Blocks() as demo: gr.Markdown("# 🎶 Spotify Playlist Shuffler") login_btn = gr.Button("🔐 Log in to Spotify") login_out = gr.Textbox(label="Login URL") playlist_list = gr.Dropdown(label="Your Playlists") refresh_btn = gr.Button("🔄 Load My Playlists") status = gr.Textbox() play_btn = gr.Button("▶️ Shuffle + Play") result = gr.Textbox() login_btn.click(fn=login, outputs=login_out) refresh_btn.click(fn=list_playlists, outputs=[playlist_list, status]) play_btn.click(fn=shuffle_and_play, inputs=playlist_list, outputs=result) demo.launch(server_port=7860, server_name="0.0.0.0")