spotifywebapiPython 1.0.156__py3-none-any.whl → 1.0.157__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of spotifywebapiPython might be problematic. Click here for more details.

Files changed (23) hide show
  1. {spotifywebapiPython-1.0.156.dist-info → spotifywebapiPython-1.0.157.dist-info}/METADATA +1 -1
  2. {spotifywebapiPython-1.0.156.dist-info → spotifywebapiPython-1.0.157.dist-info}/RECORD +23 -23
  3. spotifywebapipython/const.py +1 -1
  4. spotifywebapipython/docs/__init__.html +8 -2
  5. spotifywebapipython/docs/index.html +2 -2
  6. spotifywebapipython/docs/search.js +1 -1
  7. spotifywebapipython/docs/spotifywebapipython/const.html +3 -3
  8. spotifywebapipython/docs/spotifywebapipython/saappmessages.html +2 -2
  9. spotifywebapipython/docs/spotifywebapipython/sautils.html +2 -2
  10. spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html +2 -2
  11. spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html +2 -2
  12. spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html +2 -2
  13. spotifywebapipython/docs/spotifywebapipython/spotifyclient.html +2 -2
  14. spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html +2 -2
  15. spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html +2 -2
  16. spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html +2 -2
  17. spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html +2 -2
  18. spotifywebapipython/spotifyconnect/spotifyconnectdirectorytask.py +13 -8
  19. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastapptask.py +84 -75
  20. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastcontroller.py +14 -12
  21. {spotifywebapiPython-1.0.156.dist-info → spotifywebapiPython-1.0.157.dist-info}/LICENSE +0 -0
  22. {spotifywebapiPython-1.0.156.dist-info → spotifywebapiPython-1.0.157.dist-info}/WHEEL +0 -0
  23. {spotifywebapiPython-1.0.156.dist-info → spotifywebapiPython-1.0.157.dist-info}/top_level.txt +0 -0
@@ -4,11 +4,9 @@ import threading
4
4
  import time
5
5
 
6
6
  # our package imports.
7
- from .spotifyconnectzeroconfcastcontroller import SpotifyConnectZeroconfCastController
8
- from .spotifyconnectzeroconfexceptions import SpotifyConnectZeroconfPlaybackTransferError
9
- #from spotifywebapipython import SpotifyClient
10
- from spotifywebapipython.zeroconfapi import ZeroconfGetInfo, ZeroconfResponse
7
+ from .spotifyconnectzeroconfcastcontroller import SpotifyConnectZeroconfCastController, TYPE_LAUNCH_ERROR
11
8
  from spotifywebapipython.spotifywebplayertoken import SpotifyWebPlayerToken
9
+ from spotifywebapipython.zeroconfapi import ZeroconfGetInfo, ZeroconfResponse
12
10
 
13
11
  # get smartinspect logger reference; create a new session for this module name.
14
12
  from smartinspectpython.siauto import SIAuto, SILevel, SISession
@@ -118,42 +116,27 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
118
116
  return self._TransferPlayback
119
117
 
120
118
 
121
- @property
122
- def ZeroconfInfo(self) -> ZeroconfGetInfo:
123
- """
124
- Returns the Chromecast Spotify Connect getinfo response, if the Spotify
125
- application is running on the Chromecast devive; otherwise, None.
126
- """
127
- if (self._SpotifyConnectZeroconfCastController is None):
128
- return None
129
- return self._SpotifyConnectZeroconfCastController.zeroconfGetInfo
130
-
131
-
132
- @property
133
- def ZeroconfResponseObject(self) -> ZeroconfResponse:
134
- """
135
- Returns the Chromecast Spotify Connect zeroconf response, if the Spotify
136
- application returned one; otherwise, None.
119
+ def _CallGetInfoResponseReceivedCallback(
120
+ self,
121
+ zcResponse:ZeroconfGetInfo=None,
122
+ ) -> None:
137
123
  """
138
- if (self._SpotifyConnectZeroconfCastController is None):
139
- return None
140
- return self._SpotifyConnectZeroconfCastController.zeroconfResponse
124
+ Executes the callback to process the zeroconf getInfo response from the cast app task.
141
125
 
