Mthrfkr commited on
Commit
c33f952
·
verified ·
1 Parent(s): bbfc85d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +106 -46
app.py CHANGED
@@ -1,21 +1,19 @@
1
-
2
  import requests
3
  import pandas as pd
4
  import time
5
  import shutil
 
6
  import os
7
  from tempfile import NamedTemporaryFile
 
8
 
9
  # Spotify API credentials from environment variables
10
- client_ids = os.getenv("SPOTIFY_CLIENT_IDS", "")
11
- client_secrets = os.getenv("SPOTIFY_CLIENT_SECRETS", "")
12
 
13
- # For testing/demo purposes only - DO NOT use in production
14
  if not client_ids or not client_secrets:
15
- print("WARNING: No API credentials found in environment variables. Using demo mode with limited functionality.")
16
- # Provide fake credentials for demo purposes
17
- client_ids = "demo_client_id"
18
- client_secrets = "demo_client_secret"
19
 
20
  client_ids = client_ids.split(',')
21
  client_secrets = client_secrets.split(',')
@@ -26,28 +24,16 @@ total_requests = 0
26
 
27
  # Spotify Functions
28
  def get_token(client_id, client_secret):
29
- """Get Spotify API token. Returns a demo token in case of failure for testing."""
30
  url = 'https://accounts.spotify.com/api/token'
31
  headers = {'Content-Type': 'application/x-www-form-urlencoded'}
32
  payload = {'grant_type': 'client_credentials'}
33
-
34
- try:
35
- response = requests.post(url, headers=headers, data=payload, auth=(client_id, client_secret))
36
- global total_requests
37
- total_requests += 1
38
-
39
- if response.status_code == 200:
40
- print("Successfully obtained Spotify API token")
41
- return response.json().get('access_token')
42
- else:
43
- print(f"Error getting token: {response.status_code} - {response.text}")
44
- # For demo/testing only - simulate a token
45
- if client_id == "demo_client_id":
46
- print("Using demo token for testing purposes")
47
- return "demo_token"
48
- return None
49
- except Exception as e:
50
- print(f"Exception during token retrieval: {str(e)}")
51
  return None
52
 
53
  def handle_rate_limit(response, attempt):
@@ -328,25 +314,99 @@ def interface(project_name, spotify_urls, include_all_info=True):
328
  # Get token
329
  token_spotify = get_token(client_ids[current_api_index], client_secrets[current_api_index])
330
  if not token_spotify:
331
- if client_ids[0] == "demo_client_id":
332
- print("Running in demo mode with sample data")
333
- # In demo mode, return sample data
334
- demo_data = get_demo_data()
335
- df = pd.DataFrame(demo_data)
336
-
337
- # Save DataFrame to an Excel file
338
- tmpfile = NamedTemporaryFile(delete=False, suffix='.xlsx')
339
- df.to_excel(tmpfile.name, index=False)
340
-
341
- # Rename the file with the project name
342
- project_file_name = f"{project_name}.xlsx"
343
- shutil.move(tmpfile.name, project_file_name)
344
-
345
- return df, project_file_name
346
- else:
347
- error_message = "Failed to authenticate with Spotify API. Please try again later."
348
- return gr.Dataframe(value=pd.DataFrame({"Error": [error_message]})), None
349
 
350
  print(f"Successfully authenticated with Spotify API")
351
 
352
- all_tracks = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
  import requests
3
  import pandas as pd
4
  import time
5
  import shutil
6
+ import numpy as np
7
  import os
8
  from tempfile import NamedTemporaryFile
9
+ from openpyxl import Workbook
10
 
11
  # Spotify API credentials from environment variables
12
+ client_ids = os.getenv("SPOTIFY_CLIENT_IDS")
13
+ client_secrets = os.getenv("SPOTIFY_CLIENT_SECRETS")
14
 
 
15
  if not client_ids or not client_secrets:
16
+ raise ValueError("SPOTIFY_CLIENT_IDS or SPOTIFY_CLIENT_SECRETS environment variables not set.")
 
 
 
17
 
18
  client_ids = client_ids.split(',')
19
  client_secrets = client_secrets.split(',')
 
24
 
25
  # Spotify Functions
26
  def get_token(client_id, client_secret):
 
27
  url = 'https://accounts.spotify.com/api/token'
28
  headers = {'Content-Type': 'application/x-www-form-urlencoded'}
29
  payload = {'grant_type': 'client_credentials'}
30
+ response = requests.post(url, headers=headers, data=payload, auth=(client_id, client_secret))
31
+ global total_requests
32
+ total_requests += 1
33
+ if response.status_code == 200:
34
+ return response.json().get('access_token')
35
+ else:
36
+ print(f"Error getting token: {response.status_code} - {response.text}")
 
 
 
 
 
 
 
 
 
 
 
