示例#1
0
    def test_add_tracks_without_index(self, track_lib_mock, lib_mock):
        lib_mock.sp_playlist_add_tracks.return_value = int(spotify.ErrorType.OK)
        lib_mock.sp_playlist_num_tracks.return_value = 10
        sp_track1 = spotify.ffi.new('int * ')
        track1 = spotify.Track(self.session, sp_track=sp_track1)
        sp_track2 = spotify.ffi.new('int * ')
        track2 = spotify.Track(self.session, sp_track=sp_track2)
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)

        playlist.add_tracks([track1, track2])

        lib_mock.sp_playlist_add_tracks.assert_called_with(
            sp_playlist, [sp_track1, sp_track2], 2, 10, self.session._sp_session
        )
示例#2
0
    def test_subscribers(self, lib_mock):
        sp_subscribers = spotify.ffi.new('sp_subscribers *')
        sp_subscribers.count = 1
        user_alice = spotify.ffi.new('char[]', b'alice')
        sp_subscribers.subscribers = [user_alice]
        lib_mock.sp_playlist_subscribers.return_value = sp_subscribers
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)

        result = playlist.subscribers

        lib_mock.sp_playlist_subscribers.assert_called_with(sp_playlist)
        tests.gc_collect()
        lib_mock.sp_playlist_subscribers_free.assert_called_with(sp_subscribers)
        self.assertEqual(result, ['alice'])
示例#3
0
    def test_life_cycle(self, lib_mock):
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)

        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)
        sp_playlist = playlist._sp_playlist

        lib_mock.sp_playlist_add_ref.assert_called_with(sp_playlist)
        lib_mock.sp_playlist_add_callbacks.assert_called_with(
            sp_playlist, mock.ANY, mock.ANY)

        playlist = None  # noqa
        tests.gc_collect()

        lib_mock.sp_playlist_remove_callbacks.assert_called_with(
            sp_playlist, mock.ANY, mock.ANY)
示例#4
0
    def test_tracks_delitem_with_slice(self, lib_mock):
        lib_mock.sp_playlist_remove_tracks.return_value = int(
            spotify.ErrorType.OK
        )
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)
        tracks = playlist.tracks
        tracks.__len__ = mock.Mock(return_value=3)

        del tracks[0:2]

        # Delete items in reverse order, so the indexes doesn't change
        lib_mock.sp_playlist_remove_tracks.assert_has_calls(
            [mock.call(sp_playlist, [1], 1), mock.call(sp_playlist, [0], 1)],
            any_order=False,
        )
示例#5
0
    def test_reorder_tracks(self, track_lib_mock, lib_mock):
        lib_mock.sp_playlist_reorder_tracks.return_value = int(
            spotify.ErrorType.OK)
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)
        position1 = 13
        position2 = 17

        playlist.reorder_tracks([position1, position2], 17)

        lib_mock.sp_playlist_reorder_tracks.assert_called_with(
            sp_playlist, mock.ANY, 2, 17)
        self.assertIn(position1,
                      lib_mock.sp_playlist_reorder_tracks.call_args[0][1])
        self.assertIn(position2,
                      lib_mock.sp_playlist_reorder_tracks.call_args[0][1])
示例#6
0
    def test_remove_tracks(self, track_lib_mock, lib_mock):
        lib_mock.sp_playlist_remove_tracks.return_value = int(
            spotify.ErrorType.OK)
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)
        index1 = 13
        index2 = 17

        playlist.remove_tracks([index1, index2])

        lib_mock.sp_playlist_remove_tracks.assert_called_with(
            sp_playlist, mock.ANY, 2)
        self.assertIn(index1,
                      lib_mock.sp_playlist_remove_tracks.call_args[0][1])
        self.assertIn(index2,
                      lib_mock.sp_playlist_remove_tracks.call_args[0][1])
示例#7
0
    def test_link_may_fail_if_playlist_has_not_been_in_ram(
        self, link_mock, lib_mock
    ):
        lib_mock.sp_playlist_is_loaded.return_value = 1
        lib_mock.sp_link_create_from_playlist.return_value = spotify.ffi.NULL
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)

        with self.assertRaises(spotify.Error):
            playlist.link

        # Condition is checked only if link creation returns NULL
        lib_mock.sp_link_create_from_playlist.assert_called_with(sp_playlist)
        lib_mock.sp_playlist_is_in_ram.assert_called_with(
            self.session._sp_session, sp_playlist
        )
