diff --git a/core/genius_client.py b/core/genius_client.py index 7ac2f36d..f7b8cc18 100644 --- a/core/genius_client.py +++ b/core/genius_client.py @@ -212,24 +212,47 @@ class GeniusClient: Returns: Artist dict with: id, name, url, image_url """ - hits = self.search(artist_name, per_page=5) - if not hits: + artists = self.search_artists(artist_name, limit=10) + if not artists: return None artist_lower = artist_name.lower().strip() - for hit in hits: - result = hit.get('result', {}) - primary = result.get('primary_artist', {}) - primary_name = (primary.get('name') or '').lower() - if primary and (artist_lower in primary_name or primary_name in artist_lower): - logger.debug(f"Found artist: {primary.get('name')}") - return primary + for a in artists: + a_name = (a.get('name') or '').lower() + if artist_lower in a_name or a_name in artist_lower: + logger.debug(f"Found artist: {a.get('name')}") + return a # No confident match — let the worker mark as not_found and retry later logger.debug(f"No artist match found in search results for: {artist_name}") return None + @rate_limited + def search_artists(self, query: str, limit: int = 10) -> List[Dict[str, Any]]: + """ + Search for artists by name. Extracts unique artists from song results. + + Returns: + List of artist dicts with: id, name, url, image_url + """ + hits = self.search(query, per_page=min(limit * 2, 20)) + if not hits: + return [] + + seen_ids = set() + artists = [] + for hit in hits: + result = hit.get('result', {}) + primary = result.get('primary_artist', {}) + if primary and primary.get('id') and primary['id'] not in seen_ids: + seen_ids.add(primary['id']) + artists.append(primary) + if len(artists) >= limit: + break + + return artists + @rate_limited def get_artist(self, artist_id: int) -> Optional[Dict[str, Any]]: """ diff --git a/web_server.py b/web_server.py index c7919ff3..d63f5ae5 100644 --- a/web_server.py +++ b/web_server.py @@ -12614,15 +12614,22 @@ def _search_service(service, entity_type, query): raise ValueError("Genius worker not initialized") client = genius_worker.client if entity_type == 'artist': - result = client.search_artist(query) - if result: - return [{'id': str(result.get('id', '')), 'name': result.get('name', ''), - 'image': result.get('image_url'), 'extra': ''}] + artists = client.search_artists(query, limit=8) + return [{'id': str(a.get('id', '')), 'name': a.get('name', ''), + 'image': a.get('image_url'), 'extra': a.get('url', '')} for a in artists] elif entity_type == 'track': - result = client.search_song(query, '') - if result: - return [{'id': str(result.get('id', '')), 'name': result.get('title', ''), - 'image': result.get('song_art_image_url'), 'extra': result.get('artist_names', '')}] + # Search with broader results for manual matching + hits = client.search(f"{query}", per_page=10) + results = [] + seen_ids = set() + for hit in hits: + r = hit.get('result', {}) + rid = r.get('id') + if rid and rid not in seen_ids: + seen_ids.add(rid) + results.append({'id': str(rid), 'name': r.get('title', ''), + 'image': r.get('song_art_image_url'), 'extra': r.get('artist_names', '')}) + return results return [] elif service == 'tidal':