Exemplo n.º 1
0
    def __init__(self, session, sp_playlistcontainer, sp_playlist):
        self._session = session

        lib.sp_playlistcontainer_add_ref(sp_playlistcontainer)
        self._sp_playlistcontainer = ffi.gc(sp_playlistcontainer, lib.sp_playlistcontainer_release)

        lib.sp_playlist_add_ref(sp_playlist)
        self._sp_playlist = ffi.gc(sp_playlist, lib.sp_playlist_release)

        self._num_tracks = 0
        self._sp_tracks_len = 0
        self._get_more_tracks()
Exemplo n.º 2
0
    def __init__(self, config=None):
        super(Session, self).__init__()

        if spotify._session_instance is not None:
            raise RuntimeError('Session has already been initialized')

        if config is not None:
            self.config = config
        else:
            self.config = spotify.Config()

        if self.config.application_key is None:
            self.config.load_application_key_file()

        sp_session_ptr = ffi.new('sp_session **')

        spotify.Error.maybe_raise(lib.sp_session_create(
            self.config._sp_session_config, sp_session_ptr))

        self._sp_session = ffi.gc(sp_session_ptr[0], lib.sp_session_release)

        self._cache = weakref.WeakValueDictionary()
        self._emitters = []
        self._callback_handles = set()

        self.connection = spotify.connection.Connection(self)
        self.offline = spotify.offline.Offline(self)
        self.player = spotify.player.Player(self)
        self.social = spotify.social.Social(self)
        spotify._session_instance = self
Exemplo n.º 3
0
    def __init__(
            self, session, uri=None, sp_image=None, add_ref=True,
            callback=None):

        assert uri or sp_image, 'uri or sp_image is required'

        self._session = session

        if uri is not None:
            image = spotify.Link(self._session, uri=uri).as_image()
            if image is None:
                raise ValueError(
                    'Failed to get image from Spotify URI: %r' % uri)
            sp_image = image._sp_image
            add_ref = True

        if add_ref:
            lib.sp_image_add_ref(sp_image)
        self._sp_image = ffi.gc(sp_image, lib.sp_image_release)

        self.loaded_event = threading.Event()

        handle = ffi.new_handle((self._session, self, callback))
        self._session._callback_handles.add(handle)
        spotify.Error.maybe_raise(lib.sp_image_add_load_callback(
            self._sp_image, _image_load_callback, handle))
Exemplo n.º 4
0
    def __init__(
            self, session, type=None, region=None, canonical_username=None,
            callback=None, sp_toplistbrowse=None, add_ref=True):

        assert (type is not None and region is not None) or sp_toplistbrowse, \
            'type and region, or sp_toplistbrowse, is required'

        self._session = session
        self.type = type
        self.region = region
        self.canonical_username = canonical_username
        self.loaded_event = threading.Event()

        if sp_toplistbrowse is None:
            if isinstance(region, ToplistRegion):
                region = int(region)
            else:
                region = utils.to_country_code(region)

            handle = ffi.new_handle((self._session, self, callback))
            self._session._callback_handles.add(handle)

            sp_toplistbrowse = lib.sp_toplistbrowse_create(
                self._session._sp_session, int(type), region,
                utils.to_char_or_null(canonical_username),
                _toplistbrowse_complete_callback, handle)
            add_ref = False

        if add_ref:
            lib.sp_toplistbrowse_add_ref(sp_toplistbrowse)
        self._sp_toplistbrowse = ffi.gc(
            sp_toplistbrowse, lib.sp_toplistbrowse_release)
Exemplo n.º 5
0
    def __init__(
            self, sp_obj, add_ref_func, release_func, len_func, getitem_func):

        add_ref_func(sp_obj)
        self._sp_obj = ffi.gc(sp_obj, release_func)
        self._len_func = len_func
        self._getitem_func = getitem_func
Exemplo n.º 6
0
    def __init__(
            self, session, artist=None, type=None, callback=None,
            sp_artistbrowse=None, add_ref=True):

        assert artist or sp_artistbrowse, (
            'artist or sp_artistbrowse is required')

        self._session = session
        self.loaded_event = threading.Event()

        if sp_artistbrowse is None:
            if type is None:
                type = ArtistBrowserType.FULL

            handle = ffi.new_handle((self._session, self, callback))
            self._session._callback_handles.add(handle)

            sp_artistbrowse = lib.sp_artistbrowse_create(
                self._session._sp_session, artist._sp_artist,
                int(type), _artistbrowse_complete_callback, handle)
            add_ref = False

        if add_ref:
            lib.sp_artistbrowse_add_ref(sp_artistbrowse)
        self._sp_artistbrowse = ffi.gc(
            sp_artistbrowse, lib.sp_artistbrowse_release)
