fix: ditch librespot search

This commit is contained in:
Xoconoch
2025-08-27 08:20:11 -06:00
parent e55b15db2c
commit 573098ca6e
3 changed files with 25 additions and 38 deletions

View File

@@ -1,13 +1,12 @@
#!/usr/bin/python3 #!/usr/bin/python3
from librespot.core import Session, SearchManager from librespot.core import Session
from librespot.metadata import TrackId, AlbumId, ArtistId, EpisodeId, ShowId, PlaylistId from librespot.metadata import TrackId, AlbumId, ArtistId, EpisodeId, ShowId, PlaylistId
from deezspot.exceptions import InvalidLink from deezspot.exceptions import InvalidLink
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
# Note: We intentionally avoid importing spotipy. This module is now a # Note: Search is handled via spotipy (Web API). Other metadata (tracks/albums/...)
# thin shim over librespot's internal API, returning Web-API-shaped dicts # still use librespot via LibrespotClient.
# consumed by spotloader's converters.
from deezspot.libutils import LibrespotClient from deezspot.libutils import LibrespotClient
@@ -481,36 +480,22 @@ class Spo:
@classmethod @classmethod
def search(cls, query, search_type='track', limit=10, country: Optional[str] = None, locale: Optional[str] = None, catalogue: Optional[str] = None, image_size: Optional[str] = None, client_id=None, client_secret=None): def search(cls, query, search_type='track', limit=10, country: Optional[str] = None, locale: Optional[str] = None, catalogue: Optional[str] = None, image_size: Optional[str] = None, client_id=None, client_secret=None):
cls.__check_initialized() # Reverted: use spotipy Web API search; librespot search is not supported here.
# Preferred path: use LibrespotClient for consistent defaults and options try:
if cls.__client is not None: import spotipy # type: ignore
res = cls.__client.search( from spotipy.oauth2 import SpotifyClientCredentials # type: ignore
query=query, except Exception as e:
limit=limit, raise RuntimeError("spotipy is required for search; please install spotipy") from e
country=country or cls.__get_session_country_code(), try:
locale=locale, if client_id or client_secret:
catalogue=catalogue, auth_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret)
image_size=image_size, else:
) auth_manager = SpotifyClientCredentials()
# Optionally filter by type if requested (best-effort; librespot returns mixed) sp = spotipy.Spotify(auth_manager=auth_manager)
if search_type and isinstance(res, dict) and search_type in res: type_param = ','.join([t.strip() for t in str(search_type or 'track').split(',') if t.strip()]) or 'track'
return {search_type: res.get(search_type)} market = country or None
res = sp.search(q=query, type=type_param, market=market, limit=int(limit) if limit is not None else 10)
return res return res
# Fallback: direct SearchManager except Exception as e:
req = SearchManager.SearchRequest(query).set_limit(limit) # Surface a concise error to callers
if country: raise RuntimeError(f"Spotify search failed: {e}")
req.set_country(country)
else:
cc = cls.__get_session_country_code()
if cc:
req.set_country(cc)
if locale:
req.set_locale(locale)
if catalogue:
req.set_catalogue(catalogue)
if image_size:
req.set_image_size(image_size)
res = cls.__session.search().request(req) # type: ignore[union-attr]
if search_type and isinstance(res, dict) and search_type in res:
return {search_type: res.get(search_type)}
return res

View File

@@ -21,7 +21,8 @@ dependencies = [
"fastapi==0.116.1", "fastapi==0.116.1",
"uvicorn[standard]==0.35.0", "uvicorn[standard]==0.35.0",
"librespot-spotizerr==0.3.0", "librespot-spotizerr==0.3.0",
"rapidfuzz==3.13.0" "rapidfuzz==3.13.0",
"spotipy==2.25.1"
] ]
[project.urls] [project.urls]

View File

@@ -26,6 +26,7 @@ setup(
"fastapi==0.116.1", "fastapi==0.116.1",
"uvicorn[standard]==0.35.0", "uvicorn[standard]==0.35.0",
"librespot-spotizerr==0.3.0", "librespot-spotizerr==0.3.0",
"rapidfuzz" "rapidfuzz==3.13.0",
"spotipy==2.25.1"
], ],
) )