Пример #1
0
    def albums(self):
        """The albums matching the search query.

        Will always return an empty list if the search isn't loaded.
        """
        spotify.Error.maybe_raise(
            self.error, ignores=[spotify.ErrorType.IS_LOADING]
        )
        if not self.is_loaded:
            return []

        @serialized
        def get_album(sp_search, key):
            return spotify.Album(
                self._session,
                sp_album=lib.sp_search_album(sp_search, key),
                add_ref=True,
            )

        return utils.Sequence(
            sp_obj=self._sp_search,
            add_ref_func=lib.sp_search_add_ref,
            release_func=lib.sp_search_release,
            len_func=lib.sp_search_num_albums,
            getitem_func=get_album,
        )
Пример #2
0
    def playlists(self):
        """The playlists matching the search query as
        :class:`SearchPlaylist` objects containing the name, URI and
        image URI for matching playlists.

        Will always return an empty list if the search isn't loaded.
        """
        spotify.Error.maybe_raise(
            self.error, ignores=[spotify.ErrorType.IS_LOADING]
        )
        if not self.is_loaded:
            return []

        @serialized
        def getitem(sp_search, key):
            return spotify.SearchPlaylist(
                self._session,
                name=utils.to_unicode(
                    lib.sp_search_playlist_name(self._sp_search, key)
                ),
                uri=utils.to_unicode(
                    lib.sp_search_playlist_uri(self._sp_search, key)
                ),
                image_uri=utils.to_unicode(
                    lib.sp_search_playlist_image_uri(self._sp_search, key)
                ),
            )

        return utils.Sequence(
            sp_obj=self._sp_search,
            add_ref_func=lib.sp_search_add_ref,
            release_func=lib.sp_search_release,
            len_func=lib.sp_search_num_playlists,
            getitem_func=getitem,
        )
Пример #3
0
    def test_getitem_with_slice(self, lib_mock):
        sp_search = spotify.ffi.cast('sp_search *', 42)
        getitem_func = mock.Mock()
        getitem_func.side_effect = [
            mock.sentinel.item_one,
            mock.sentinel.item_two,
            mock.sentinel.item_three,
        ]
        seq = utils.Sequence(
            sp_obj=sp_search,
            add_ref_func=lib_mock.sp_search_add_ref,
            release_func=lib_mock.sp_search_release,
            len_func=lambda x: 3,
            getitem_func=getitem_func,
        )

        result = seq[0:2]

        # Entire collection of length 3 is created as a list
        self.assertEqual(getitem_func.call_count, 3)

        # Only a subslice of length 2 is returned
        self.assertIsInstance(result, list)
        self.assertEqual(len(result), 2)
        self.assertEqual(result[0], mock.sentinel.item_one)
        self.assertEqual(result[1], mock.sentinel.item_two)
Пример #4
0
    def portraits(self, callback=None):
        """The artist's portraits.

        Due to limitations in libspotify's API you can't specify the
        :class:`ImageSize` of these images.

        If ``callback`` isn't :class:`None`, it is expected to be a callable
        that accepts a single argument, an :class:`Image` instance, when
        the image is done loading. The callable will be called once for each
        portrait.

        Will always return an empty list if the artist browser isn't loaded.
        """
        if not self.is_loaded:
            return []

        @serialized
        def get_image(sp_artistbrowse, key):
            image_id = lib.sp_artistbrowse_portrait(sp_artistbrowse, key)
            sp_image = lib.sp_image_create(image_id)
            return spotify.Image(self._session,
                                 sp_image=sp_image,
                                 add_ref=False,
                                 callback=callback)

        return utils.Sequence(sp_obj=self._sp_artistbrowse,
                              add_ref_func=lib.sp_artistbrowse_add_ref,
                              release_func=lib.sp_artistbrowse_release,
                              len_func=lib.sp_artistbrowse_num_portraits,
                              getitem_func=get_image)
Пример #5
0
    def artists(self):
        """The artists performing on the track.

        Will always return an empty list if the track isn't loaded.
        """
        spotify.Error.maybe_raise(self.error,
                                  ignores=[spotify.ErrorType.IS_LOADING])
        if not self.is_loaded:
            return []

        @serialized
        def get_artist(sp_track, key):
            return spotify.Artist(
                self._session,
                sp_artist=lib.sp_track_artist(sp_track, key),
                add_ref=True,
            )

        return utils.Sequence(
            sp_obj=self._sp_track,
            add_ref_func=lib.sp_track_add_ref,
            release_func=lib.sp_track_release,
            len_func=lib.sp_track_num_artists,
            getitem_func=get_artist,
        )
Пример #6
0
    def test_adds_ref_to_sp_obj_when_created(self, lib_mock):
        sp_search = spotify.ffi.new('int *')
        utils.Sequence(sp_obj=sp_search,
                       add_ref_func=lib_mock.sp_search_add_ref,
                       release_func=lib_mock.sp_search_release,
                       len_func=None,
                       getitem_func=None)

        self.assertEqual(lib_mock.sp_search_add_ref.call_count, 1)