Exemplo n.º 7
0
    def __init__(
            self, session, canonical_username=None, tracks=None, message='',
            callback=None, sp_inbox=None, add_ref=True):

        assert canonical_username and tracks or sp_inbox, \
            'canonical_username and tracks, or sp_inbox, is required'

        self._session = session
        self.loaded_event = threading.Event()

        if sp_inbox is None:
            canonical_username = utils.to_char(canonical_username)

            if isinstance(tracks, spotify.Track):
                tracks = [tracks]

            message = utils.to_char(message)

            handle = ffi.new_handle((self._session, self, callback))
            self._session._callback_handles.add(handle)

            sp_inbox = lib.sp_inbox_post_tracks(
                self._session._sp_session, canonical_username,
                [t._sp_track for t in tracks], len(tracks),
                message, _inboxpost_complete_callback, handle)
            add_ref = True

            if sp_inbox == ffi.NULL:
                raise spotify.Error('Inbox post request failed to initialize')

        if add_ref:
            lib.sp_inbox_add_ref(sp_inbox)
        self._sp_inbox = ffi.gc(sp_inbox, lib.sp_inbox_release)
Exemplo n.º 8
0
    def __init__(self, session, sp_playlist, index):
        self._session = session

        lib.sp_playlist_add_ref(sp_playlist)
        self._sp_playlist = ffi.gc(sp_playlist, lib.sp_playlist_release)

        self._index = index
Exemplo n.º 9
0
    def __init__(self, session, uri=None, sp_playlist=None, add_ref=True):
        super(Playlist, self).__init__()

        assert uri or sp_playlist, 'uri or sp_playlist is required'

        self._session = session

        if uri is not None:
            playlist = spotify.Link(self._session, uri).as_playlist()
            if playlist is None:
                raise spotify.Error(
                    'Failed to get playlist from Spotify URI: %r' % uri)
            sp_playlist = playlist._sp_playlist
            session._cache[sp_playlist] = self
            add_ref = True

        if add_ref:
            lib.sp_playlist_add_ref(sp_playlist)
        self._sp_playlist = ffi.gc(sp_playlist, lib.sp_playlist_release)

        self._sp_playlist_callbacks = _PlaylistCallbacks.get_struct()
        lib.sp_playlist_add_callbacks(
            self._sp_playlist, self._sp_playlist_callbacks, ffi.NULL)

        # Make sure we remove callbacks in __del__() using the same lib as we
        # added callbacks with.
        self._lib = lib
Exemplo n.º 10
0
    def __init__(self, session, sp_playlistcontainer, add_ref=True):
        super(PlaylistContainer, self).__init__()

        self._session = session

        if add_ref:
            lib.sp_playlistcontainer_add_ref(sp_playlistcontainer)
        self._sp_playlistcontainer = ffi.gc(
            sp_playlistcontainer, lib.sp_playlistcontainer_release)

        self._sp_playlistcontainer_callbacks = None

        # Make sure we remove callbacks in __del__() using the same lib as we
        # added callbacks with.
        self._lib = lib
Exemplo n.º 11
0
    def __init__(self, session, uri=None, sp_artist=None, add_ref=True):
        assert uri or sp_artist, 'uri or sp_artist is required'

        self._session = session

        if uri is not None:
            artist = spotify.Link(self._session, uri=uri).as_artist()
            if artist is None:
                raise ValueError(
                    'Failed to get artist from Spotify URI: %r' % uri)
            sp_artist = artist._sp_artist

        if add_ref:
            lib.sp_artist_add_ref(sp_artist)
        self._sp_artist = ffi.gc(sp_artist, lib.sp_artist_release)
Exemplo n.º 12
0
    def __init__(self, session, uri=None, sp_album=None, add_ref=True):
        assert uri or sp_album, 'uri or sp_album is required'

        self._session = session

        if uri is not None:
            album = spotify.Link(self._session, uri=uri).as_album()
            if album is None:
                raise ValueError(
                    'Failed to get album from Spotify URI: %r' % uri)
            sp_album = album._sp_album
            add_ref = True

        if add_ref:
            lib.sp_album_add_ref(sp_album)
        self._sp_album = ffi.gc(sp_album, lib.sp_album_release)
