Skip to content

Commit

Permalink
Switch playlist and starred lookup to web-api
Browse files Browse the repository at this point in the history
  • Loading branch information
adamcik committed Jun 12, 2017
1 parent 7321b0e commit a0250e8
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 51 deletions.
72 changes: 34 additions & 38 deletions mopidy_spotify/lookup.py
Expand Up @@ -27,32 +27,19 @@ def lookup(config, session, web_client, uri):
return []

if web_link.type == 'track':
return list(_lookup_track(web_client, config, uri))
return list(_lookup_track(web_client, config, web_link))
elif web_link.type == 'album':
return list(_lookup_album(web_client, config, uri))
return list(_lookup_album(web_client, config, web_link))
elif web_link.type == 'artist':
with utils.time_logger('Artist lookup'):
return list(_lookup_artist(web_client, config, uri))
return list(_lookup_artist(web_client, config, web_link))
elif web_link.type == 'playlist':
return list(_lookup_playlist(web_client, config, web_link))
elif web_link.type == 'starred':
return list(reversed(_lookup_starred(web_client, config, web_link)))

try:
sp_link = session.get_link(uri)
except ValueError as exc:
logger.info('Failed to lookup "%s": %s', uri, exc)
return []

try:
if sp_link.type is spotify.LinkType.PLAYLIST:
return list(_lookup_playlist(config, sp_link))
elif sp_link.type is spotify.LinkType.STARRED:
return list(reversed(list(_lookup_playlist(config, sp_link))))
else:
logger.info(
'Failed to lookup "%s": Cannot handle %r',
uri, sp_link.type)
return []
except spotify.Error as exc:
logger.info('Failed to lookup "%s": %s', uri, exc)
return []
logger.info('Failed to lookup "%s".', uri)
return []


def web_lookup(web_client, uri):
Expand Down Expand Up @@ -96,13 +83,13 @@ def _process_web_lookups_batch(web_client, uri_type, batch):
return result


def _lookup_track(web_client, config, uri):
def _lookup_track(web_client, config, link):
yield translator.web_to_track(
web_lookup(web_client, uri), bitrate=config['bitrate'])
web_lookup(web_client, link.uri), bitrate=config['bitrate'])


def _lookup_album(web_client, config, uri):
return _convert_album(web_lookup(web_client, uri), config)
def _lookup_album(web_client, config, link):
return _convert_album(web_lookup(web_client, link.uri), config)


def _convert_album(result, config):
Expand All @@ -113,11 +100,10 @@ def _convert_album(result, config):
item, album=album, bitrate=config['bitrate'])


def _lookup_artist(web_client, config, uri):
artist_id = translator.parse_uri(uri).id
def _lookup_artist(web_client, config, link):
artist_result = web_client.get(
'https://api.spotify.com/v1/artists/%s/albums?'
'album_type=album,single&limit=50' % artist_id)
'album_type=album,single&limit=50' % link.id)
# TODO: Limit to given country?
# TODO: Check for result next pagination.
album_uris = [i['uri'] for i in artist_result['items']]
Expand All @@ -130,12 +116,22 @@ def _lookup_artist(web_client, config, uri):
# TODO: Convert to using top tracks for artist?


def _lookup_playlist(config, sp_link):
sp_playlist = sp_link.as_playlist()
sp_playlist.load(config['timeout'])
for sp_track in sp_playlist.tracks:
sp_track.load(config['timeout'])
track = translator.to_track(
sp_track, bitrate=config['bitrate'])
if track is not None:
yield track
def _lookup_playlist(web_client, config, link):
# TODO: Check for result next pagination.
result = web_client.get('https://api.spotify.com/v1/users/%s/playlists/%s/'
'tracks?limit=100&market=from_token' %
(link.id, link.owner))

for item in result['items']:
yield translator.web_to_track(item, bitrate=config['bitrate'])


def _lookup_starred(web_client, config, link):
# TODO: Check for result next pagination.
playlists_result = web_client.get(
'https://api.spotify.com/v1/users/%s/playlists?limit=50' % link.owner)
for playlist in playlists_result['items']:
if playlist['name'] == 'Starred':
link = translator.parse_uri(playlist['uri'])
return list(_lookup_playlist(web_client, config, link))
return []
15 changes: 15 additions & 0 deletions tests/conftest.py
Expand Up @@ -366,6 +366,11 @@ def web_album_simplified_mock():
}


@pytest.fixture
def web_playlist_mock():
return {'name': 'Starred', 'uri': 'spotify:playlist:alice:bar'}


@pytest.fixture
def web_track_lookup_mock(web_track_mock):
return {'tracks': [web_track_mock]}
Expand All @@ -381,6 +386,16 @@ def web_artist_albums_mock(web_album_simplified_mock):
return {'items': [web_album_simplified_mock, web_album_simplified_mock]}


@pytest.fixture
def web_playlist_tracks_mock(web_track_mock):
return {'items': [web_track_mock]}


@pytest.fixture
def web_playlists_mock(web_playlist_mock):
return {'items': [web_playlist_mock]}


@pytest.fixture
def web_oauth_mock():
return {
Expand Down
25 changes: 12 additions & 13 deletions tests/test_lookup.py
Expand Up @@ -65,31 +65,30 @@ def test_lookup_of_artist_uri(web_client_mock, web_artist_albums_mock,
assert track.bitrate == 160


def test_lookup_of_playlist_uri(session_mock, sp_playlist_mock, provider):
session_mock.get_link.return_value = sp_playlist_mock.link
def test_lookup_of_playlist_uri(web_client_mock, web_playlist_tracks_mock,
provider):
web_client_mock.get.return_value = web_playlist_tracks_mock

results = provider.lookup('spotify:playlist:alice:foo')

session_mock.get_link.assert_called_once_with('spotify:playlist:alice:foo')
sp_playlist_mock.link.as_playlist.assert_called_once_with()
sp_playlist_mock.load.assert_called_once_with(10)
sp_playlist_mock.tracks[0].load.assert_called_once_with(10)

assert len(results) == 1
track = results[0]
assert track.uri == 'spotify:track:abc'
assert track.name == 'ABC 123'
assert track.bitrate == 160


def test_lookup_of_starred_uri(session_mock, sp_starred_mock, provider):
session_mock.get_link.return_value = sp_starred_mock.link
def test_lookup_of_starred_uri(web_client_mock, web_playlists_mock,
web_playlist_tracks_mock, provider):
track = web_playlist_tracks_mock['items'][0].copy()
track['uri'] = 'spotify:track:newest'
track['name'] = 'Newest'
web_playlist_tracks_mock['items'].append(track)

results = provider.lookup('spotify:user:alice:starred')
web_client_mock.get.side_effect = (web_playlists_mock,
web_playlist_tracks_mock)

session_mock.get_link.assert_called_once_with('spotify:user:alice:starred')
sp_starred_mock.link.as_playlist.assert_called_once_with()
sp_starred_mock.load.assert_called_once_with(10)
results = provider.lookup('spotify:user:alice:starred')

assert len(results) == 2
track = results[0]
Expand Down

0 comments on commit a0250e8

Please sign in to comment.