Пример #7
0
    def test_getitem_raises_type_error_on_non_integral_index(self, lib_mock):
        sp_search = spotify.ffi.new('int *')
        seq = utils.Sequence(sp_obj=sp_search,
                             add_ref_func=lib_mock.sp_search_add_ref,
                             release_func=lib_mock.sp_search_release,
                             len_func=lambda x: 1,
                             getitem_func=None)

        with self.assertRaises(TypeError):
            seq['abc']
Пример #8
0
    def test_getitem_raises_index_error_on_too_high_index(self, lib_mock):
        sp_search = spotify.ffi.new('int *')
        seq = utils.Sequence(sp_obj=sp_search,
                             add_ref_func=lib_mock.sp_search_add_ref,
                             release_func=lib_mock.sp_search_release,
                             len_func=lambda x: 1,
                             getitem_func=None)

        with self.assertRaises(IndexError):
            seq[1]
Пример #9
0
    def test_repr(self, lib_mock):
        sp_search = spotify.ffi.new('int *')
        seq = utils.Sequence(sp_obj=sp_search,
                             add_ref_func=lib_mock.sp_search_add_ref,
                             release_func=lib_mock.sp_search_release,
                             len_func=lambda x: 1,
                             getitem_func=lambda s, i: 123)

        result = repr(seq)

        self.assertEqual(result, '[123]')
Пример #10
0
    def test_getitem_raises_index_error_on_too_low_index(self, lib_mock):
        sp_search = spotify.ffi.cast('sp_search *', 42)
        seq = utils.Sequence(
            sp_obj=sp_search,
            add_ref_func=lib_mock.sp_search_add_ref,
            release_func=lib_mock.sp_search_release,
            len_func=lambda x: 1,
            getitem_func=None,
        )

        with self.assertRaises(IndexError):
            seq[-3]
Пример #11
0
    def test_releases_sp_obj_when_sequence_dies(self, lib_mock):
        sp_search = spotify.ffi.new('int *')
        seq = utils.Sequence(sp_obj=sp_search,
                             add_ref_func=lib_mock.sp_search_add_ref,
                             release_func=lib_mock.sp_search_release,
                             len_func=None,
                             getitem_func=None)

        seq = None  # noqa
        tests.gc_collect()

        self.assertEqual(lib_mock.sp_search_release.call_count, 1)
Пример #12
0
    def test_repr(self, lib_mock):
        sp_search = spotify.ffi.cast('sp_search *', 42)
        seq = utils.Sequence(
            sp_obj=sp_search,
            add_ref_func=lib_mock.sp_search_add_ref,
            release_func=lib_mock.sp_search_release,
            len_func=lambda x: 1,
            getitem_func=lambda s, i: 123,
        )

        result = repr(seq)

        self.assertEqual(result, 'Sequence([123])')
Пример #13
0
    def test_getitem_with_negative_index(self, lib_mock):
        sp_search = spotify.ffi.cast('sp_search *', 42)
        getitem_func = mock.Mock()
        getitem_func.return_value = mock.sentinel.item_one
        seq = utils.Sequence(sp_obj=sp_search,
                             add_ref_func=lib_mock.sp_search_add_ref,
                             release_func=lib_mock.sp_search_release,
                             len_func=lambda x: 1,
                             getitem_func=getitem_func)

        result = seq[-1]

        self.assertEqual(result, mock.sentinel.item_one)
        getitem_func.assert_called_with(sp_search, 0)
Пример #14
0
    def test_getitem_calls_getitem_func(self, lib_mock):
        sp_search = spotify.ffi.new('int *')
        getitem_func = mock.Mock()
        getitem_func.return_value = mock.sentinel.item_one
        seq = utils.Sequence(sp_obj=sp_search,
                             add_ref_func=lib_mock.sp_search_add_ref,
                             release_func=lib_mock.sp_search_release,
                             len_func=lambda x: 1,
                             getitem_func=getitem_func)

        result = seq[0]

        self.assertEqual(result, mock.sentinel.item_one)
        getitem_func.assert_called_with(sp_search, 0)
Пример #15
0
    def test_len_calls_len_func(self, lib_mock):
        sp_search = spotify.ffi.new('int *')
        len_func = mock.Mock()
        len_func.return_value = 0
        seq = utils.Sequence(sp_obj=sp_search,
                             add_ref_func=lib_mock.sp_search_add_ref,
                             release_func=lib_mock.sp_search_release,
                             len_func=len_func,
                             getitem_func=None)

        result = len(seq)

        self.assertEqual(result, 0)
        len_func.assert_called_with(sp_search)
Пример #16
0
    def copyrights(self):
        """The album's copyright strings.

        Will always return an empty list if the album browser isn't loaded.
        """
        if not self.is_loaded:
            return []

        @serialized
        def get_copyright(sp_albumbrowse, key):
            return utils.to_unicode(
                lib.sp_albumbrowse_copyright(sp_albumbrowse, key))

        return utils.Sequence(sp_obj=self._sp_albumbrowse,
                              add_ref_func=lib.sp_albumbrowse_add_ref,
                              release_func=lib.sp_albumbrowse_release,
                              len_func=lib.sp_albumbrowse_num_copyrights,
                              getitem_func=get_copyright)