Exemplo n.º 13
0
    def __init__(self, session, uri=None, sp_user=None, add_ref=True):
        assert uri or sp_user, 'uri or sp_user is required'

        self._session = session

        if uri is not None:
            user = spotify.Link(self._session, uri=uri).as_user()
            if user is None:
                raise ValueError(
                    'Failed to get user from Spotify URI: %r' % uri)
            sp_user = user._sp_user
            add_ref = True

        if add_ref:
            lib.sp_user_add_ref(sp_user)
        self._sp_user = ffi.gc(sp_user, lib.sp_user_release)
Exemplo n.º 14
0
    def __init__(self, session, uri=None, sp_link=None, add_ref=True):
        assert uri or sp_link, 'uri or sp_link is required'

        self._session = session

        if uri is not None:
            sp_link = lib.sp_link_create_from_string(
                utils.to_char(Link._normalize_uri(uri)))
            add_ref = False
            if sp_link == ffi.NULL:
                raise ValueError(
                    'Failed to get link from Spotify URI: %r' % uri)

        if add_ref:
            lib.sp_link_add_ref(sp_link)
        self._sp_link = ffi.gc(sp_link, lib.sp_link_release)
Exemplo n.º 15
0
    def __init__(self, session, uri=None, sp_track=None, add_ref=True):
        assert uri or sp_track, 'uri or sp_track is required'

        self._session = session

        if uri is not None:
            track = spotify.Link(self._session, uri=uri).as_track()
            if track is None:
                raise ValueError(
                    'Failed to get track from Spotify URI: %r' % uri)
            sp_track = track._sp_track
            add_ref = True

        if add_ref:
            lib.sp_track_add_ref(sp_track)
        self._sp_track = ffi.gc(sp_track, lib.sp_track_release)
Exemplo n.º 16
0
    def __init__(
        self,
        session,
        canonical_username=None,
        tracks=None,
        message='',
        callback=None,
        sp_inbox=None,
        add_ref=True,
    ):

        assert (
            canonical_username and tracks or sp_inbox
        ), 'canonical_username and tracks, or sp_inbox, is required'

        self._session = session
        self.loaded_event = threading.Event()

        if sp_inbox is None:
            canonical_username = utils.to_char(canonical_username)

            if isinstance(tracks, spotify.Track):
                tracks = [tracks]

            message = utils.to_char(message)

            handle = ffi.new_handle((self._session, self, callback))
            self._session._callback_handles.add(handle)

            sp_inbox = lib.sp_inbox_post_tracks(
                self._session._sp_session,
                canonical_username,
                [t._sp_track for t in tracks],
                len(tracks),
                message,
                _inboxpost_complete_callback,
                handle,
            )
            add_ref = True

            if sp_inbox == ffi.NULL:
                raise spotify.Error('Inbox post request failed to initialize')

        if add_ref:
            lib.sp_inbox_add_ref(sp_inbox)
        self._sp_inbox = ffi.gc(sp_inbox, lib.sp_inbox_release)
Exemplo n.º 17
0
    def subscribers(self):
        """The canonical usernames of up to 500 of the subscribers of the
        playlist.

        May be empty until you call :meth:`update_subscribers` and the
        :attr:`~PlaylistEvent.SUBSCRIBERS_CHANGED` event is emitted from the
        playlist.
        """
        sp_subscribers = ffi.gc(lib.sp_playlist_subscribers(self._sp_playlist),
                                lib.sp_playlist_subscribers_free)
        # The ``subscribers`` field is ``char *[1]`` according to the struct,
        # so we must cast it to ``char **`` to be able to access more than the
        # first subscriber.
        subscribers = ffi.cast('char **', sp_subscribers.subscribers)
        usernames = []
        for i in range(sp_subscribers.count):
            usernames.append(utils.to_unicode(subscribers[i]))
        return usernames
Exemplo n.º 18
0
    def __init__(self, session, uri=None, sp_link=None, add_ref=True):
        assert uri or sp_link, 'uri or sp_link is required'

        self._session = session

        if uri is not None:
            sp_link = lib.sp_link_create_from_string(
                utils.to_char(Link._normalize_uri(uri))
            )
            add_ref = False
            if sp_link == ffi.NULL:
                raise ValueError(
                    'Failed to get link from Spotify URI: %r' % uri
                )

        if add_ref:
            lib.sp_link_add_ref(sp_link)
        self._sp_link = ffi.gc(sp_link, lib.sp_link_release)
