jisaacso219 commited on
Commit
702b499
Β·
verified Β·
1 Parent(s): a7abb2d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -74
app.py CHANGED
@@ -4,18 +4,10 @@ import spotipy
4
  from spotipy.oauth2 import SpotifyOAuth
5
  import random
6
 
7
- # β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”β€”
8
- # 1. Hard-code your Redirect URI here:
9
  REDIRECT_URI = "https://jisaacso219-rng-shuffle.hf.space/"
10
-
11
- # 2. Client creds in Secrets:
12
  CLIENT_ID = os.environ["SPOTIFY_CLIENT_ID"]
13
  CLIENT_SECRET = os.environ["SPOTIFY_CLIENT_SECRET"]
14
- SCOPE = (
15
- "user-read-playback-state "
16
- "user-modify-playback-state "
17
- "playlist-read-private"
18
- )
19
 
20
  sp_oauth = SpotifyOAuth(
21
  client_id=CLIENT_ID,
@@ -29,43 +21,32 @@ sp = None
29
  user_playlists = {}
30
 
31
  def get_auth_url():
32
- url = sp_oauth.get_authorize_url()
33
- print(f"[DEBUG] Generated auth URL: {url}")
34
- return url
35
 
36
  def check_login(code: str):
37
- print(f"[DEBUG] check_login called with code: {code}")
38
- global sp, user_playlists
39
- # Hide controls if no code yet
40
  if not code:
41
  return gr.update(visible=False), gr.update(visible=False, choices=[])
42
- # Exchange code for token
43
  token = sp_oauth.get_access_token(code, as_dict=False)
 
44
  sp = spotipy.Spotify(auth=token)
45
  pls = sp.current_user_playlists(limit=50)["items"]
46
  user_playlists = {p["name"]: p["id"] for p in pls}
47
- print(f"[DEBUG] Retrieved playlists: {list(user_playlists.keys())}")
48
  return (
49
  gr.update(visible=True, value="βœ… Logged in! Choose a playlist below."),
50
  gr.update(visible=True, choices=list(user_playlists.keys())),
51
  )
52
 
53
- def load_playlist_info(pl_name: str):
54
- print(f"[DEBUG] load_playlist_info called for: {pl_name}")
55
  pid = user_playlists[pl_name]
56
  data = sp.playlist(pid)
57
  img = data["images"][0]["url"] if data["images"] else ""
58
  owner = data["owner"]["display_name"]
59
  desc = data.get("description", "")
60
- html = f"""
61
- <img src="{img}" width="300px" style="border-radius:10px;"/><br/>
62
- <strong>{pl_name}</strong> by {owner}<br/>
63
- {desc}
64
- """
65
  return html, gr.update(visible=True)
66
 
67
- def shuffle_and_play(pl_name: str):
68
- print(f"[DEBUG] shuffle_and_play called for: {pl_name}")
69
  pid = user_playlists[pl_name]
70
  tracks, results = [], sp.playlist_tracks(pid)
71
  tracks.extend(results["items"])
@@ -73,80 +54,51 @@ def shuffle_and_play(pl_name: str):
73
  results = sp.next(results)
74
  tracks.extend(results["items"])
75
  uris = [t["track"]["uri"] for t in tracks if t["track"]]
76
- devices = sp.devices()["devices"]
77
- if not devices:
78
- print("[DEBUG] No active devices found")
79
- return gr.update(value="⚠️ No active device. Open Spotify and try again.", visible=True)
80
- sp.start_playback(device_id=devices[0]["id"], uris=uris)
81
  now = sp.current_playback()
82
  if now and now.get("item"):
83
  it = now["item"]
84
  art = it["album"]["images"][0]["url"]
85
  title = it["name"]
86
  artists = ", ".join(a["name"] for a in it["artists"])
87
- html = f"""
88
- <img src="{art}" width="200px" style="border-radius:8px;"/><br/>
89
- ▢️ <strong>{title}</strong><br/>
90
- by {artists}
91
- """
92
- return html
93
  return "▢️ Playing your shuffled playlist!"
94
 
95
  with gr.Blocks() as demo:
96
- gr.Markdown("## 🎡 RNG Spotify Playlist Shuffler")
97
- gr.Markdown("Login, pick a playlist, then shuffle & playβ€”all in one flow.")
98
-
99
- # 1️⃣ Login button: redirect the TOP window out of the iframe
100
- login_btn = gr.Button("πŸ” Step 1: Login to Spotify")
101
- login_btn.click(
102
- fn=None, inputs=None, outputs=None,
103
- js=f"""
104
- () => {{
105
- console.log("πŸ‘‰ [JS] Login button clicked, redirecting...");
106
- window.top.location.href = '{get_auth_url()}';
107
- }}
108
- """
109
  )
110
 
111
- # Hidden box to capture the `code` after redirect
112
  code_box = gr.Textbox(visible=False, elem_id="auth_code")
113
-
114
- # Status + playlist selector (hidden until login finishes)
115
  status = gr.Markdown(visible=False)
116
  dropdown = gr.Dropdown(choices=[], label="Step 2: Select a Playlist", visible=False)
117
-
118
- # Playlist info + shuffle controls
119
  info_html = gr.HTML(visible=False)
120
  shuffle_btn = gr.Button("πŸ”€ Step 3: Shuffle & Play", visible=False)
121
  result = gr.HTML(visible=False)
122
 
123
- # πŸ”„ On every page-load: pull `?code=` from URL into our hidden box and call check_login()
124
  demo.load(
125
  fn=check_login,
126
  inputs=[code_box],
127
  outputs=[status, dropdown],
128
  js="""
129
- () => {
130
- const url = window.location.href;
131
- const code = new URLSearchParams(window.location.search).get('code') || "";
132
- console.log("🌐 [JS] Current URL:", url);
133
- console.log("πŸ”‘ [JS] Parsed code:", code);
134
- return code;
135
- }
136
  """
137
  )
138
 
139
- dropdown.change(
140
- fn=load_playlist_info,
141
- inputs=[dropdown],
142
- outputs=[info_html, shuffle_btn]
143
- )
144
-
145
- shuffle_btn.click(
146
- fn=shuffle_and_play,
147
- inputs=[dropdown],
148
- outputs=[result]
149
- )
150
 
151
  if __name__ == "__main__":
152
  demo.launch()
 
4
  from spotipy.oauth2 import SpotifyOAuth
5
  import random
6
 
 
 
7
  REDIRECT_URI = "https://jisaacso219-rng-shuffle.hf.space/"
 
 
8
  CLIENT_ID = os.environ["SPOTIFY_CLIENT_ID"]
9
  CLIENT_SECRET = os.environ["SPOTIFY_CLIENT_SECRET"]
10
+ SCOPE = "user-read-playback-state user-modify-playback-state playlist-read-private"
 
 
 
 
11
 
12
  sp_oauth = SpotifyOAuth(
13
  client_id=CLIENT_ID,
 
21
  user_playlists = {}
22
 
23
  def get_auth_url():
24
+ return sp_oauth.get_authorize_url()
 
 
25
 
26
  def check_login(code: str):
 
 
 
27
  if not code:
28
  return gr.update(visible=False), gr.update(visible=False, choices=[])
 
29
  token = sp_oauth.get_access_token(code, as_dict=False)
30
+ global sp, user_playlists
31
  sp = spotipy.Spotify(auth=token)
32
  pls = sp.current_user_playlists(limit=50)["items"]
33
  user_playlists = {p["name"]: p["id"] for p in pls}
 
34
  return (
35
  gr.update(visible=True, value="βœ… Logged in! Choose a playlist below."),
36
  gr.update(visible=True, choices=list(user_playlists.keys())),
37
  )
38
 
39
+ def load_playlist_info(pl_name):
 
40
  pid = user_playlists[pl_name]
41
  data = sp.playlist(pid)
42
  img = data["images"][0]["url"] if data["images"] else ""
43
  owner = data["owner"]["display_name"]
44
  desc = data.get("description", "")
45
+ html = f"""<img src="{img}" width="300"/><br/>
46
+ <strong>{pl_name}</strong> by {owner}<br/>{desc}"""
 
 
 
47
  return html, gr.update(visible=True)
48
 
49
+ def shuffle_and_play(pl_name):
 
50
  pid = user_playlists[pl_name]
51
  tracks, results = [], sp.playlist_tracks(pid)
52
  tracks.extend(results["items"])
 
54
  results = sp.next(results)
55
  tracks.extend(results["items"])
56
  uris = [t["track"]["uri"] for t in tracks if t["track"]]
57
+ devs = sp.devices()["devices"]
58
+ if not devs:
59
+ return gr.update(value="⚠️ No active Spotify device.", visible=True)
60
+ sp.start_playback(device_id=devs[0]["id"], uris=uris)
 
61
  now = sp.current_playback()
62
  if now and now.get("item"):
63
  it = now["item"]
64
  art = it["album"]["images"][0]["url"]
65
  title = it["name"]
66
  artists = ", ".join(a["name"] for a in it["artists"])
67
+ return f"""<img src="{art}" width="200"/><br/>
68
+ ▢️ <strong>{title}</strong><br/>by {artists}"""
 
 
 
 
69
  return "▢️ Playing your shuffled playlist!"
70
 
71
  with gr.Blocks() as demo:
72
+ gr.Markdown("""
73
+ ⚠️ **View this Space in its own tab!**
74
+ Click the πŸ”— icon at top-right before logging in.
75
+ """)
76
+
77
+ login_btn = gr.Button(
78
+ "πŸ” Step 1: Login to Spotify",
79
+ link=get_auth_url()
 
 
 
 
 
80
  )
81
 
 
82
  code_box = gr.Textbox(visible=False, elem_id="auth_code")
 
 
83
  status = gr.Markdown(visible=False)
84
  dropdown = gr.Dropdown(choices=[], label="Step 2: Select a Playlist", visible=False)
 
 
85
  info_html = gr.HTML(visible=False)
86
  shuffle_btn = gr.Button("πŸ”€ Step 3: Shuffle & Play", visible=False)
87
  result = gr.HTML(visible=False)
88
 
 
89
  demo.load(
90
  fn=check_login,
91
  inputs=[code_box],
92
  outputs=[status, dropdown],
93
  js="""
94
+ () => {
95
+ return new URLSearchParams(window.location.search).get('code') || "";
96
+ }
 
 
 
 
97
  """
98
  )
99
 
100
+ dropdown.change(load_playlist_info, [dropdown], [info_html, shuffle_btn])
101
+ shuffle_btn.click(shuffle_and_play, [dropdown], [result])
 
 
 
 
 
 
 
 
 
102
 
103
  if __name__ == "__main__":
104
  demo.launch()