Spaces:
Running
Running
import os | |
import gradio as gr | |
import spotipy | |
from spotipy.oauth2 import SpotifyOAuth | |
import random | |
import time | |
# Load environment variables securely from Hugging Face secrets | |
CLIENT_ID = os.environ["SPOTIFY_CLIENT_ID"] | |
CLIENT_SECRET = os.environ["SPOTIFY_CLIENT_SECRET"] | |
REDIRECT_URI = os.environ.get("SPOTIFY_REDIRECT_URI", "https://jisaacso219-rng-shuffle.hf.space/callback") | |
SCOPE = "user-read-playback-state user-modify-playback-state playlist-read-private" | |
sp_oauth = SpotifyOAuth( | |
client_id=CLIENT_ID, | |
client_secret=CLIENT_SECRET, | |
redirect_uri=REDIRECT_URI, | |
scope=SCOPE | |
) | |
auth_url = sp_oauth.get_authorize_url() | |
sp = None # Will be set after authorization | |
user_playlists = {} | |
selected_playlist_id = None | |
with gr.Blocks(title="RNG Spotify Playlist Shuffler") as demo: | |
gr.Markdown("## π΅ RNG Spotify Playlist Shuffler", elem_id="title") | |
gr.Markdown("A clean and simple way to shuffle your Spotify playlists with one click.") | |
with gr.Column(): | |
login_button = gr.Button("π Step 1: Login to Spotify") | |
login_link = gr.Markdown(f"[Click here to login to Spotify]({auth_url})", visible=False) | |
code_box = gr.Textbox(label="Step 2: Paste authorization code", placeholder="...?code=ABC123", visible=False) | |
authorize_button = gr.Button("β Step 3: Complete Authorization", visible=False) | |
login_status = gr.Markdown(visible=False) | |
playlist_dropdown = gr.Dropdown(choices=[], label="Step 4: π§ Select a Playlist", visible=False) | |
shuffle_button = gr.Button("π Step 5: Shuffle and Play", visible=False) | |
result_box = gr.Markdown(visible=False) | |
def check_login(code): | |
global sp, user_playlists | |
if not code: | |
return ( | |
gr.update(visible=True, value="β οΈ No authorization code received."), | |
gr.update(visible=False), | |
gr.update(visible=False), | |
gr.update(visible=False) | |
) | |
token_info = sp_oauth.get_access_token(code, as_dict=False) | |
sp = spotipy.Spotify(auth=token_info) | |
playlists = sp.current_user_playlists(limit=50) | |
user_playlists = {p['name']: p['id'] for p in playlists['items']} | |
return ( | |
gr.update(visible=True, value="β Logged in! Select your playlist below."), | |
gr.update(visible=True, choices=list(user_playlists.keys())), | |
gr.update(visible=True), | |
gr.update(visible=True) | |
) | |
def shuffle_and_play(playlist_name): | |
global selected_playlist_id | |
if not sp: | |
return gr.update(value="β οΈ You must login first.", visible=True) | |
selected_playlist_id = user_playlists[playlist_name] | |
tracks = [] | |
results = sp.playlist_tracks(selected_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 gr.update(value="β οΈ No active Spotify devices found. Open the Spotify app and try again.", visible=True) | |
device_id = devices['devices'][0]['id'] | |
sp.start_playback(device_id=device_id, uris=uris) | |
return gr.update(value=f"βΆοΈ Now playing: **{playlist_name}** in shuffled order!", visible=True) | |
authorize_button.click( | |
check_login, | |
inputs=[code_box], | |
outputs=[login_status, playlist_dropdown, shuffle_button, result_box] | |
) | |
shuffle_button.click( | |
shuffle_and_play, | |
inputs=[playlist_dropdown], | |
outputs=[result_box] | |
) | |
def show_authorize_inputs(): | |
return gr.update(visible=True), gr.update(visible=True), gr.update(visible=True) | |
login_button.click( | |
fn=show_authorize_inputs, | |
outputs=[login_link, code_box, authorize_button], | |
show_progress=False | |
) | |
if __name__ == "__main__": | |
demo.launch() | |