Exemplo n.º 19
0
    def __init__(
            self, session, query='', callback=None,
            track_offset=0, track_count=20,
            album_offset=0, album_count=20,
            artist_offset=0, artist_count=20,
            playlist_offset=0, playlist_count=20,
            search_type=None,
            sp_search=None, add_ref=True):

        assert query or sp_search, 'query or sp_search is required'

        self._session = session
        self.callback = callback
        self.track_offset = track_offset
        self.track_count = track_count
        self.album_offset = album_offset
        self.album_count = album_count
        self.artist_offset = artist_offset
        self.artist_count = artist_count
        self.playlist_offset = playlist_offset
        self.playlist_count = playlist_count
        if search_type is None:
            search_type = SearchType.STANDARD
        self.search_type = search_type

        self.loaded_event = threading.Event()

        if sp_search is None:
            handle = ffi.new_handle((self._session, self, callback))
            self._session._callback_handles.add(handle)

            sp_search = lib.sp_search_create(
                self._session._sp_session, utils.to_char(query),
                track_offset, track_count,
                album_offset, album_count,
                artist_offset, artist_count,
                playlist_offset, playlist_count,
                int(search_type), _search_complete_callback, handle)
            add_ref = False

        if add_ref:
            lib.sp_search_add_ref(sp_search)
        self._sp_search = ffi.gc(sp_search, lib.sp_search_release)
Exemplo n.º 20
0
    def __init__(self, session, sp_playlistcontainer, add_ref=True):
        super(PlaylistContainer, self).__init__()

        self._session = session

        if add_ref:
            lib.sp_playlistcontainer_add_ref(sp_playlistcontainer)
        self._sp_playlistcontainer = ffi.gc(sp_playlistcontainer,
                                            lib.sp_playlistcontainer_release)

        self._sp_playlistcontainer_callbacks = (
            _PlaylistContainerCallbacks.get_struct())
        lib.sp_playlistcontainer_add_callbacks(
            self._sp_playlistcontainer, self._sp_playlistcontainer_callbacks,
            ffi.NULL)

        # Make sure we remove callbacks in __del__() using the same lib as we
        # added callbacks with.
        self._lib = lib
Exemplo n.º 21
0
    def __init__(
        self,
        session,
        type=None,
        region=None,
        canonical_username=None,
        callback=None,
        sp_toplistbrowse=None,
        add_ref=True,
    ):

        assert (type is not None and region is not None) or sp_toplistbrowse, (
            'type and region, or sp_toplistbrowse, is required')

        self._session = session
        self.type = type
        self.region = region
        self.canonical_username = canonical_username
        self.loaded_event = threading.Event()

        if sp_toplistbrowse is None:
            if isinstance(region, ToplistRegion):
                region = int(region)
            else:
                region = utils.to_country_code(region)

            handle = ffi.new_handle((self._session, self, callback))
            self._session._callback_handles.add(handle)

            sp_toplistbrowse = lib.sp_toplistbrowse_create(
                self._session._sp_session,
                int(type),
                region,
                utils.to_char_or_null(canonical_username),
                _toplistbrowse_complete_callback,
                handle,
            )
            add_ref = False

        if add_ref:
            lib.sp_toplistbrowse_add_ref(sp_toplistbrowse)
        self._sp_toplistbrowse = ffi.gc(sp_toplistbrowse,
                                        lib.sp_toplistbrowse_release)
Exemplo n.º 22
0
    def subscribers(self):
        """The canonical usernames of up to 500 of the subscribers of the
        playlist.

        May be empty until you call :meth:`update_subscribers` and the
        :attr:`~PlaylistEvent.SUBSCRIBERS_CHANGED` event is emitted from the
        playlist.
        """
        sp_subscribers = ffi.gc(
            lib.sp_playlist_subscribers(self._sp_playlist),
            lib.sp_playlist_subscribers_free)
        # The ``subscribers`` field is ``char *[1]`` according to the struct,
        # so we must cast it to ``char **`` to be able to access more than the
        # first subscriber.
        subscribers = ffi.cast('char **', sp_subscribers.subscribers)
        usernames = []
        for i in range(sp_subscribers.count):
            usernames.append(utils.to_unicode(subscribers[i]))
        return usernames