142
-
143
- def _CallGetInfoResponseReceivedCallback(self) -> None:
144
- """
145
- If defined, call the callback to process the zeroconf getInfo response from the cast app task.
126
+ Args:
127
+ zcResponse (ZeroconfGetInfo):
128
+ Zeroconf getInfo response object.
146
129
  """
147
- # was a GetInfoResponse callback defined?
130
+ # was the callback defined?
148
131
  if (self._GetInfoResponseReceivedCallback):
149
132
 
150
133
  try:
151
134
 
152
135
  # trace.
153
- _logsi.LogVerbose("%s - Zeroconf getInfoResponse received; Spotify Connect info: \"%s\" (%s)" % (self.name, self.ZeroconfInfo.RemoteName, self.ZeroconfInfo.DeviceId))
136
+ _logsi.LogVerbose("%s - Zeroconf getInfoResponse received; Spotify Connect info: \"%s\" (%s)" % (self.name, zcResponse.RemoteName, zcResponse.DeviceId))
154
137
 
155
138
  # invoke callback to process the GetInfoResponse data.
156
- self._GetInfoResponseReceivedCallback(self._CastDevice.uuid, self.ZeroconfInfo)
139
+ self._GetInfoResponseReceivedCallback(self._CastDevice.uuid, zcResponse)
157
140
 
158
141
  except Exception as ex:
159
142
 
@@ -162,21 +145,27 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
162
145
  #ignore exceptions, as there is nothing we can do about them!
163
146
 
164
147
 
165
-
166
- def _CallZeroconfResponseReceivedCallback(self) -> None:
148
+ def _CallZeroconfResponseReceivedCallback(
149
+ self,
150
+ zcResponse:ZeroconfResponse=None,
151
+ ) -> None:
167
152
  """
168
- If defined, call the callback to process the various zeroconf responses from the cast app task.
153
+ Executes the callback to process the various zeroconf responses from the cast app task.
154
+
155
+ Args:
156
+ zcResponse (ZeroconfResponse):
157
+ Zeroconf response object.
169
158
  """
170
- # was a ZeroconfResponse callback defined?
159
+ # was the callback defined?
171
160
  if (self._ZeroconfResponseReceivedCallback):
172
161
 
173
162
  try:
174
163
 
175
164
  # trace.
176
- _logsi.LogVerbose("%s - Zeroconf \"%s\" received; Spotify Connect response: \"%s\" (%s)" % (self.name, self.ZeroconfResponseObject.ResponseSource, self.ZeroconfResponseObject.StatusString, self.ZeroconfResponseObject.Status))
165
+ _logsi.LogVerbose("%s - Zeroconf \"%s\" received; Spotify Connect response: \"%s\" (%s)" % (self.name, zcResponse.ResponseSource, zcResponse.StatusString, zcResponse.Status))
177
166
 
178
167
  # invoke callback to process the ZeroconfResponse data.
179
- self._ZeroconfResponseReceivedCallback(self._CastDevice.uuid, self.ZeroconfResponseObject)
168
+ self._ZeroconfResponseReceivedCallback(self._CastDevice.uuid, zcResponse)
180
169
 
181
170
  except Exception as ex:
182
171
 
@@ -188,6 +177,9 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
188
177
  def run(self):
189
178
  """
190
179
  The task to perform on a seperate thread.
180
+
181
+ Note that any exceptions must be processed via a call to _PostLaunchErrorEvent, if you
182
+ want the exception to be see by the user; just raising an exception will only log it!
191
183
  """
192
184
  try:
193
185
 
@@ -220,32 +212,24 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
220
212
  # at this point the cast app should be either fully launched, or an error
221
213
  # occured while trying to launch.
222
214
 
223
- # was a ZeroconfResponse callback defined?
224
- if (self._ZeroconfResponseReceivedCallback):
225
-
226
- try:
215
+ # did an error occur?
216
+ if (not self._SpotifyConnectZeroconfCastController.isLaunched):
227
217
 