37
  return None
38
 
39
  def handle_rate_limit(response, attempt):
 
314
  # Get token
315
  token_spotify = get_token(client_ids[current_api_index], client_secrets[current_api_index])
316
  if not token_spotify:
317
+ error_message = "Failed to authenticate with Spotify API. Please try again later."
318
+ return gr.Dataframe(value=pd.DataFrame({"Error": [error_message]})), None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
 
320
  print(f"Successfully authenticated with Spotify API")
321
 
322
+ all_tracks = []
323
+
324
+ # Process each URL
325
+ for url in valid_urls:
326
+ try:
327
+ print(f"Processing URL: {url}")
328
+ if "playlist" in url:
329
+ tracks = get_playlist_tracks(token_spotify, url)
330
+ # Add source information
331
+ for track in tracks:
332
+ track['playlist_source'] = url
333
+ all_tracks.extend(tracks)
334
+ elif "track" in url:
335
+ track = get_track_info(token_spotify, url)
336
+ if track:
337
+ track[0]['playlist_source'] = url
338
+ all_tracks.extend(track)
339
+ elif "album" in url:
340
+ album_tracks = get_album_tracks(token_spotify, url)
341
+ all_tracks.extend(album_tracks)
342
+ except Exception as e:
343
+ print(f"Error processing URL {url}: {str(e)}")
344
+ continue
345
+
346
+ if not all_tracks:
347
+ error_message = "Could not find any tracks in the provided URLs."
348
+ return gr.Dataframe(value=pd.DataFrame({"Error": [error_message]})), None
349
+
350
+ # Extract track details including artist information
351
+ print("Extracting detailed track information including ISRCs...")
352
+ tracks_info = extract_track_details(all_tracks, token_spotify)
353
+
354
+ # Remove duplicate tracks (based on ISRC or title+artist if ISRC not available)
355
+ print("Creating DataFrame and removing duplicates...")
356
+ df = pd.DataFrame(tracks_info)
357
+
358
+ # Create a key for deduplication
359
+ df['dedup_key'] = df.apply(
360
+ lambda row: row['isrc'] if row['isrc'] != 'Not available' else f"{row['artist']}_{row['title']}",
361
+ axis=1
362
+ )
363
+
364
+ # Drop duplicates
365
+ df = df.drop_duplicates(subset='dedup_key')
366
+ df = df.drop(columns=['dedup_key'])
367
+
368
+ print(f"Found {len(df)} unique tracks after deduplication")
369
+
370
+ # Filter columns if not include_all_info
371
+ if not include_all_info:
372
+ columns_to_keep = ['artist', 'title', 'isrc', 'album', 'genres', 'release_date', 'track_popularity', 'explicit', 'spotify_url']
373
+ df = df[columns_to_keep]
374
+
375
+ # Save DataFrame to an Excel file
376
+ tmpfile = NamedTemporaryFile(delete=False, suffix='.xlsx')
377
+ df.to_excel(tmpfile.name, index=False)
378
+
379
+ # Rename the file with the project name
380
+ project_file_name = f"{project_name}.xlsx"
381
+ shutil.move(tmpfile.name, project_file_name)
382
+
383
+ return df, project_file_name
384
+
385
+ # Gradio Interface Configuration
386
+ iface = gr.Interface(
387
+ fn=interface,
388
+ inputs=[
389
+ gr.Textbox(label="Project Name", placeholder="Enter a name for your export"),
390
+ gr.Textbox(
391
+ label="Spotify URLs (Tracks, Albums or Playlists)",
392
+ placeholder="Enter one Spotify URL per line (tracks, albums or playlists)",
393
+ lines=5
394
+ ),
395
+ gr.Checkbox(label="Include All Track Information", value=True)
396
+ ],
397
+ outputs=[
398
+ gr.Dataframe(),
399
+ gr.File(label="Download Excel")
400
+ ],
401
+ title="Spotify Track Collector",
402
+ description="Extract tracks from multiple Spotify playlists, albums, and tracks into a single Excel file.",
403
+ examples=[
404
+ ["Pop Collection", "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M\nhttps://open.spotify.com/track/4cOdK2wGLETKBW3PvgPWqT", True],
405
+ ["Rock Collection", "https://open.spotify.com/playlist/37i9dQZF1DWXRqgorJj26U", False],
406
+ ["Album Tracks", "https://open.spotify.com/album/1R5BORZZxNUg8QMgbqt0nd", True]
407
+ ],
408
+ allow_flagging="never"
409
+ )
410
+
411
+ if __name__ == "__main__":
412
+ iface.launch()