| import streamlit as st |
| import spotipy |
| from spotipy.oauth2 import SpotifyClientCredentials |
| import requests |
| from io import BytesIO |
| from PIL import Image |
| import base64 |
| import os |
|
|
| |
| spotify_client_secret = os.environ['spotifyclient'] |
| spotify_client_id = os.environ['spotifyid'] |
|
|
| |
| spotify_client_credentials_manager = SpotifyClientCredentials(client_id=spotify_client_id, client_secret=spotify_client_secret) |
| spotify = spotipy.Spotify(client_credentials_manager=spotify_client_credentials_manager) |
|
|
| def buscar_cancion_o_artista(nombre): |
| resultado = {} |
| resultados_busqueda = spotify.search(q=nombre, type="track", limit=1) |
| if resultados_busqueda["tracks"]["total"] > 0: |
| item = resultados_busqueda["tracks"]["items"][0] |
| resultado["nombre_cancion"] = item["name"] |
| resultado["artista"] = item["artists"][0]["name"] |
| resultado["id_cancion"] = item["id"] |
| resultado["artista_id"] = item["artists"][0]["id"] |
| return resultado |
|
|
| def generar_recomendaciones(id_cancion, artista_original): |
| recomendaciones = spotify.recommendations(seed_tracks=[id_cancion], limit=8) |
| canciones_filtradas = [cancion for cancion in recomendaciones["tracks"] if cancion["artists"][0]["name"].lower() != artista_original.lower()] |
| canciones_seleccionadas = canciones_filtradas[:8] |
|
|
| return canciones_seleccionadas |
|
|
| def generar_html(canciones_similares): |
| html = "" |
|
|
| html += ''' |
| <style> |
| @media screen and (min-width: 768px) { |
| .responsive-grid-item { |
| width: calc(25% - 10px); |
| } |
| } |
| @media screen and (max-width: 767px) { |
| .responsive-grid-item { |
| width: calc(50% - 10px); |
| } |
| } |
| .responsive-grid-item { |
| box-sizing: border-box; |
| padding: 10px; |
| background-color: #fff; |
| border-radius: 8px; |
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| } |
| .responsive-grid-item img { |
| max-width: 100%; |
| border-radius: 8px; |
| margin-bottom: 10px; |
| } |
| .responsive-grid-item h4 { |
| font-family: Arial, sans-serif; |
| font-size: 16px; |
| color: #333; |
| margin-bottom: 10px; |
| } |
| .responsive-grid-item p { |
| font-family: Arial, sans-serif; |
| font-size: 14px; |
| color: #666; |
| text-align: justify; |
| } |
| </style> |
| ''' |
|
|
| html += '<div class="responsive-grid" style="display: flex; flex-wrap: wrap; gap: 10px;">' |
| for cancion in canciones_similares: |
| html += f'<div class="responsive-grid-item">' |
| html += f'<h4>{cancion["name"]} - {cancion["artists"][0]["name"]}</h4>' |
| imagen_url = cancion["album"]["images"][0]["url"] |
| imagen_bytes = requests.get(imagen_url).content |
| imagen = Image.open(BytesIO(imagen_bytes)) |
| imagen.thumbnail((150, 150)) |
| imagen_buffer = BytesIO() |
| imagen.save(imagen_buffer, format="PNG") |
| imagen_str = base64.b64encode(imagen_buffer.getvalue()).decode("utf-8") |
| html += f'<a href="{cancion["external_urls"]["spotify"]}" target="_blank"><img src="data:image/png;base64,{imagen_str}"/></a>' |
| html += f'<p>' |
| html += f'<b>Album:</b> {cancion["album"]["name"]}<br/>' |
| html += f'</p>' |
| html += '</div>' |
| html += '</div>' |
| return html |
|
|
| st.title("Recomendador de canciones de Spotify") |
| st.write("") |
|
|
| nombre = st.text_input("Nombre de la canción o artista") |
|
|
| if st.button("Buscar"): |
| datos = buscar_cancion_o_artista(nombre) |
| if datos: |
| st.write(f"Resultados para: {datos['nombre_cancion']} - {datos['artista']}") |
| canciones_similares = generar_recomendaciones(datos["id_cancion"], datos["artista"]) |
| html = generar_html(canciones_similares) |
| st.write(html, unsafe_allow_html=True) |
| else: |
| st.write("No se encontraron resultados. Por favor, intenta con otro término de búsqueda.") |