Exemplo n.º 23
0
    def __init__(self,
                 type=None,
                 region=None,
                 canonical_username=None,
                 callback=None,
                 sp_toplistbrowse=None,
                 add_ref=True):

        assert (type is not None and region is not None) or sp_toplistbrowse, \
            'type and region, or sp_toplistbrowse, is required'

        # TODO Document these attributes?
        self.type = type
        self.region = region
        self.canonical_username = canonical_username

        self.complete_event = threading.Event()
        self._callback_handles = set()

        if sp_toplistbrowse is None:
            if isinstance(region, ToplistRegion):
                region = int(region)
            else:
                region = utils.to_country_code(region)

            handle = ffi.new_handle((callback, self))
            # TODO Think through the life cycle of the handle object. Can it
            # happen that we GC the search and handle object, and then later
            # the callback is called?
            self._callback_handles.add(handle)

            sp_toplistbrowse = lib.sp_toplistbrowse_create(
                spotify.session_instance._sp_session, int(type), region,
                utils.to_char_or_null(canonical_username),
                _toplistbrowse_complete_callback, handle)
            add_ref = False

        if add_ref:
            lib.sp_toplistbrowse_add_ref(sp_toplistbrowse)
        self._sp_toplistbrowse = ffi.gc(sp_toplistbrowse,
                                        lib.sp_toplistbrowse_release)
Exemplo n.º 24
0
    def __init__(self,
                 canonical_username=None,
                 tracks=None,
                 message='',
                 callback=None,
                 sp_inbox=None,
                 add_ref=True):

        assert canonical_username and tracks or sp_inbox, \
            'canonical_username and tracks, or sp_inbox, is required'

        self.complete_event = threading.Event()
        self._callback_handles = set()

        if sp_inbox is None:
            canonical_username = utils.to_char(canonical_username)

            if isinstance(tracks, spotify.Track):
                tracks = [tracks]

            message = utils.to_char(message)

            handle = ffi.new_handle((callback, self))
            # TODO Think through the life cycle of the handle object. Can it
            # happen that we GC the search and handle object, and then later
            # the callback is called?
            self._callback_handles.add(handle)

            sp_inbox = lib.sp_inbox_post_tracks(
                spotify.session_instance._sp_session, canonical_username,
                [t._sp_track for t in tracks], len(tracks), message,
                _inboxpost_complete_callback, handle)
            add_ref = True

            if sp_inbox == ffi.NULL:
                raise spotify.Error('Inbox post request failed to initialize')

        if add_ref:
            lib.sp_inbox_add_ref(sp_inbox)
        self._sp_inbox = ffi.gc(sp_inbox, lib.sp_inbox_release)
Exemplo n.º 25
0
    def __init__(
            self, session, album=None, callback=None,
            sp_albumbrowse=None, add_ref=True):

        assert album or sp_albumbrowse, 'album or sp_albumbrowse is required'

        self._session = session
        self.loaded_event = threading.Event()

        if sp_albumbrowse is None:
            handle = ffi.new_handle((self._session, self, callback))
            self._session._callback_handles.add(handle)

            sp_albumbrowse = lib.sp_albumbrowse_create(
                self._session._sp_session, album._sp_album,
                _albumbrowse_complete_callback, handle)
            add_ref = False

        if add_ref:
            lib.sp_albumbrowse_add_ref(sp_albumbrowse)
        self._sp_albumbrowse = ffi.gc(
            sp_albumbrowse, lib.sp_albumbrowse_release)
Exemplo n.º 26
0
    def __init__(self, session, uri=None, sp_playlist=None, add_ref=True):
        super(Playlist, self).__init__()

        assert uri or sp_playlist, 'uri or sp_playlist is required'

        self._session = session

        if uri is not None:
            sp_playlist = spotify.Link(self._session, uri)._as_sp_playlist()
            if sp_playlist is None:
                raise spotify.Error(
                    'Failed to get playlist from Spotify URI: %r' % uri)
            session._cache[sp_playlist] = self
            add_ref = False

        if add_ref:
            lib.sp_playlist_add_ref(sp_playlist)
        self._sp_playlist = ffi.gc(sp_playlist, lib.sp_playlist_release)

        self._sp_playlist_callbacks = None

        # Make sure we remove callbacks in __del__() using the same lib as we
        # added callbacks with.
        self._lib = lib