Exemplo n.º 1
0
    def _follow_unfollow_help(self, other, request_type):
        """ follow and unfollow are identical, except for the request type.

        This function implements that functionality to remove duplicate code.
        """
        # Validate input
        if not isinstance(other, list):
            other = [other]

        for elem in other:
            if type(elem) not in [Artist, User, Playlist]:
                raise TypeError(elem)

        # Split up input
        artists = utils.separate(other, Artist)
        users = utils.separate(other, User)
        playlists = utils.separate(other, Playlist)

        for batch in utils.create_batches(utils.map_ids(artists)):
            response_json, status_code = utils.request(
                self._session,
                request_type=request_type,
                endpoint=Endpoints.USER_FOLLOW_ARTIST_USER,
                body=None,
                uri_params={
                    'type': 'artist',
                    'ids': batch
                })

            if status_code != 204:
                raise utils.SpotifyError(status_code, response_json)

        for batch in utils.create_batches(utils.map_ids(users)):
            response_json, status_code = utils.request(
                self._session,
                request_type=request_type,
                endpoint=Endpoints.USER_FOLLOW_ARTIST_USER,
                body=None,
                uri_params={
                    'type': 'user',
                    'ids': batch
                })

            if status_code != 204:
                raise utils.SpotifyError(status_code, response_json)

        for playlist in playlists:
            response_json, status_code = utils.request(
                self._session,
                request_type=request_type,
                endpoint=Endpoints.USER_FOLLOW_PLAYLIST % playlist,
                body=None,
                uri_params=None)

            if status_code != 200:
                raise utils.SpotifyError(status_code, response_json)
Exemplo n.º 2
0
    def test_remove(self):
        user = self.user

        albums = get_dummy_data(const.ALBUMS, 10, to_obj=True)
        album_ids = utils.map_ids(albums)
        tracks = get_dummy_data(const.TRACKS, 10, to_obj=True)
        playlists = get_dummy_data(const.PLAYLISTS, 10, to_obj=True)

        # Validate input checking
        self.assertRaises(TypeError, user.remove, playlists)

        # Make sure saving albums does what's expected
        #pylint: disable=unused-argument
        def request_mock_return(session,
                                request_type,
                                endpoint,
                                body,
                                uri_params):
            self.assertEqual(request_type, const.REQUEST_DELETE)
            self.assertIsNotNone(uri_params)
            self.assertTrue('ids' in uri_params)
            for elem in uri_params['ids']:
                self.assertIsInstance(elem, str)
                self.assertTrue(elem in album_ids)
            return None, 200

        self.request_mock.side_effect = request_mock_return
        user.remove(albums)

        # Should not raise exception - expects code 200 for playlists
        self.request_mock.side_effect = [(None, 200)]*10
        user.remove(tracks)
Exemplo n.º 3
0
    def _save_remove_help(self, other, request_type):
        """ save and remove are identical, except for the request type and
        return codes.

        This function implements that functionality to remove duplicate code.
        """
        # Validate input
        if not isinstance(other, list):
            other = [other]

        for elem in other:
            if type(elem) not in [Album, Track]:
                raise TypeError(elem)

        # Split up input
        albums = utils.separate(other, Album)
        tracks = utils.separate(other, Track)

        for batch in utils.create_batches(utils.map_ids(albums)):
            response_json, status_code = utils.request(
                self._session,
                request_type=request_type,
                endpoint=Endpoints.USER_SAVE_ALBUMS,
                body=None,
                uri_params={'ids': batch})

            # All success codes are 200, except saving an album
            success = 201 if request_type == const.REQUEST_PUT else 200
            if status_code != success:
                raise utils.SpotifyError(status_code, response_json)

        for batch in utils.create_batches(utils.map_ids(tracks)):
            response_json, status_code = utils.request(
                self._session,
                request_type=request_type,
                endpoint=Endpoints.USER_SAVE_TRACKS,
                body=None,
                uri_params={'ids': batch})

            if status_code != 200:
                raise utils.SpotifyError(status_code, response_json)