Пример #17
0
    def portraits(self):
        """The artist's portraits.

        Will always return an empty list if the artist browser isn't loaded.
        """
        if not self.is_loaded:
            return []

        @serialized
        def get_image(sp_artistbrowse, key):
            image_id = lib.sp_artistbrowse_portrait(sp_artistbrowse, key)
            sp_image = lib.sp_image_create(image_id)
            return spotify.Image(sp_image=sp_image, add_ref=False)

        return utils.Sequence(sp_obj=self._sp_artistbrowse,
                              add_ref_func=lib.sp_artistbrowse_add_ref,
                              release_func=lib.sp_artistbrowse_release,
                              len_func=lib.sp_artistbrowse_num_portraits,
                              getitem_func=get_image)
Пример #18
0
    def artists(self):
        """The artists performing on the track.

        Will always return :class:`None` if the track isn't loaded.
        """
        spotify.Error.maybe_raise(self.error)
        if not self.is_loaded:
            return []

        @serialized
        def get_artist(sp_track, key):
            return spotify.Artist(sp_artist=lib.sp_track_artist(sp_track, key),
                                  add_ref=True)

        return utils.Sequence(sp_obj=self._sp_track,
                              add_ref_func=lib.sp_track_add_ref,
                              release_func=lib.sp_track_release,
                              len_func=lib.sp_track_num_artists,
                              getitem_func=get_artist)
Пример #19
0
    def tophit_tracks(self):
        """The artist's top hit tracks.

        Will always return an empty list if the artist browser isn't loaded.
        """
        if not self.is_loaded:
            return []

        @serialized
        def get_track(sp_artistbrowse, key):
            return spotify.Track(sp_track=lib.sp_artistbrowse_tophit_track(
                sp_artistbrowse, key),
                                 add_ref=True)

        return utils.Sequence(sp_obj=self._sp_artistbrowse,
                              add_ref_func=lib.sp_artistbrowse_add_ref,
                              release_func=lib.sp_artistbrowse_release,
                              len_func=lib.sp_artistbrowse_num_tophit_tracks,
                              getitem_func=get_track)
Пример #20
0
    def similar_artists(self):
        """The artist's similar artists.

        Will always return an empty list if the artist browser isn't loaded.
        """
        if not self.is_loaded:
            return []

        @serialized
        def get_artist(sp_artistbrowse, key):
            return spotify.Artist(sp_artist=lib.sp_artistbrowse_similar_artist(
                sp_artistbrowse, key),
                                  add_ref=True)

        return utils.Sequence(sp_obj=self._sp_artistbrowse,
                              add_ref_func=lib.sp_artistbrowse_add_ref,
                              release_func=lib.sp_artistbrowse_release,
                              len_func=lib.sp_artistbrowse_num_similar_artists,
                              getitem_func=get_artist)
Пример #21
0
    def artists(self):
        """The artists in the toplist.

        Will always return an empty list if the toplist isn't loaded.
        """
        spotify.Error.maybe_raise(self.error)
        if not self.is_loaded:
            return []

        @serialized
        def get_artist(sp_toplistbrowse, key):
            return spotify.Artist(sp_artist=lib.sp_toplistbrowse_artist(
                sp_toplistbrowse, key),
                                  add_ref=True)

        return utils.Sequence(sp_obj=self._sp_toplistbrowse,
                              add_ref_func=lib.sp_toplistbrowse_add_ref,
                              release_func=lib.sp_toplistbrowse_release,
                              len_func=lib.sp_toplistbrowse_num_artists,
                              getitem_func=get_artist)
Пример #22
0
    def albums(self):
        """The artist's albums.

        Will be an empty list if the browser was created with a ``type`` of
        :attr:`ArtistBrowserType.NO_ALBUMS`.

        Will always return an empty list if the artist browser isn't loaded.
        """
        if not self.is_loaded:
            return []

        @serialized
        def get_album(sp_artistbrowse, key):
            return spotify.Album(sp_album=lib.sp_artistbrowse_album(
                sp_artistbrowse, key),
                                 add_ref=True)

        return utils.Sequence(sp_obj=self._sp_artistbrowse,
                              add_ref_func=lib.sp_artistbrowse_add_ref,
                              release_func=lib.sp_artistbrowse_release,
                              len_func=lib.sp_artistbrowse_num_albums,
                              getitem_func=get_album)
Пример #23
0
    def tracks(self):
        """The tracks in the toplist.

        Will always return an empty list if the toplist isn't loaded.
        """
        spotify.Error.maybe_raise(self.error)
        if not self.is_loaded:
            return []

        @serialized
        def get_track(sp_toplistbrowse, key):
            return spotify.Track(
                self._session,
                sp_track=lib.sp_toplistbrowse_track(sp_toplistbrowse, key),
                add_ref=True,
            )

        return utils.Sequence(
            sp_obj=self._sp_toplistbrowse,
            add_ref_func=lib.sp_toplistbrowse_add_ref,
            release_func=lib.sp_toplistbrowse_release,
            len_func=lib.sp_toplistbrowse_num_tracks,
            getitem_func=get_track,
        )