def __init__(self, artist=None, title=None, album=None, length=None): artist = utils.to_char_or_null(artist) title = utils.to_char_or_null(title) album = utils.to_char_or_null(album) if length is None: length = -1 sp_track = lib.sp_localtrack_create(artist, title, album, length) super(LocalTrack, self).__init__(sp_track=sp_track, add_ref=False)
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)
def application_key(self, value): if value is None: size = 0 else: size = len(value) assert size in (0, 321), ( 'Invalid application key; expected 321 bytes, got %d bytes' % size) self._application_key = utils.to_char_or_null(value) self._sp_session_config.application_key = ffi.cast( 'void *', self._application_key) self._sp_session_config.application_key_size = size
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)
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)
def proxy(self, value): # NOTE libspotify reuses cached values from previous sessions if this # is set to NULL, thus we convert None to empty string. self._proxy = utils.to_char_or_null('' if value is None else value) self._sp_session_config.proxy = self._proxy
def test_anything_else_fails(self): with self.assertRaises(ValueError): utils.to_char_or_null(123)
def proxy(self, value): self._proxy = utils.to_char_or_null(value) self._sp_session_config.proxy = self._proxy
def settings_location(self, value): self._settings_location = utils.to_char_or_null(value) self._sp_session_config.settings_location = self._settings_location
def tracefile(self, value): self._tracefile = utils.to_char_or_null(value) self._sp_session_config.tracefile = self._tracefile
def proxy_password(self, value): self._proxy_password = utils.to_char_or_null(value) self._sp_session_config.proxy_password = self._proxy_password
def user_agent(self, value): self._user_agent = utils.to_char_or_null(value) self._sp_session_config.user_agent = self._user_agent
def cache_location(self, value): self._cache_location = utils.to_char_or_null(value) self._sp_session_config.cache_location = self._cache_location
def ca_certs_filename(self, value): ptr = self._get_ca_certs_filename_ptr() if ptr is not None: self._ca_certs_filename = utils.to_char_or_null(value) ptr[0] = self._ca_certs_filename
def proxy_username(self, value): self._proxy_username = utils.to_char_or_null(value) self._sp_session_config.proxy_username = self._proxy_username
def device_id(self, value): self._device_id = utils.to_char_or_null(value) self._sp_session_config.device_id = self._device_id
def tracefile(self, value): # NOTE libspotify does not consider empty string as unset, and will try # to open the file "" and fail with a "LibError: Unable to open trace # file", thus we convert empty string to NULL. self._tracefile = utils.to_char_or_null(value or None) self._sp_session_config.tracefile = self._tracefile
def device_id(self, value): # NOTE libspotify segfaults if device_id is set to an empty string, # thus we convert empty strings to NULL. self._device_id = utils.to_char_or_null(value or None) self._sp_session_config.device_id = self._device_id
def test_none_becomes_null(self): self.assertEqual(utils.to_char_or_null(None), spotify.ffi.NULL)
def test_bytes_becomes_char(self): result = utils.to_char_or_null(b'abc') self.assertIsInstance(result, spotify.ffi.CData) self.assertEqual(spotify.ffi.string(result), b'abc')
def test_unicode_becomes_char(self): result = utils.to_char_or_null('æøå') self.assertIsInstance(result, spotify.ffi.CData) self.assertEqual(spotify.ffi.string(result).decode('utf-8'), 'æøå')