Exemplo n.º 4
0
    def has_saved(self, other):
        """ Check if the user has one or more things saved to their library.

        Args:
            other: check if the current user has 'other' saved to the library.
                Other must be one of the following:

                    - Track
                    - Album
                    - List: can contain multiple of the above types

        Returns:
            List of tuples. Each tuple has an input object and whether the user
            has that object saved.

        Required token scopes:
            - user-library-read

        Calls endpoints:
            - GET     /v1/me/albums/contains
            - GET     /v1/me/tracks/contains
        """
        # Validate input
        if not isinstance(other, list):
            other = [other]

        for elem in other:
            if type(elem) not in [Track, Album]:
                raise TypeError(elem)

        # Split up input
        tracks = utils.separate(other, Track)
        albums = utils.separate(other, Album)

        # Get boolean values for whether the user has each item saved
        endpoint = Endpoints.USER_HAS_SAVED

        track_bools = []
        for batch in utils.create_batches(utils.map_ids(tracks)):
            response_json, status_code = utils.request(
                self._session,
                request_type=const.REQUEST_GET,
                endpoint=endpoint % 'tracks',
                body=None,
                uri_params={'ids': batch})

            if status_code != 200:
                raise utils.SpotifyError(status_code, response_json)

            track_bools.append(response_json)

        album_bools = []
        for batch in utils.create_batches(utils.map_ids(albums)):
            response_json, status_code = utils.request(
                self._session,
                request_type=const.REQUEST_GET,
                endpoint=endpoint % 'albums',
                body=None,
                uri_params={'ids': batch})

            if status_code != 200:
                raise utils.SpotifyError(status_code, response_json)

            album_bools.append(response_json)

        # Zip output with input to make tuples
        zipped_tracks = list(zip(tracks, track_bools))
        zipped_albums = list(zip(albums, album_bools))
        return zipped_tracks + zipped_albums
Exemplo n.º 5
0
    def is_following(self, other):
        """ Check if the current user is following something.

        Args:
            other: check if current user is following 'other'. Other must be
                one of the following:

                    - Artist
                    - User
                    - Playlist
                    - List: can contain multiple of the above types

        Required token scopes:
            - user-follow-read
            - playlist-read-private
            - playlist-read-collaborative

        Calls endpoints:
            - GET     /v1/me/following/contains
            - GET     /v1/users/{user_id}/playlists

        Returns:
            List of tuples. Each tuple has an input object and whether the user
            follows the object.
        """
        # Validate input
        if not isinstance(other, list):
            other = [other]

        for elem in other:
            if type(elem) not in [Artist, User, Playlist]:
                raise TypeError(elem)

        # Split up input
        artists = utils.separate(other, Artist)
        users = utils.separate(other, User)
        playlists = utils.separate(other, Playlist)

        # Get boolean values for whether the user follows each in 'other'
        endpoint = Endpoints.USER_FOLLOWING_CONTAINS
        artist_bools = []
        for batch in utils.create_batches(utils.map_ids(artists)):
            response_json, status_code = utils.request(
                self._session,
                request_type=const.REQUEST_GET,
                endpoint=endpoint,
                body=None,
                uri_params={
                    'type': 'artist',
                    'ids': batch
                })

            if status_code != 200:
                raise utils.SpotifyError(status_code, response_json)

            artist_bools.append(response_json)

        user_bools = []
        for batch in utils.create_batches(utils.map_ids(users)):
            response_json, status_code = utils.request(
                self._session,
                request_type=const.REQUEST_GET,
                endpoint=endpoint,
                body=None,
                uri_params={
                    'type': 'user',
                    'ids': batch
                })

            if status_code != 200:
                raise utils.SpotifyError(status_code, response_json)

            user_bools.append(response_json)

        # For each playlist in other, check if in the User's followed playlists
        followed_playlists = self.get_following(const.PLAYLISTS)
        playlist_bools = list(map(lambda p: p in followed_playlists,
                                  playlists))

        # Zip output with input to make tuples
        artists = list(zip(artists, artist_bools))
        users = list(zip(users, user_bools))
        playlists = list(zip(playlists, playlist_bools))
        return artists + users + playlists