def test_ignores_invalid_album(self, web_track_mock): web_track_mock["album"]["uri"] = None track = translator.web_to_track(web_track_mock) assert track.name == "ABC 123" assert track.album is None
def search(config, session, web_client, query=None, uris=None, exact=False, types=_SEARCH_TYPES): # TODO Respect `uris` argument # TODO Support `exact` search if query is None: logger.debug('Ignored search without query') return models.SearchResult(uri='spotify:search') if 'uri' in query: return _search_by_uri(config, session, query) sp_query = translator.sp_search_query(query) if not sp_query: logger.debug('Ignored search with empty query') return models.SearchResult(uri='spotify:search') uri = 'spotify:search:%s' % urllib.quote(sp_query.encode('utf-8')) logger.info('Searching Spotify for: %s', sp_query) if session.connection.state is not spotify.ConnectionState.LOGGED_IN: logger.info('Spotify search aborted: Spotify is offline') return models.SearchResult(uri=uri) search_count = max( config['search_album_count'], config['search_artist_count'], config['search_track_count']) if search_count > 50: logger.warn( 'Spotify currently allows maximum 50 search results of each type. ' 'Please set the config values spotify/search_album_count, ' 'spotify/search_artist_count and spotify/search_track_count ' 'to at most 50.') search_count = 50 result = web_client.get(_API_BASE_URI, params={ 'q': sp_query, 'limit': search_count, 'type': ','.join(types)}) albums = [ translator.web_to_album(web_album) for web_album in result['albums']['items'][:config['search_album_count']] ] if 'albums' in result else [] artists = [ translator.web_to_artist(web_artist) for web_artist in result['artists']['items'][:config['search_artist_count']] ] if 'artists' in result else [] tracks = [ translator.web_to_track(web_track) for web_track in result['tracks']['items'][:config['search_track_count']] ] if 'tracks' in result else [] return models.SearchResult( uri=uri, albums=albums, artists=artists, tracks=tracks)
def test_ignores_missing_album(self, web_track_mock): del web_track_mock["album"] track = translator.web_to_track(web_track_mock) assert track.name == "ABC 123" assert track.length == 174300 assert track.album is None
def test_filters_out_none_artists(self, web_track_mock): web_track_mock["artists"].insert(0, {}) web_track_mock["artists"].insert(0, {"foo": "bar"}) track = translator.web_to_track(web_track_mock) artists = [models.Artist(uri="spotify:artist:abba", name="ABBA")] assert list(track.artists) == artists
def _lookup_playlist(web_client, config, link): uri = '%s/users/%s/playlists/%s' % (_API_BASE_URI, link.owner, link.id) fields = ['name', 'owner', 'type', 'uri', 'tracks'] result = web_client.get(uri, params={'fields': ','.join(fields)}) if result: for item in result.get('tracks', {}).get('items', []): track = item.get('track', None) if track: yield translator.web_to_track(track, bitrate=config['bitrate'])
def test_successful_translation(self, web_track_mock, web_playlist_mock): track = translator.web_to_track(web_track_mock) playlist = translator.to_playlist(web_playlist_mock) assert playlist.uri == "spotify:user:alice:playlist:foo" assert playlist.name == "Foo" assert playlist.length == 1 assert track in playlist.tracks assert playlist.last_modified is None
def test_successful_translation(self, web_track_mock): track = translator.web_to_track(web_track_mock) assert track.uri == 'spotify:track:abc' assert track.name == 'ABC 123' assert list(track.artists) == [ models.Artist(uri='spotify:artist:abba', name='ABBA') ] assert track.album == models.Album(uri='spotify:album:def', name='DEF 456') assert track.track_no == 7 assert track.disc_no == 1 assert track.length == 174300
def test_calls_web_to_track_ref(self, web_track_mock): ref_mock = mock.Mock(spec=models.Ref.track) ref_mock.uri = str(sentinel.uri) ref_mock.name = str(sentinel.name) with patch.object(translator, "web_to_track_ref", return_value=ref_mock) as ref_func_mock: track = translator.web_to_track(web_track_mock) ref_func_mock.assert_called_once_with(web_track_mock) assert track.uri == str(sentinel.uri) assert track.name == str(sentinel.name)
def test_successful_translation(self, web_track_mock): track = translator.web_to_track(web_track_mock) artists = [models.Artist(uri="spotify:artist:abba", name="ABBA")] assert track.uri == "spotify:track:abc" assert track.name == "ABC 123" assert list(track.artists) == artists assert track.album == models.Album(uri="spotify:album:def", name="DEF 456", artists=artists) assert track.track_no == 7 assert track.disc_no == 1 assert track.length == 174300
def test_successful_translation(self, web_track_mock): track = translator.web_to_track(web_track_mock) artists = [models.Artist(uri='spotify:artist:abba', name='ABBA')] assert track.uri == 'spotify:track:abc' assert track.name == 'ABC 123' assert list(track.artists) == artists assert track.album == models.Album( uri='spotify:album:def', name='DEF 456', artists=artists) assert track.track_no == 7 assert track.disc_no == 1 assert track.length == 174300
def search(config, session, web_client, query=None, uris=None, exact=False, types=_SEARCH_TYPES): # TODO Respect `uris` argument # TODO Support `exact` search if query is None: logger.debug('Ignored search without query') return models.SearchResult(uri='spotify:search') if 'uri' in query: return _search_by_uri(config, session, query, web_client) sp_query = translator.sp_search_query(query) if not sp_query: logger.debug('Ignored search with empty query') return models.SearchResult(uri='spotify:search') uri = 'spotify:search:%s' % urllib.quote(sp_query.encode('utf-8')) logger.info('Searching Spotify for: %s', sp_query) if session.connection.state is not spotify.ConnectionState.LOGGED_IN: logger.info('Spotify search aborted: Spotify is offline') return models.SearchResult(uri=uri) search_count = max(config['search_album_count'], config['search_artist_count'], config['search_track_count']) if search_count > 50: logger.warn( 'Spotify currently allows maximum 50 search results of each type. ' 'Please set the config values spotify/search_album_count, ' 'spotify/search_artist_count and spotify/search_track_count ' 'to at most 50.') search_count = 50 result = web_client.get('search', params={ 'q': sp_query, 'limit': search_count, 'market': session.user_country, 'type': ','.join(types) }) albums = [ translator.web_to_album(web_album) for web_album in result['albums'] ['items'][:config['search_album_count']] ] if 'albums' in result else [] artists = [ translator.web_to_artist(web_artist) for web_artist in result['artists']['items'][:config['search_artist_count']] ] if 'artists' in result else [] tracks = [ translator.web_to_track(web_track) for web_track in result['tracks'] ['items'][:config['search_track_count']] ] if 'tracks' in result else [] return models.SearchResult(uri=uri, albums=albums, artists=artists, tracks=tracks)
def search( config, session, web_client, query=None, uris=None, exact=False, types=_SEARCH_TYPES, ): # TODO Respect `uris` argument # TODO Support `exact` search if query is None: logger.debug("Ignored search without query") return models.SearchResult(uri="spotify:search") if "uri" in query: return _search_by_uri(config, session, web_client, query) sp_query = translator.sp_search_query(query) if not sp_query: logger.debug("Ignored search with empty query") return models.SearchResult(uri="spotify:search") uri = f"spotify:search:{urllib.parse.quote(sp_query)}" logger.info(f"Searching Spotify for: {sp_query}") if session.connection.state is not spotify.ConnectionState.LOGGED_IN: logger.info("Spotify search aborted: Spotify is offline") return models.SearchResult(uri=uri) search_count = max( config["search_album_count"], config["search_artist_count"], config["search_track_count"], ) if search_count > 50: logger.warn( "Spotify currently allows maximum 50 search results of each type. " "Please set the config values spotify/search_album_count, " "spotify/search_artist_count and spotify/search_track_count " "to at most 50.") search_count = 50 result = web_client.get( "search", params={ "q": sp_query, "limit": search_count, "market": "from_token", "type": ",".join(types), }, ) albums = ([ translator.web_to_album(web_album) for web_album in result["albums"] ["items"][:config["search_album_count"]] ] if "albums" in result else []) artists = ([ translator.web_to_artist(web_artist) for web_artist in result["artists"]["items"][:config["search_artist_count"]] ] if "artists" in result else []) tracks = ([ translator.web_to_track(web_track) for web_track in result["tracks"] ["items"][:config["search_track_count"]] ] if "tracks" in result else []) return models.SearchResult(uri=uri, albums=albums, artists=artists, tracks=tracks)
def test_dont_check_playable(self, web_track_mock): del web_track_mock["is_playable"] track = translator.web_to_track(web_track_mock, check_playable=False) assert track is not None
def test_sets_bitrate(self, web_track_mock): track = translator.web_to_track(web_track_mock, bitrate=100) assert track.bitrate == 100
def test_returns_none_if_invalid_ref(self, web_track_mock): with patch.object(translator, "web_to_track_ref", return_value=None): assert translator.web_to_track(web_track_mock) is None