228
- # at this point, the Spotify Connect `addUser` has been made and the results populated.
229
- _logsi.LogVerbose("%s - Zeroconf ZeroconfResponse received; Spotify Connect response: \"%s\" (%s)" % (self.name, self.ZeroconfResponseObject.StatusString, self.ZeroconfResponseObject.ResponseSource))
218
+ # was it a launchError or getInfoError?
219
+ if (not self._SpotifyConnectZeroconfCastController.isAddUserError):
220
+ self._CallZeroconfResponseReceivedCallback(self._SpotifyConnectZeroconfCastController.zeroconfResponse)
221
+ _logsi.LogException("%s - Failed to launch spotify controller due to timeout" % (self.name), None, logToSystemLogger=False)
222
+ return
230
223
 
231
- # invoke callback to process the ZeroconfResponse data.
232
- self._ZeroconfResponseReceivedCallback(self._CastDevice.uuid, self.ZeroconfResponseObject)
224
+ # if getInfoResponse was received, then execute callback to process the getInfoResponse.
225
+ if (not self._SpotifyConnectZeroconfCastController.isGetInfoError) and (self._SpotifyConnectZeroconfCastController.zeroconfGetInfo is not None):
226
+ self._CallGetInfoResponseReceivedCallback(self._SpotifyConnectZeroconfCastController.zeroconfGetInfo)
233
227
 
234
- except Exception as ex:
235
-
236
- # trace.
237
- _logsi.LogException("An unhandled exception occured in ZeroconfResponseReceivedCallback: %s" % (str(ex)), ex, logToSystemLogger=False)
238
- #ignore exceptions, as there is nothing we can do about them!
239
-
240
- # check for launch or getInfoError errors.
241
- if (not self._SpotifyConnectZeroconfCastController.isLaunched) and (not self._SpotifyConnectZeroconfCastController.isAddUserError):
242
- self._CallZeroconfResponseReceivedCallback()
243
- raise ValueError("%s - Failed to launch spotify controller due to timeout" % (self.name))
244
-
245
- # check for addUserError errors.
246
- if (not self._SpotifyConnectZeroconfCastController.isLaunched) and (self._SpotifyConnectZeroconfCastController.isAddUserError):
247
- self._CallZeroconfResponseReceivedCallback()
248
- raise ValueError("%s - Failed to launch spotify controller due to credentials error" % (self.name))
228
+ # was it a addUserError? if so, then sp_dc / sp_key credentials are probably bad.
229
+ if (self._SpotifyConnectZeroconfCastController.isAddUserError):
230
+ self._CallZeroconfResponseReceivedCallback(self._SpotifyConnectZeroconfCastController.zeroconfResponse)
231
+ _logsi.LogException("%s - Failed to launch spotify controller due to credentials error" % (self.name), None, logToSystemLogger=False)
232
+ return
249
233
 
250
234
  # at this point the cast app launch was successful; the following steps were performed:
251
235
  # - issues a Spotify Connect Zeroconf `getInfo` request to retrieve info about the device.
@@ -258,10 +242,10 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
258
242
  # as well as AFTER the call to `addUser` (no need to call `getInfo` again AFTER addUser).
259
243
 
260
244
  # call the callback to process the getInfoResponse.
261
- self._CallGetInfoResponseReceivedCallback()
245
+ self._CallGetInfoResponseReceivedCallback(self._SpotifyConnectZeroconfCastController.zeroconfGetInfo)
262
246
 
263
247
  # call the callback to process the addUserResponse.
264
- self._CallZeroconfResponseReceivedCallback()
248
+ self._CallZeroconfResponseReceivedCallback(self._SpotifyConnectZeroconfCastController.zeroconfResponse)
265
249
 
266
250
  # trace.
267
251
  _logsi.LogVerbose("%s - User is logged in to Spotify Cast App; waiting for transfer playback ..." % (self.name))
@@ -271,7 +255,8 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
271
255
 
272
256
  # transfer playback to the Chromecast device.
273
257
  _logsi.LogVerbose("%s - Transferring playback for loginId \"%s\"" % (self.name, self.SpotifyClientInstance.SpotifyConnectLoginId))
274
- self.SpotifyClientInstance.PlayerTransferPlayback(self.ZeroconfInfo.DeviceId, play=True, refreshDeviceList=False)
258
+ deviceId:str = self._SpotifyConnectZeroconfCastController.zeroconfGetInfo.DeviceId
259
+ self.SpotifyClientInstance.PlayerTransferPlayback(deviceId, play=True, refreshDeviceList=False)
275
260
 
