Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
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'])
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
    def test_sets_bitrate(self, web_track_mock):
        track = translator.web_to_track(web_track_mock, bitrate=100)

        assert track.bitrate == 100
Ejemplo n.º 15
0
 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