feat: implement librespot-powered search
This commit is contained in:
@@ -8,7 +8,7 @@ from typing import Any, Dict, List, Optional, Union
|
||||
from google.protobuf.descriptor import FieldDescriptor
|
||||
from google.protobuf.message import Message
|
||||
|
||||
from librespot.core import Session
|
||||
from librespot.core import Session, SearchManager
|
||||
from librespot.metadata import AlbumId, ArtistId, PlaylistId, TrackId
|
||||
from librespot import util
|
||||
from librespot.proto import Metadata_pb2 as Metadata
|
||||
@@ -68,6 +68,34 @@ class LibrespotClient:
|
||||
playlist_proto = self._session.api().get_playlist(playlist_id)
|
||||
return self._playlist_proto_to_object(playlist_proto, include_track_objects=expand_items)
|
||||
|
||||
def search(
|
||||
self,
|
||||
query: str,
|
||||
limit: int = 10,
|
||||
country: Optional[str] = None,
|
||||
locale: Optional[str] = None,
|
||||
catalogue: Optional[str] = None,
|
||||
image_size: Optional[str] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""Perform a full-featured search using librespot's SearchManager.
|
||||
|
||||
- country precedence: explicit country > session country code > unset
|
||||
- returns the raw JSON-like mapping response provided by librespot
|
||||
"""
|
||||
req = SearchManager.SearchRequest(query).set_limit(limit)
|
||||
# Country precedence
|
||||
cc = country or self._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 = self._session.search().request(req)
|
||||
return res
|
||||
|
||||
# ---------- ID parsing helpers ----------
|
||||
|
||||
@staticmethod
|
||||
@@ -118,6 +146,18 @@ class LibrespotClient:
|
||||
builder.stored_file(stored_credentials_path)
|
||||
return builder.create()
|
||||
|
||||
def _get_session_country_code(self) -> str:
|
||||
try:
|
||||
cc = getattr(self._session, "_Session__country_code", None)
|
||||
if isinstance(cc, str) and len(cc) == 2:
|
||||
return cc
|
||||
cc2 = getattr(self._session, "country_code", None)
|
||||
if isinstance(cc2, str) and len(cc2) == 2:
|
||||
return cc2
|
||||
except Exception:
|
||||
pass
|
||||
return ""
|
||||
|
||||
# ---------- Private: ID coercion ----------
|
||||
|
||||
def _ensure_track_id(self, v: Union[str, TrackId]) -> TrackId:
|
||||
|
||||
Reference in New Issue
Block a user