File size: 7,358 Bytes
a085bd3
 
 
 
0dd3b0c
ce80102
a085bd3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b155d01
 
 
 
 
 
 
a085bd3
 
 
 
 
b155d01
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a085bd3
6ff194f
a085bd3
 
 
 
 
 
b155d01
a085bd3
 
 
b155d01
 
 
 
a085bd3
6ff194f
a085bd3
 
b155d01
a085bd3
6cd9583
b155d01
 
6ff194f
b155d01
a085bd3
 
 
6cd9583
 
 
a085bd3
6cd9583
 
b155d01
a085bd3
 
 
 
 
b155d01
a085bd3
6ff194f
 
 
 
b155d01
6ff194f
f80d783
8adb578
 
a085bd3
 
b155d01
 
 
a085bd3
 
6cd9583
a085bd3
6ff194f
a085bd3
b155d01
6cd9583
 
 
 
 
 
 
 
 
 
 
 
 
 
a085bd3
 
 
 
 
 
 
f80d783
0dd3b0c
b155d01
a085bd3
 
 
 
19de75c
895f819
 
a085bd3
895f819
ffc4dc1
6ff194f
a085bd3
b155d01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
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()