Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions src/artist_tracker/tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,15 +290,15 @@ def _is_noise(self, title: str) -> bool:
return True
return False

def _search_artist(self, artist_name: str) -> Optional[str]:
def _search_artist(self, artist_name: str) -> Tuple[Optional[str], Optional[str]]:
"""
Search for an artist by name and return their ID with retry logic.
Search for an artist by name and return their ID and official name with retry logic.

Args:
artist_name: Name of the artist to search

Returns:
Artist ID or None if not found
Tuple of (Artist ID, Official Name). Both None if not found.

Raises:
SpotifyAPIError: If API call fails after retries
Expand All @@ -316,11 +316,12 @@ def search_call():
if results['artists']['items']:
artist = results['artists']['items'][0]
artist_id = artist['id']
logger.info(f"Found artist '{artist['name']}' (ID: {artist_id})")
return artist_id
official_name = artist['name']
logger.info(f"Found artist '{official_name}' (ID: {artist_id})")
return artist_id, official_name
else:
logger.warning(f"No results found for artist '{artist_name}'")
return None
return None, None

except (SpotifyAPIError, RateLimitError) as e:
logger.error(f"API error searching for artist '{artist_name}': {e}")
Expand Down Expand Up @@ -672,15 +673,11 @@ def _process_artist(

# Get artist ID if we have a name
if artist_name and not artist_id:
artist_id = self._search_artist(artist_name)
artist_id, official_name = self._search_artist(artist_name)
if not artist_id:
return artist_name, [] # Return name for missing artists tracking

# Update artist_name to the official one from Spotify to fix capitalization
# We already did a search, so ideally we'd get the name from that result,
# but _search_artist only returns the ID.
# Let's fetch the official name using the ID.
official_name = self._get_artist_name(artist_id)
if official_name:
artist_name = official_name

Expand Down
16 changes: 10 additions & 6 deletions tests/test_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ def test_search_artist_success(self):
}
}

artist_id = self.tracker._search_artist('Taylor Swift')
artist_id, artist_name = self.tracker._search_artist('Taylor Swift')
self.assertEqual(artist_id, 'artist123')
self.assertEqual(artist_name, 'Taylor Swift')
self.tracker.sp.search.assert_called_once()

def test_search_artist_not_found(self):
Expand All @@ -166,8 +167,9 @@ def test_search_artist_not_found(self):
}
}

artist_id = self.tracker._search_artist('NonexistentArtist')
artist_id, artist_name = self.tracker._search_artist('NonexistentArtist')
self.assertIsNone(artist_id)
self.assertIsNone(artist_name)

def test_get_artist_name_success(self):
"""Test getting artist name by ID."""
Expand Down Expand Up @@ -449,9 +451,10 @@ def test_retry_on_server_error(self, mock_sleep):
{'artists': {'items': [{'id': 'artist123', 'name': 'Test'}]}}
]

result = self.tracker._search_artist('Test Artist')
artist_id, artist_name = self.tracker._search_artist('Test Artist')

self.assertEqual(result, 'artist123')
self.assertEqual(artist_id, 'artist123')
self.assertEqual(artist_name, 'Test')
self.assertEqual(self.tracker.sp.search.call_count, 2)
mock_sleep.assert_called() # Should have slept between retries

Expand All @@ -469,9 +472,10 @@ def test_retry_on_rate_limit(self, mock_sleep):
{'artists': {'items': [{'id': 'artist123', 'name': 'Test'}]}}
]

result = self.tracker._search_artist('Test Artist')
artist_id, artist_name = self.tracker._search_artist('Test Artist')

self.assertEqual(result, 'artist123')
self.assertEqual(artist_id, 'artist123')
self.assertEqual(artist_name, 'Test')
self.assertEqual(self.tracker.sp.search.call_count, 2)

def test_client_error_no_retry(self):
Expand Down