Example #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,
        )
Example #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,
        )
Example #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)
Example #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)
Example #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,
        )
Example #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)
Example #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']
Example #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]
Example #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]')
Example #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]
Example #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)
Example #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])')
Example #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)
Example #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)
Example #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)
Example #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)
Example #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)
Example #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)
Example #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)
Example #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)
Example #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)
Example #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)
Example #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,
        )