示例#8
0
    def test_tracks(self, track_lib_mock, lib_mock):
        sp_track = spotify.ffi.cast('sp_track *', 43)
        lib_mock.sp_playlist_num_tracks.return_value = 1
        lib_mock.sp_playlist_track.return_value = sp_track
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)

        self.assertEqual(lib_mock.sp_playlist_add_ref.call_count, 1)
        result = playlist.tracks
        self.assertEqual(lib_mock.sp_playlist_add_ref.call_count, 2)

        self.assertEqual(len(result), 1)
        lib_mock.sp_playlist_num_tracks.assert_called_with(sp_playlist)

        item = result[0]
        self.assertIsInstance(item, spotify.Track)
        self.assertEqual(item._sp_track, sp_track)
        self.assertEqual(lib_mock.sp_playlist_track.call_count, 1)
        lib_mock.sp_playlist_track.assert_called_with(sp_playlist, 0)
        track_lib_mock.sp_track_add_ref.assert_called_with(sp_track)
示例#9
0
    def test_tracks_setitem_with_slice(self, lib_mock):
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)
        tracks = playlist.tracks
        tracks.__len__ = mock.Mock(return_value=5)
        playlist.remove_tracks = mock.Mock()
        playlist.add_tracks = mock.Mock()

        tracks[0:2] = [mock.sentinel.track1, mock.sentinel.track2]

        playlist.add_tracks.assert_has_calls(
            [
                mock.call(mock.sentinel.track1, index=0),
                mock.call(mock.sentinel.track2, index=1),
            ],
            any_order=False,
        )
        playlist.remove_tracks.assert_has_calls(
            [mock.call(3), mock.call(2)], any_order=False
        )
示例#10
0
    def test_life_cycle(self, lib_mock):
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)

        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)
        sp_playlist = playlist._sp_playlist

        lib_mock.sp_playlist_add_ref.assert_called_with(sp_playlist)

        # Callbacks are only added when someone registers a Python event
        # handler on the playlist:
        lib_mock.sp_playlist_add_callbacks.assert_not_called()
        playlist.on(spotify.PlaylistEvent.TRACKS_ADDED, lambda *args: None)
        lib_mock.sp_playlist_add_callbacks.assert_called_with(
            sp_playlist, mock.ANY, mock.ANY
        )

        playlist = None  # noqa
        tests.gc_collect()

        # Callbacks are removed when the playlist is GC-ed:
        lib_mock.sp_playlist_remove_callbacks.assert_called_with(
            sp_playlist, mock.ANY, mock.ANY
        )
async def get_spotify_tracks(
    ctx, search_type: str, spotify_id: str, spotify_client, spotify_http
) -> t.Tuple[str, list]:
    name = None
    search_tracks = None

    try:
        if search_type == "album":
            search_result = await spotify_client.get_album(spotify_id=spotify_id)

            name = search_result.name
            search_tracks = await search_result.get_all_tracks()

            if len(search_tracks) > 500:
                search_tracks = search_tracks[:500]

        elif search_type == "playlist":
            search_result = spotify.Playlist(
                client=spotify_client, data=await spotify_http.get_playlist(spotify_id)
            )
            name = search_result.name
            search_tracks = list(await search_result.get_all_tracks())

            if len(search_tracks) > 500:
                search_tracks = search_tracks[:500]

        elif search_type == "track":
            search_result = await spotify_client.get_track(spotify_id=spotify_id)
            name = search_result.name
            search_tracks = [search_result]

    except (spotify.NotFound, discord.HTTPException):
        return await ctx.send(
            "No results were found for your spotify link.", delete_after=15
        )

    return name, search_tracks
示例#12
0
    def get_playlist(self, uri):
        """
        Get :class:`Playlist` from a Spotify playlist URI.

        .. warning::

            The playlists API was broken at 2018-05-24 by a server-side change
            made by Spotify. The functionality was never restored.

            Please use the Spotify Web API to work with playlists.

        Example::

            >>> session = spotify.Session()
            # ...
            >>> playlist = session.get_playlist(
            ...     'spotify:user:fiat500c:playlist:54k50VZdvtnIPt4d8RBCmZ')
            >>> playlist.load().name
            u'500C feelgood playlist'
        """
        warnings.warn("Spotify broke the libspotify playlists API 2018-05-24 "
                      "and never restored it. "
                      "Please use the Spotify Web API to work with playlists.")
        return spotify.Playlist(self, uri=uri)
示例#13
0
 def test_create_without_uri_or_sp_playlist_fails(self, lib_mock):
     with self.assertRaises(AssertionError):
         spotify.Playlist(self.session)