276
261
  # the cast device will receive a Chromecast message of payload type `transferSuccess`
277
262
  # on successful transfer of playback; this will set the `isPlaybackTransferred` flag to True.
@@ -284,17 +269,19 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
284
269
  while counter < (timeout + 1):
285
270
  if (self._SpotifyConnectZeroconfCastController.waitPlaybackTransfer.wait(1)):
286
271
  if (self._SpotifyConnectZeroconfCastController.isPlaybackTransferError):
287
- raise SpotifyConnectZeroconfPlaybackTransferError("%s - playback transfer error: %s" % (self.name, str(self.ZeroconfResponseObject)))
272
+ self._PostLaunchErrorEvent(1001, "Playback transfer error: %s" % (self._SpotifyConnectZeroconfCastController.zeroconfResponse.StatusString))
273
+ return
288
274
  break
289
275
  if (counter >= timeout):
290
- raise SpotifyConnectZeroconfPlaybackTransferError("%s - Timed out waiting for playback transfer to device" % (self.name))
276
+ self._PostLaunchErrorEvent(1002, "Playback transfer error - Timed out waiting for playback transfer to device")
277
+ return
291
278
  counter += 1
292
279
 
293
280
  # update task status.
294
281
  _logsi.LogVerbose("%s - Transfer Playback complete for loginId \"%s\"" % (self.name, self.SpotifyClientInstance.SpotifyConnectLoginId))
295
282
 
296
283
  # call the callback to process the transferSuccess or transferError.
297
- self._CallZeroconfResponseReceivedCallback()
284
+ self._CallZeroconfResponseReceivedCallback(self._SpotifyConnectZeroconfCastController.zeroconfResponse)
298
285
 
299
286
  # event loop; we have to keep this thread active in order to keep the
300
287
  # Spotify App on the Chromecast device active and available.
@@ -309,20 +296,16 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
309
296
  # trace.
310
297
  _logsi.LogVerbose("%s - Thread task was stopped" % (self.name))
311
298
 
312
- except SpotifyConnectZeroconfPlaybackTransferError as ex:
313
-
314
- # trace.
315
- _logsi.LogError(str(ex))
316
- _logsi.LogVerbose("%s - Thread task is ending due to error" % (self.name))
317
-
318
299
  except Exception as ex:
319
300
 
301
+ # post launchError event with exception details.
302
+ # this will also log a trace message.
303
+ self._PostLaunchErrorEvent(1000, str(ex))
304
+
320
305
  # trace.
321
- _logsi.LogException("%s - Exception: %s" % (self.name, str(ex)), ex, logToSystemLogger=False)
322
306
  _logsi.LogVerbose("%s - Thread task is ending due to exception" % (self.name))
323
-
324
- # raise unhandled exception.
325
- raise
307
+
308
+ #ignore exceptions, as there is nothing we can do about them!
326
309
 
327
310
  finally:
328
311
 
@@ -334,3 +317,29 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
334
317
  self._SpotifyConnectZeroconfCastController.tear_down()
335
318
  except:
336
319
  pass
320
+
321
+
322
+ def _PostLaunchErrorEvent(
323
+ self,
324
+ returnCode:int,
325
+ message:str
326
+ ) -> None:
327
+ """
328
+ Formats a `launchError` Zeroconf Response, and executes the callback.
329
+ """
330
+ try:
331
+
332
+ # trace.
333
+ _logsi.LogError("%s - LaunchError event; (%s) %s" % (self.name, returnCode, message), logToSystemLogger=False)
334
+
335
+ # post launchError event with error details.
336
+ response:ZeroconfResponse = ZeroconfResponse()
337
+ response.ResponseSource = TYPE_LAUNCH_ERROR
338
+ response.Status = returnCode
339
+ response.StatusString = message
340
+ self._CallZeroconfResponseReceivedCallback(response)
341
+
342
+ except:
343
+
344
+ # ignore exceptions, as there is nothing we can do about them.
345
+ pass
@@ -38,8 +38,10 @@ TYPE_GET_INFO_RESPONSE = "getInfoResponse"
38
38
  TYPE_ADD_USER = "addUser"
