import gradio as gr import requests import pandas as pd from tempfile import NamedTemporaryFile import shutil import os # Funciones para Spotify def obtener_token(client_id, client_secret): print("Obteniendo token de Spotify...") url = 'https://accounts.spotify.com/api/token' headers = {'Content-Type': 'application/x-www-form-urlencoded'} payload = {'grant_type': 'client_credentials'} response = requests.post(url, headers=headers, data=payload, auth=(client_id, client_secret)) return response.json().get('access_token') def buscar_playlists_spotify(token, query, limit=50): print("Buscando playlists en Spotify...") url = 'https://api.spotify.com/v1/search' headers = {'Authorization': f'Bearer {token}'} playlists = [] if limit <= 50: params = {'q': query, 'type': 'playlist', 'limit': limit} response = requests.get(url, headers=headers, params=params) if response.status_code != 200: print(f"Error en la solicitud a Spotify: {response.status_code}") print(response.json()) return [] items = response.json().get('playlists', {}).get('items', []) items = [item for item in items if item is not None] playlists.extend(items) else: offset = 0 while limit > 0: params = {'q': query, 'type': 'playlist', 'limit': min(50, limit), 'offset': offset} response = requests.get(url, headers=headers, params=params) if response.status_code != 200: print(f"Error en la solicitud a Spotify: {response.status_code}") print(response.json()) break items = response.json().get('playlists', {}).get('items', []) items = [item for item in items if item is not None] playlists.extend(items) fetched = len(items) limit -= fetched offset += fetched if fetched == 0: break valid_playlists = [] for playlist in playlists: if playlist is not None and 'id' in playlist and 'name' in playlist: valid_playlists.append({ 'playlist_id': playlist['id'], 'playlist_name': playlist['name'] }) return valid_playlists def obtener_canciones_playlist_spotify(token, playlist_id, playlist_name): print(f"Obteniendo canciones de la playlist {playlist_id} de Spotify...") url = f'https://api.spotify.com/v1/playlists/{playlist_id}/tracks' headers = {'Authorization': f'Bearer {token}'} response = requests.get(url, headers=headers) canciones = [] if response.status_code == 200: tracks = response.json().get('items', []) for item in tracks: track = item.get('track') if track: artista_info = {} if track['artists']: artista_info = obtener_info_artista(track['artists'][0]['id'], token) record_label = obtener_record_label_spotify(track['album']['id'], token) if track.get('album') else 'No disponible' canciones.append({ 'playlist_name': playlist_name, 'artista': track['artists'][0]['name'] if track['artists'] else 'Desconocido', 'titulo': track['name'], 'isrc': track.get('external_ids', {}).get('isrc', 'No disponible'), 'popularity': track.get('popularity', 'No disponible'), 'track_id': track['id'], 'link': track.get('external_urls', {}).get('spotify', 'No disponible'), 'record_label': record_label, 'source': 'Spotify', 'genero_artista': ', '.join(artista_info.get('genres', [])) if artista_info else 'No disponible' }) return canciones def obtener_caracteristicas_audio(token, track_ids): print("Obteniendo características de audio para las pistas...") url = f'https://api.spotify.com/v1/audio-features' headers = {'Authorization': f'Bearer {token}'} params = {'ids': ','.join(track_ids)} response = requests.get(url, headers=headers, params=params) return response.json().get('audio_features', []) if response.status_code == 200 else [] def obtener_record_label_spotify(album_id, token): url = f'https://api.spotify.com/v1/albums/{album_id}' headers = {'Authorization': f'Bearer {token}'} response = requests.get(url, headers=headers) return response.json().get('label', 'No disponible') if response.status_code == 200 else 'No disponible' def obtener_info_artista(artista_id, token): url = f'https://api.spotify.com/v1/artists/{artista_id}' headers = {'Authorization': f'Bearer {token}'} response = requests.get(url, headers=headers) return response.json() if response.status_code == 200 else {} def interface(query, num_spotify_playlists=50, project_name="Proyecto"): client_id = os.getenv('Spotify_ID') client_secret = os.getenv('Spotify_client') token_spotify = obtener_token(client_id, client_secret) if not token_spotify: raise gr.Error("Failed to obtain Spotify token. Check client ID and secret.") playlists_spotify = buscar_playlists_spotify(token_spotify, query, num_spotify_playlists) canciones_spotify = [] track_ids = [] for playlist in playlists_spotify: songs = obtener_canciones_playlist_spotify(token_spotify, playlist['playlist_id'], playlist['playlist_name']) canciones_spotify.extend(songs) track_ids.extend([song['track_id'] for song in songs if song.get('track_id')]) audio_features_list = obtener_caracteristicas_audio(token_spotify, track_ids) audio_features_dict = {af['id']: af for af in audio_features_list if af} for song in canciones_spotify: audio_features = audio_features_dict.get(song['track_id'], {}) song.update({ 'valence': audio_features.get('valence', 'No disponible'), 'danceability': audio_features.get('danceability', 'No disponible'), 'energy': audio_features.get('energy', 'No disponible'), 'tempo': audio_features.get('tempo', 'No disponible'), 'speechiness': audio_features.get('speechiness', 'No disponible'), 'instrumentalness': audio_features.get('instrumentalness', 'No disponible') }) df = pd.DataFrame(canciones_spotify) df.rename(columns={'isrc': 'ISRCs'}, inplace=True) df.sort_values(by=['popularity'], ascending=False, inplace=True) with NamedTemporaryFile(delete=False, suffix='.xlsx') as tmpfile: df.to_excel(tmpfile.name, index=False) project_filename = f"{project_name}.xlsx" shutil.move(tmpfile.name, project_filename) return df, project_filename iface = gr.Interface( fn=interface, inputs=[ gr.Textbox(label="Keywords o Títulos de Playlists"), gr.Number(label="Número de playlists que queremos buscar", value=50, minimum=1, maximum=1000), gr.Textbox(label="Nombre del proyecto") ], outputs=[gr.Dataframe(), gr.File(label="Descargar Excel")], title="Busca Playlists con Keywords", description="Ingresa tu búsqueda para encontrar playlists en Spotify con esas palabras en sus títulos." ) iface.launch()