示例#14
0
    async def search(self, query: str,
                     ctx: context.Context) -> objects.SearchResult:

        search_result = None
        search_tracks = None

        spotify_url_check = self.spotify_url_regex.match(query)
        if spotify_url_check is not None:

            source = 'spotify'

            spotify_client: spotify.Client = self.bot.cogs["Music"].spotify
            spotify_http_client: spotify.HTTPClient = self.bot.cogs[
                "Music"].spotify_http

            search_type = spotify_url_check.group('type')
            spotify_id = spotify_url_check.group('id')

            try:
                if search_type == 'album':
                    search_result = await spotify_client.get_album(
                        spotify_id=spotify_id)
                    search_tracks = await search_result.get_all_tracks()
                elif search_type == 'playlist':
                    search_result = spotify.Playlist(
                        client=spotify_client,
                        data=await
                        spotify_http_client.get_playlist(spotify_id))
                    search_tracks = await search_result.get_all_tracks()
                elif search_type == 'track':
                    search_result = await spotify_client.get_track(
                        spotify_id=spotify_id)
                    search_tracks = [search_result]

            except spotify.NotFound or HTTPException:
                raise exceptions.VoiceError(
                    f'No results were found for your Spotify link.')
            if not search_tracks:
                raise exceptions.VoiceError(
                    f'No results were found for your Spotify link.')

            tracks = [
                slate.Track(
                    track_id='',
                    ctx=ctx,
                    track_info={
                        'title':
                        track.name or 'Unknown',
                        'author':
                        ', '.join(artist.name
                                  for artist in track.artists) or 'Unknown',
                        'length':
                        track.duration or 0,
                        'identifier':
                        track.id or 'Unknown',
                        'uri':
                        track.url or 'spotify',
                        'isStream':
                        False,
                        'isSeekable':
                        False,
                        'position':
                        0,
                        'thumbnail':
                        track.images[0].url if track.images else None
                    },
                ) for track in search_tracks
            ]

        else:

            url = yarl.URL(query)
            if not url.host or not url.scheme:
                if query.startswith('soundcloud'):
                    query = f'scsearch:{query[11:]}'
                else:
                    query = f'ytsearch:{query}'

            try:
                search_result = await self.node.search(query=query, ctx=ctx)
            except slate.TrackLoadError as error:
                raise exceptions.VoiceError(
                    f'`{error.status_code}` error code while searching for results. For support use `{self.bot.config.prefix}support`.'
                )
            except slate.TrackLoadFailed as error:
                raise exceptions.VoiceError(
                    f'`{error.severity}` error while searching for results. For support use `{self.bot.config.prefix}support`.\nReason: `{error.message}`'
                )

            if not search_result:
                raise exceptions.VoiceError(
                    f'No results were found for your search.')

            if isinstance(search_result, slate.Playlist):
                source = 'youtube'
                search_type = 'playlist'
                tracks = search_result.tracks
            else:
                source = search_result[0].source
                search_type = 'track'
                tracks = search_result

        return objects.SearchResult(source=source,
                                    search_type=search_type,
                                    search_result=search_result,
                                    tracks=tracks)
示例#15
0
    def test_ne(self, lib_mock):
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist1 = spotify.Playlist(self.session, sp_playlist=sp_playlist)
        playlist2 = spotify.Playlist(self.session, sp_playlist=sp_playlist)

        self.assertFalse(playlist1 != playlist2)
示例#16
0
    def test_tracks_is_a_mutable_sequence(self, lib_mock):
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist = spotify.Playlist(self.session, sp_playlist=sp_playlist)

        self.assertIsInstance(playlist.tracks, compat.MutableSequence)
示例#17
0
    def test_hash(self, lib_mock):
        sp_playlist = spotify.ffi.cast('sp_playlist *', 42)
        playlist1 = spotify.Playlist(self.session, sp_playlist=sp_playlist)
        playlist2 = spotify.Playlist(self.session, sp_playlist=sp_playlist)

        self.assertEqual(hash(playlist1), hash(playlist2))
示例#18
0
 def playlist_tracks(self, playlisturi):
     playlist = spotify.Playlist(self.session, uri=playlisturi)
     if not playlist.is_loaded:
         playlist.load()
     return [str(track.link) for track in playlist.tracks]
示例#19
0
 def playlist(self):
     """The :class:`~spotify.Playlist` object for this
     :class:`SearchPlaylist`."""
     return spotify.Playlist(self.uri)