39
39
  TYPE_ADD_USER_RESPONSE = "addUserResponse"
40
40
  TYPE_ADD_USER_ERROR = "addUserError"
41
- TYPE_TRANSFER_SUCCESS_RESPONSE = "transferSuccess"
42
- TYPE_TRANSFER_ERROR_RESPONSE = "transferError"
41
+ TYPE_TRANSFER_SUCCESS = "transferSuccess"
42
+ TYPE_TRANSFER_ERROR = "transferError"
43
+ # not an actual Google Cast zeroconf response; used by this api to denote a launch / config error.
44
+ TYPE_LAUNCH_ERROR = "launchError"
43
45
 
44
46
  SPOTIFY_WEB_API_DEVICEAUTH_REFRESH = "https://spclient.wg.spotify.com/device-auth/v1/refresh"
45
47
 
@@ -144,26 +146,26 @@ class SpotifyConnectZeroconfCastController(BaseController):
144
146
  # launch the spotify app on the device.
145
147
  # this will perform the following steps, initiated via the callback function:
146
148
  # - issues a Spotify Connect Zeroconf `getInfo` request to retrieve info about the device.
147
- # - waits for a `getInfoResponse` message and processes the results.
149
+ # - waits for a `getInfoResponse` (or `getInfoError`) message and processes the results.
148
150
  # - issues a Spotify Connect Zeroconf `addUser` request to login the user to Spotify Connect.
149
151
  # - waits for a `addUserResponse` (or `addUserError`) message and processes the results.
150
152
  self.launch(callback_function=callback)
151
153
 
152
- # wait for the launched spotify app to fully initialize.
153
- # this occurs when we receive an `addUserResponse` or `addUserError` message.
154
+ # wait for the launched spotify app to fully initialize. this occurs when we receive one
155
+ # of the following messages: `addUserResponse`, `addUserError`, `getInfoError`, `launchError`.
154
156
  counter = 0
155
157
  while counter < (timeout + 1):
156
158
  if (self.waitAddUser.wait(1)):
157
- if (self.isAddUserError):
158
- raise SpotifyZeroconfApiError(self.zeroconfResponse.Status, "AddUser request failed", "launch_app", self.zeroconfResponse.StatusString)
159
159
  break
160
- if (self.isGetInfoError):
161
- raise SpotifyZeroconfApiError(self.zeroconfResponse.Status, "GetInformation request failed", "launch_app", self.zeroconfResponse.StatusString)
162
160
  if (counter >= timeout):
163
161
  raise SpotifyZeroconfApiError(0, "Timed out while waiting for a response", "launch_app", "timeout")
164
162
  counter += 1
165
163
 
166
- # one more check to ensure that we launched.
164
+ # check for error conditions.
165
+ if (self.isAddUserError):
166
+ raise SpotifyZeroconfApiError(self.zeroconfResponse.Status, "AddUser request failed", "launch_app", self.zeroconfResponse.StatusString)
167
+ if (self.isGetInfoError):
168
+ raise SpotifyZeroconfApiError(self.zeroconfResponse.Status, "GetInformation request failed", "launch_app", self.zeroconfResponse.StatusString)
167
169
  if (not self.isLaunched):
168
170
  raise SpotifyConnectZeroconfLaunchError("Spotify Cast App could not be launched")
169
171
 
@@ -336,7 +338,7 @@ class SpotifyConnectZeroconfCastController(BaseController):
336
338
  return True
337
339
 
338
340
  # was playback transferred to the device?
339
- if payloadDataType == TYPE_TRANSFER_SUCCESS_RESPONSE:
341
+ if payloadDataType == TYPE_TRANSFER_SUCCESS:
340
342
 
341
343
  # example payload response (Nest Speaker):
342
344
  # { 'type': 'transferSuccess',
@@ -354,7 +356,7 @@ class SpotifyConnectZeroconfCastController(BaseController):
354
356
  return True
355
357
 
356
358
  # did an error occur transferring playback to the device?
357
- if payloadDataType == TYPE_TRANSFER_ERROR_RESPONSE:
359
+ if payloadDataType == TYPE_TRANSFER_ERROR:
358
360
 
359
361
  # example payload response (Nest Speaker):
360
362
  # { 'type': 'transferError',