spotifywebapiPython 1.0.42__py3-none-any.whl → 1.0.44__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.
- {spotifywebapiPython-1.0.42.dist-info → spotifywebapiPython-1.0.44.dist-info}/METADATA +1 -1
- {spotifywebapiPython-1.0.42.dist-info → spotifywebapiPython-1.0.44.dist-info}/RECORD +33 -26
- spotifywebapipython/const.py +1 -1
- spotifywebapipython/docs/__init__.html +24 -2
- spotifywebapipython/docs/index.html +2 -2
- spotifywebapipython/docs/search.js +1 -1
- spotifywebapipython/docs/spotifywebapiPython/const.html +3 -3
- spotifywebapipython/docs/spotifywebapiPython/saappmessages.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/sautils.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifyapierror.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifyapimessage.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifyauthtoken.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifyclient.html +376 -36
- spotifywebapipython/docs/spotifywebapiPython/spotifydiscovery.html +45 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifywebapiauthenticationerror.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifywebapierror.html +2 -2
- spotifywebapipython/models/__init__.py +14 -0
- spotifywebapipython/models/playlist.py +4 -1
- spotifywebapipython/models/playlistsimplified.py +4 -1
- spotifywebapipython/models/playlisttracksummary.py +3 -1
- spotifywebapipython/models/searchresponse.py +1 -1
- spotifywebapipython/models/zeroconfblobbuilder.py +144 -0
- spotifywebapipython/models/zeroconfdiscoveryresult.py +451 -0
- spotifywebapipython/models/zeroconfgetinfo.py +359 -0
- spotifywebapipython/models/zeroconfgetinfoalias.py +96 -0
- spotifywebapipython/models/zeroconfgetinfodrmmediaformat.py +90 -0
- spotifywebapipython/models/zeroconfproperty.py +93 -0
- spotifywebapipython/models/zeroconfresponse.py +108 -0
- spotifywebapipython/spotifyclient.py +484 -32
- spotifywebapipython/spotifydiscovery.py +98 -11
- {spotifywebapiPython-1.0.42.dist-info → spotifywebapiPython-1.0.44.dist-info}/LICENSE +0 -0
- {spotifywebapiPython-1.0.42.dist-info → spotifywebapiPython-1.0.44.dist-info}/WHEEL +0 -0
- {spotifywebapiPython-1.0.42.dist-info → spotifywebapiPython-1.0.44.dist-info}/top_level.txt +0 -0
|
@@ -14,6 +14,7 @@ from lxml.etree import fromstring, Element
|
|
|
14
14
|
from .oauthcli import AuthClient
|
|
15
15
|
from .models import *
|
|
16
16
|
from .models import UserProfile as UserProfileCurrentUser
|
|
17
|
+
from .models.zeroconfblobbuilder import int_to_b64str
|
|
17
18
|
from .sautils import export, GetUnixTimestampMSFromUtcNow, _xmlGetInnerText
|
|
18
19
|
from .saappmessages import SAAppMessages
|
|
19
20
|
from .spotifyapierror import SpotifyApiError
|
|
@@ -40,6 +41,8 @@ from .const import (
|
|
|
40
41
|
CACHE_SOURCE_CACHED:str = "cached"
|
|
41
42
|
CACHE_SOURCE_CURRENT:str = "current"
|
|
42
43
|
|
|
44
|
+
SPOTIFY_DJ_PLAYLIST_ID = "37i9dqzf1eykqdzj48dyyq"
|
|
45
|
+
|
|
43
46
|
# get smartinspect logger reference; create a new session for this module name.
|
|
44
47
|
from smartinspectpython.siauto import SIAuto, SILevel, SISession, SIMethodParmListContext, SISourceId
|
|
45
48
|
import logging
|
|
@@ -454,6 +457,19 @@ class SpotifyClient:
|
|
|
454
457
|
|
|
455
458
|
elif responseData is not None:
|
|
456
459
|
|
|
460
|
+
# if response is a string (e.g. html response) and is not in the 2xx range then
|
|
461
|
+
# we will assume it's an error, even though no json 'error' response body was returned!
|
|
462
|
+
# this is usually due to a '503 Server Error' response.
|
|
463
|
+
if (response.status > 299) and (isinstance(responseData, str)):
|
|
464
|
+
|
|
465
|
+
errCode = response.status
|
|
466
|
+
errMessage = response.reason
|
|
467
|
+
|
|
468
|
+
if responseUTF8 is not None:
|
|
469
|
+
errMessage = responseUTF8
|
|
470
|
+
|
|
471
|
+
raise SpotifyWebApiError(errCode, errMessage, msg.MethodName, response.reason, _logsi)
|
|
472
|
+
|
|
457
473
|
# does json response contain error details?
|
|
458
474
|
if CONST_ERROR in responseData:
|
|
459
475
|
|
|
@@ -669,7 +685,8 @@ class SpotifyClient:
|
|
|
669
685
|
uri:str = msg.Uri
|
|
670
686
|
if (uri == self.SpotifyApiTokenUrl) \
|
|
671
687
|
or (uri == self.SpotifyApiAuthorizeUrl) \
|
|
672
|
-
or (uri.startswith('https:'))
|
|
688
|
+
or (uri.startswith('https:')) \
|
|
689
|
+
or (uri.startswith('http:')):
|
|
673
690
|
url = uri
|
|
674
691
|
else:
|
|
675
692
|
url = f'{self.SpotifyWebApiUrlBase}{uri}'
|
|
@@ -705,9 +722,13 @@ class SpotifyClient:
|
|
|
705
722
|
# call the appropriate poolmanager request method.
|
|
706
723
|
if msg.HasUrlParameters:
|
|
707
724
|
|
|
708
|
-
# add querystring parameters to url
|
|
725
|
+
# add querystring parameters to url; if url already has a partial parm
|
|
726
|
+
# string (e.g. has a '?xxx=...') then use the append separator (e.g. '...&xxx=...').
|
|
709
727
|
urlQS:str = urlencode(msg.UrlParameters)
|
|
710
|
-
|
|
728
|
+
urlParmSep:str = '?'
|
|
729
|
+
if (url.find('?') > 0):
|
|
730
|
+
urlParmSep = '&'
|
|
731
|
+
url = url + urlParmSep + urlQS
|
|
711
732
|
|
|
712
733
|
_logsi.LogDictionary(SILevel.Verbose, "SpotifyClient http request: '%s' (with urlparms)" % (url), msg.UrlParameters, prettyPrint=True)
|
|
713
734
|
response = self._Manager.request_encode_url(method, url, headers=msg.RequestHeaders)
|
|
@@ -793,9 +814,10 @@ class SpotifyClient:
|
|
|
793
814
|
The uri of the item to add to the queue; must be a track or an episode uri.
|
|
794
815
|
Example: `spotify:track:4iV5W9uYEdYUVa79Axb7Rh`
|
|
795
816
|
deviceId (str):
|
|
796
|
-
The id of the device this command is targeting.
|
|
817
|
+
The id or name of the device this command is targeting.
|
|
797
818
|
If not supplied, the user's currently active device is the target.
|
|
798
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
819
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
820
|
+
Example: `Web Player (Chrome)`
|
|
799
821
|
|
|
800
822
|
Raises:
|
|
801
823
|
SpotifyWebApiError:
|
|
@@ -826,6 +848,10 @@ class SpotifyClient:
|
|
|
826
848
|
apiMethodParms.AppendKeyValue("deviceId", deviceId)
|
|
827
849
|
_logsi.LogMethodParmList(SILevel.Verbose, "Add item to playback queue", apiMethodParms)
|
|
828
850
|
|
|
851
|
+
# check for device name; convert to an id if a name was supplied.
|
|
852
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
853
|
+
|
|
854
|
+
# build spotify web api request parameters.
|
|
829
855
|
urlParms:dict = \
|
|
830
856
|
{
|
|
831
857
|
'uri': uri
|
|
@@ -5826,7 +5852,7 @@ class SpotifyClient:
|
|
|
5826
5852
|
result = item
|
|
5827
5853
|
break
|
|
5828
5854
|
|
|
5829
|
-
# if no match by id, then try to
|
|
5855
|
+
# if no match by id, then try to match by device name.
|
|
5830
5856
|
if result is None:
|
|
5831
5857
|
for item in devices:
|
|
5832
5858
|
if deviceId == item.Name.lower():
|
|
@@ -5850,6 +5876,115 @@ class SpotifyClient:
|
|
|
5850
5876
|
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
5851
5877
|
|
|
5852
5878
|
|
|
5879
|
+
def PlayerConvertDeviceNameToId(self,
|
|
5880
|
+
value:str,
|
|
5881
|
+
refresh:bool=False
|
|
5882
|
+
) -> str:
|
|
5883
|
+
"""
|
|
5884
|
+
Converts a Spotify Connect player device name to it's equivalent id value if
|
|
5885
|
+
the value is a device name. If the value is a device id, then the value is
|
|
5886
|
+
returned as-is.
|
|
5887
|
+
|
|
5888
|
+
This method requires the `user-read-playback-state` scope.
|
|
5889
|
+
|
|
5890
|
+
Args:
|
|
5891
|
+
value (str):
|
|
5892
|
+
The device id or name value to check.
|
|
5893
|
+
refresh (bool):
|
|
5894
|
+
True to resolve the device real-time from the spotify web api device list;
|
|
5895
|
+
otherwise, False (default) to use the cached device list to resolve the device.
|
|
5896
|
+
|
|
5897
|
+
Returns:
|
|
5898
|
+
One of the following:
|
|
5899
|
+
- if value is a device id, then the value is returned as-is; no device list
|
|
5900
|
+
lookup is performed, and the value is assumed to be a valid device id.
|
|
5901
|
+
- if value is not a device id, then it is assumed to be a name; a device list
|
|
5902
|
+
lookup is performed to retrieve it's device id. if found, then the id is
|
|
5903
|
+
returned; otherwise, the value is returned as-is with the understanding that
|
|
5904
|
+
subsequent operations will fail since it's not in the device list.
|
|
5905
|
+
|
|
5906
|
+
Raises:
|
|
5907
|
+
SpotifyWebApiError:
|
|
5908
|
+
If the Spotify Web API request was for a non-authorization service
|
|
5909
|
+
and the response contains error information.
|
|
5910
|
+
SpotifApiError:
|
|
5911
|
+
If the method fails for any other reason.
|
|
5912
|
+
|
|
5913
|
+
The id for the first match found on the device name will be returned if multiple devices
|
|
5914
|
+
are found in the Spotify Connect player device list that have the same name (with different
|
|
5915
|
+
id's). Care should be taken to make device names unique if using device names for
|
|
5916
|
+
methods that require a device id or name.
|
|
5917
|
+
|
|
5918
|
+
If the `refresh` argument is specified, then the `ConfigurationCache` is updated with
|
|
5919
|
+
the latest Spotify Connect player device list. Use the `refresh` argument (with False
|
|
5920
|
+
value) to retrieve the cached value and avoid the spotify web api request. This results
|
|
5921
|
+
in better performance.
|
|
5922
|
+
|
|
5923
|
+
<details>
|
|
5924
|
+
<summary>Sample Code</summary>
|
|
5925
|
+
```python
|
|
5926
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/PlayerConvertDeviceNameToId.py
|
|
5927
|
+
```
|
|
5928
|
+
</details>
|
|
5929
|
+
"""
|
|
5930
|
+
apiMethodName:str = 'PlayerConvertDeviceNameToId'
|
|
5931
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
5932
|
+
|
|
5933
|
+
try:
|
|
5934
|
+
|
|
5935
|
+
# trace.
|
|
5936
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
5937
|
+
apiMethodParms.AppendKeyValue("value", value)
|
|
5938
|
+
apiMethodParms.AppendKeyValue("refresh", refresh)
|
|
5939
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Checking Spotify Connect Player device for name", apiMethodParms)
|
|
5940
|
+
|
|
5941
|
+
# if nothing specified then just use it as-is.
|
|
5942
|
+
if (value is None) or (len(value.strip()) == 0):
|
|
5943
|
+
_logsi.LogVerbose("Device ID not specified; active device will be used")
|
|
5944
|
+
return value
|
|
5945
|
+
|
|
5946
|
+
try:
|
|
5947
|
+
|
|
5948
|
+
# is this a hex string value?
|
|
5949
|
+
intValue:int = int(str(value), 16)
|
|
5950
|
+
|
|
5951
|
+
# if it IS a hex string, then it should have been converted to a number.
|
|
5952
|
+
# at this point we can assume it's a device id. in this case, just return it.
|
|
5953
|
+
# note that we will NOT perform a lookup in the device list
|
|
5954
|
+
_logsi.LogVerbose("Device id '%s' was specified, and will be used as-is" % value)
|
|
5955
|
+
if intValue is not None:
|
|
5956
|
+
return value
|
|
5957
|
+
return value
|
|
5958
|
+
|
|
5959
|
+
except Exception:
|
|
5960
|
+
|
|
5961
|
+
# the above will fail if it's a device name.
|
|
5962
|
+
pass
|
|
5963
|
+
|
|
5964
|
+
# try resolving the device name to a device id value.
|
|
5965
|
+
device:Device = self.GetPlayerDevice(value, refresh)
|
|
5966
|
+
if device is not None:
|
|
5967
|
+
_logsi.LogVerbose("Converted device name '%s' to device id '%s'" % (value, device.Id))
|
|
5968
|
+
return device.Id
|
|
5969
|
+
|
|
5970
|
+
# if a name could not be found in the Spotify Connect Player devices then just
|
|
5971
|
+
# return the value as-is.
|
|
5972
|
+
_logsi.LogVerbose("Device name '%s' could not be found in the Spotify Connect Device list; subsequent actions will probably fail using this device name" % value)
|
|
5973
|
+
return value
|
|
5974
|
+
|
|
5975
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
5976
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
5977
|
+
except Exception as ex:
|
|
5978
|
+
|
|
5979
|
+
# format unhandled exception.
|
|
5980
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
5981
|
+
|
|
5982
|
+
finally:
|
|
5983
|
+
|
|
5984
|
+
# trace.
|
|
5985
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
5986
|
+
|
|
5987
|
+
|
|
5853
5988
|
def GetPlayerDevices(self,
|
|
5854
5989
|
refresh:bool=True
|
|
5855
5990
|
) -> list[Device]:
|
|
@@ -6437,6 +6572,27 @@ class SpotifyClient:
|
|
|
6437
6572
|
|
|
6438
6573
|
# ensure market was either supplied or implied; default if neither.
|
|
6439
6574
|
market = self._ValidateMarket(market)
|
|
6575
|
+
|
|
6576
|
+
# was the Spotify DJ playlist specified?
|
|
6577
|
+
# the DJ is not fully integrated with the playlist API, so the GET request will fail.
|
|
6578
|
+
# we will manually build a basic playlist object to return for the playlist.
|
|
6579
|
+
if (playlistId is not None) and (playlistId.lower() == SPOTIFY_DJ_PLAYLIST_ID):
|
|
6580
|
+
|
|
6581
|
+
# build basic playlist response.
|
|
6582
|
+
result = Playlist()
|
|
6583
|
+
result._Collaborative = False
|
|
6584
|
+
result._Description = 'Spotify DJ Playlist'
|
|
6585
|
+
result._ExternalUrls._Spotify = 'https://open.spotify.com/playlist/%s' % playlistId
|
|
6586
|
+
result._Id = playlistId
|
|
6587
|
+
result._Name = 'DJ'
|
|
6588
|
+
result._Public = False
|
|
6589
|
+
result._Type = 'playlist'
|
|
6590
|
+
result._Uri = 'spotify:playlist:%s' % playlistId
|
|
6591
|
+
|
|
6592
|
+
# trace.
|
|
6593
|
+
_logsi.LogVerbose("Spotify DJ Playlist detected; request will be bypassed, and a basic PlayList object returned")
|
|
6594
|
+
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
6595
|
+
return result
|
|
6440
6596
|
|
|
6441
6597
|
# build spotify web api request parameters.
|
|
6442
6598
|
urlParms:dict = {}
|
|
@@ -8868,9 +9024,10 @@ class SpotifyClient:
|
|
|
8868
9024
|
|
|
8869
9025
|
Args:
|
|
8870
9026
|
deviceId (str):
|
|
8871
|
-
The id of the device this command is targeting.
|
|
9027
|
+
The id or name of the device this command is targeting.
|
|
8872
9028
|
If not supplied, the user's currently active device is the target.
|
|
8873
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9029
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9030
|
+
Example: `Web Player (Chrome)`
|
|
8874
9031
|
delay (float):
|
|
8875
9032
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
8876
9033
|
This delay will give the spotify web api time to process the change before
|
|
@@ -8909,6 +9066,9 @@ class SpotifyClient:
|
|
|
8909
9066
|
# validations.
|
|
8910
9067
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
8911
9068
|
|
|
9069
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9070
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9071
|
+
|
|
8912
9072
|
# build spotify web api request parameters.
|
|
8913
9073
|
urlParms:dict = {}
|
|
8914
9074
|
if deviceId is not None:
|
|
@@ -8979,9 +9139,10 @@ class SpotifyClient:
|
|
|
8979
9139
|
Default is `0`.
|
|
8980
9140
|
Example: `25000`
|
|
8981
9141
|
deviceId (str):
|
|
8982
|
-
The id of the device this command is targeting.
|
|
9142
|
+
The id or name of the device this command is targeting.
|
|
8983
9143
|
If not supplied, the user's currently active device is the target.
|
|
8984
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9144
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9145
|
+
Example: `Web Player (Chrome)`
|
|
8985
9146
|
delay (float):
|
|
8986
9147
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
8987
9148
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9038,6 +9199,9 @@ class SpotifyClient:
|
|
|
9038
9199
|
# validations.
|
|
9039
9200
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
9040
9201
|
|
|
9202
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9203
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9204
|
+
|
|
9041
9205
|
# build spotify web api request parameters.
|
|
9042
9206
|
reqData:dict = \
|
|
9043
9207
|
{
|
|
@@ -9093,9 +9257,10 @@ class SpotifyClient:
|
|
|
9093
9257
|
|
|
9094
9258
|
Args:
|
|
9095
9259
|
deviceId (str):
|
|
9096
|
-
The id of the device this command is targeting.
|
|
9260
|
+
The id or name of the device this command is targeting.
|
|
9097
9261
|
If not supplied, the user's currently active device is the target.
|
|
9098
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9262
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9263
|
+
Example: `Web Player (Chrome)`
|
|
9099
9264
|
shuffle (bool):
|
|
9100
9265
|
True to set player shuffle mode to on; otherwise, False for no shuffle.
|
|
9101
9266
|
delay (float):
|
|
@@ -9150,6 +9315,9 @@ class SpotifyClient:
|
|
|
9150
9315
|
for trackSaved in tracks.Items:
|
|
9151
9316
|
arrUris.append(trackSaved.Track.Uri)
|
|
9152
9317
|
|
|
9318
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9319
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9320
|
+
|
|
9153
9321
|
# set desired shuffle mode.
|
|
9154
9322
|
self.PlayerSetShuffleMode(shuffle, deviceId, delay)
|
|
9155
9323
|
|
|
@@ -9198,9 +9366,10 @@ class SpotifyClient:
|
|
|
9198
9366
|
Default is `0`.
|
|
9199
9367
|
Example: `25000`
|
|
9200
9368
|
deviceId (str):
|
|
9201
|
-
The id of the device this command is targeting.
|
|
9369
|
+
The id or name of the device this command is targeting.
|
|
9202
9370
|
If not supplied, the user's currently active device is the target.
|
|
9203
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9371
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9372
|
+
Example: `Web Player (Chrome)`
|
|
9204
9373
|
delay (float):
|
|
9205
9374
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
9206
9375
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9251,6 +9420,9 @@ class SpotifyClient:
|
|
|
9251
9420
|
for idx in range(0, len(arrUris)):
|
|
9252
9421
|
arrUris[idx] = arrUris[idx].strip()
|
|
9253
9422
|
|
|
9423
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9424
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9425
|
+
|
|
9254
9426
|
# build spotify web api request parameters.
|
|
9255
9427
|
reqData:dict = \
|
|
9256
9428
|
{
|
|
@@ -9303,9 +9475,10 @@ class SpotifyClient:
|
|
|
9303
9475
|
|
|
9304
9476
|
Args:
|
|
9305
9477
|
deviceId (str):
|
|
9306
|
-
The id of the device this command is targeting.
|
|
9478
|
+
The id or name of the device this command is targeting.
|
|
9307
9479
|
If not supplied, the user's currently active device is the target.
|
|
9308
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9480
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9481
|
+
Example: `Web Player (Chrome)`
|
|
9309
9482
|
delay (float):
|
|
9310
9483
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
9311
9484
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9344,6 +9517,9 @@ class SpotifyClient:
|
|
|
9344
9517
|
# validations.
|
|
9345
9518
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
9346
9519
|
|
|
9520
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9521
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9522
|
+
|
|
9347
9523
|
# build spotify web api request parameters.
|
|
9348
9524
|
urlParms:dict = {}
|
|
9349
9525
|
if deviceId is not None:
|
|
@@ -9395,9 +9571,10 @@ class SpotifyClient:
|
|
|
9395
9571
|
player to start playing the next song.
|
|
9396
9572
|
Example: `25000`
|
|
9397
9573
|
deviceId (str):
|
|
9398
|
-
The id of the device this command is targeting.
|
|
9574
|
+
The id or name of the device this command is targeting.
|
|
9399
9575
|
If not supplied, the user's currently active device is the target.
|
|
9400
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9576
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9577
|
+
Example: `Web Player (Chrome)`
|
|
9401
9578
|
delay (float):
|
|
9402
9579
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
9403
9580
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9437,6 +9614,9 @@ class SpotifyClient:
|
|
|
9437
9614
|
# validations.
|
|
9438
9615
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
9439
9616
|
|
|
9617
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9618
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9619
|
+
|
|
9440
9620
|
# build spotify web api request parameters.
|
|
9441
9621
|
urlParms:dict = \
|
|
9442
9622
|
{
|
|
@@ -9484,9 +9664,10 @@ class SpotifyClient:
|
|
|
9484
9664
|
|
|
9485
9665
|
Args:
|
|
9486
9666
|
deviceId (str):
|
|
9487
|
-
The id of the device this command is targeting.
|
|
9667
|
+
The id or name of the device this command is targeting.
|
|
9488
9668
|
If not supplied, the user's currently active device is the target.
|
|
9489
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9669
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9670
|
+
Example: `Web Player (Chrome)`
|
|
9490
9671
|
delay (float):
|
|
9491
9672
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
9492
9673
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9525,6 +9706,9 @@ class SpotifyClient:
|
|
|
9525
9706
|
# validations.
|
|
9526
9707
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
9527
9708
|
|
|
9709
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9710
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9711
|
+
|
|
9528
9712
|
# build spotify web api request parameters.
|
|
9529
9713
|
urlParms:dict = {}
|
|
9530
9714
|
if deviceId is not None:
|
|
@@ -9569,9 +9753,10 @@ class SpotifyClient:
|
|
|
9569
9753
|
|
|
9570
9754
|
Args:
|
|
9571
9755
|
deviceId (str):
|
|
9572
|
-
The id of the device this command is targeting.
|
|
9756
|
+
The id or name of the device this command is targeting.
|
|
9573
9757
|
If not supplied, the user's currently active device is the target.
|
|
9574
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9758
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9759
|
+
Example: `Web Player (Chrome)`
|
|
9575
9760
|
delay (float):
|
|
9576
9761
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
9577
9762
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9610,6 +9795,9 @@ class SpotifyClient:
|
|
|
9610
9795
|
# validations.
|
|
9611
9796
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
9612
9797
|
|
|
9798
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9799
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9800
|
+
|
|
9613
9801
|
# build spotify web api request parameters.
|
|
9614
9802
|
urlParms:dict = {}
|
|
9615
9803
|
if deviceId is not None:
|
|
@@ -9661,9 +9849,10 @@ class SpotifyClient:
|
|
|
9661
9849
|
- `off` - will turn repeat off.
|
|
9662
9850
|
Default: `off`
|
|
9663
9851
|
deviceId (str):
|
|
9664
|
-
The id of the device this command is targeting.
|
|
9852
|
+
The id or name of the device this command is targeting.
|
|
9665
9853
|
If not supplied, the user's currently active device is the target.
|
|
9666
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9854
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9855
|
+
Example: `Web Player (Chrome)`
|
|
9667
9856
|
delay (float):
|
|
9668
9857
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
9669
9858
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9703,6 +9892,9 @@ class SpotifyClient:
|
|
|
9703
9892
|
# validations.
|
|
9704
9893
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
9705
9894
|
|
|
9895
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9896
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9897
|
+
|
|
9706
9898
|
# build spotify web api request parameters.
|
|
9707
9899
|
urlParms:dict = \
|
|
9708
9900
|
{
|
|
@@ -9756,9 +9948,10 @@ class SpotifyClient:
|
|
|
9756
9948
|
- `False` - Do not shuffle user's playback.
|
|
9757
9949
|
Default: `False`
|
|
9758
9950
|
deviceId (str):
|
|
9759
|
-
The id of the device this command is targeting.
|
|
9951
|
+
The id or name of the device this command is targeting.
|
|
9760
9952
|
If not supplied, the user's currently active device is the target.
|
|
9761
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9953
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
9954
|
+
Example: `Web Player (Chrome)`
|
|
9762
9955
|
delay (float):
|
|
9763
9956
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
9764
9957
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9798,6 +9991,9 @@ class SpotifyClient:
|
|
|
9798
9991
|
# validations.
|
|
9799
9992
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
9800
9993
|
|
|
9994
|
+
# check for device name; convert to an id if a name was supplied.
|
|
9995
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9996
|
+
|
|
9801
9997
|
# build spotify web api request parameters.
|
|
9802
9998
|
urlParms:dict = \
|
|
9803
9999
|
{
|
|
@@ -9850,9 +10046,10 @@ class SpotifyClient:
|
|
|
9850
10046
|
Must be a value from 0 to 100 inclusive.
|
|
9851
10047
|
Example: `50`
|
|
9852
10048
|
deviceId (str):
|
|
9853
|
-
The id of the device this command is targeting.
|
|
10049
|
+
The id or name of the device this command is targeting.
|
|
9854
10050
|
If not supplied, the user's currently active device is the target.
|
|
9855
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
10051
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
10052
|
+
Example: `Web Player (Chrome)`
|
|
9856
10053
|
delay (float):
|
|
9857
10054
|
Time delay (in seconds) to wait AFTER issuing the command to the player.
|
|
9858
10055
|
This delay will give the spotify web api time to process the change before
|
|
@@ -9892,6 +10089,9 @@ class SpotifyClient:
|
|
|
9892
10089
|
# validations.
|
|
9893
10090
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
9894
10091
|
|
|
10092
|
+
# check for device name; convert to an id if a name was supplied.
|
|
10093
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
10094
|
+
|
|
9895
10095
|
# build spotify web api request parameters.
|
|
9896
10096
|
urlParms:dict = \
|
|
9897
10097
|
{
|
|
@@ -9940,8 +10140,9 @@ class SpotifyClient:
|
|
|
9940
10140
|
|
|
9941
10141
|
Args:
|
|
9942
10142
|
deviceId (str):
|
|
9943
|
-
The id of the device on which playback should be started/transferred.
|
|
9944
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
10143
|
+
The id or name of the device on which playback should be started/transferred.
|
|
10144
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
10145
|
+
Example: `Web Player (Chrome)`
|
|
9945
10146
|
play (bool):
|
|
9946
10147
|
The transfer method:
|
|
9947
10148
|
- `True` - ensure playback happens on new device.
|
|
@@ -9985,6 +10186,9 @@ class SpotifyClient:
|
|
|
9985
10186
|
|
|
9986
10187
|
# validations.
|
|
9987
10188
|
delay = self._ValidateDelay(delay, 0.50, 10)
|
|
10189
|
+
|
|
10190
|
+
# check for device name; convert to an id if a name was supplied.
|
|
10191
|
+
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
9988
10192
|
|
|
9989
10193
|
# build spotify web api request parameters.
|
|
9990
10194
|
reqData:dict = \
|
|
@@ -10038,8 +10242,8 @@ class SpotifyClient:
|
|
|
10038
10242
|
Args:
|
|
10039
10243
|
defaultDeviceId (str):
|
|
10040
10244
|
The id of the device on which playback should be started/transferred if there is
|
|
10041
|
-
currently no active device.
|
|
10042
|
-
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
10245
|
+
currently no active device.
|
|
10246
|
+
Example: `0d1841b0976bae2a3a310dd74c0f3df354899bc8`
|
|
10043
10247
|
play (bool):
|
|
10044
10248
|
The transfer method:
|
|
10045
10249
|
- `True` - ensure playback happens on new device.
|
|
@@ -13615,3 +13819,251 @@ class SpotifyClient:
|
|
|
13615
13819
|
|
|
13616
13820
|
# trace.
|
|
13617
13821
|
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
13822
|
+
|
|
13823
|
+
|
|
13824
|
+
|
|
13825
|
+
def ZeroconfGetInformation(self,
|
|
13826
|
+
actionUrl:str,
|
|
13827
|
+
) -> ZeroconfGetInfo:
|
|
13828
|
+
"""
|
|
13829
|
+
Retrieve Spotify Connect device information from the Spotify Zeroconf API `getInfo` endpoint.
|
|
13830
|
+
|
|
13831
|
+
Args:
|
|
13832
|
+
actionUrl (str):
|
|
13833
|
+
The Zeroconf action url to issue the request to.
|
|
13834
|
+
Example: `http://192.168.1.80:8200/zc?action=getInfo`
|
|
13835
|
+
|
|
13836
|
+
Returns:
|
|
13837
|
+
An `ZeroconfGetInfo` object that contains the response.
|
|
13838
|
+
|
|
13839
|
+
Raises:
|
|
13840
|
+
SpotifyWebApiError:
|
|
13841
|
+
If the Spotify Web API request was for a non-authorization service
|
|
13842
|
+
and the response contains error information.
|
|
13843
|
+
SpotifApiError:
|
|
13844
|
+
If the method fails for any other reason.
|
|
13845
|
+
|
|
13846
|
+
<details>
|
|
13847
|
+
<summary>Sample Code</summary>
|
|
13848
|
+
```python
|
|
13849
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/ZeroconfGetInformation.py
|
|
13850
|
+
```
|
|
13851
|
+
</details>
|
|
13852
|
+
"""
|
|
13853
|
+
apiMethodName:str = 'ZeroconfGetInformation'
|
|
13854
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
13855
|
+
result:ZeroconfGetInfo = None
|
|
13856
|
+
|
|
13857
|
+
try:
|
|
13858
|
+
|
|
13859
|
+
# trace.
|
|
13860
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
13861
|
+
apiMethodParms.AppendKeyValue("actionUrl", actionUrl)
|
|
13862
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify Zeroconf getInfo response", apiMethodParms)
|
|
13863
|
+
|
|
13864
|
+
# execute spotify zeroconf api request.
|
|
13865
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, actionUrl)
|
|
13866
|
+
self.MakeRequest('GET', msg)
|
|
13867
|
+
|
|
13868
|
+
# process results.
|
|
13869
|
+
result = ZeroconfGetInfo(root=msg.ResponseData)
|
|
13870
|
+
|
|
13871
|
+
# trace.
|
|
13872
|
+
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
13873
|
+
return result
|
|
13874
|
+
|
|
13875
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
13876
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
13877
|
+
except Exception as ex:
|
|
13878
|
+
|
|
13879
|
+
# format unhandled exception.
|
|
13880
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
13881
|
+
|
|
13882
|
+
finally:
|
|
13883
|
+
|
|
13884
|
+
# trace.
|
|
13885
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
13886
|
+
|
|
13887
|
+
|
|
13888
|
+
def ZeroconfResetUsers(self,
|
|
13889
|
+
actionUrl:str,
|
|
13890
|
+
) -> ZeroconfResponse:
|
|
13891
|
+
"""
|
|
13892
|
+
Reset users for a Spotify Connect device by calling the Spotify Zeroconf API `resetUsers` endpoint.
|
|
13893
|
+
|
|
13894
|
+
Args:
|
|
13895
|
+
actionUrl (str):
|
|
13896
|
+
The Zeroconf action url to issue the request to.
|
|
13897
|
+
Example: `http://192.168.1.80:8200/zc?action=resetUsers`
|
|
13898
|
+
|
|
13899
|
+
Returns:
|
|
13900
|
+
An `ZeroconfResponse` object that contains the response.
|
|
13901
|
+
|
|
13902
|
+
Raises:
|
|
13903
|
+
SpotifyWebApiError:
|
|
13904
|
+
If the Spotify Web API request was for a non-authorization service
|
|
13905
|
+
and the response contains error information.
|
|
13906
|
+
SpotifApiError:
|
|
13907
|
+
If the method fails for any other reason.
|
|
13908
|
+
|
|
13909
|
+
<details>
|
|
13910
|
+
<summary>Sample Code</summary>
|
|
13911
|
+
```python
|
|
13912
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/ZeroconfResetUsers.py
|
|
13913
|
+
```
|
|
13914
|
+
</details>
|
|
13915
|
+
"""
|
|
13916
|
+
apiMethodName:str = 'ZeroconfResetUsers'
|
|
13917
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
13918
|
+
result:ZeroconfResponse = None
|
|
13919
|
+
|
|
13920
|
+
try:
|
|
13921
|
+
|
|
13922
|
+
# trace.
|
|
13923
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
13924
|
+
apiMethodParms.AppendKeyValue("actionUrl", actionUrl)
|
|
13925
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify Zeroconf GetInfo response", apiMethodParms)
|
|
13926
|
+
|
|
13927
|
+
# execute spotify zeroconf api request.
|
|
13928
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, actionUrl)
|
|
13929
|
+
self.MakeRequest('GET', msg)
|
|
13930
|
+
|
|
13931
|
+
# process results.
|
|
13932
|
+
result = ZeroconfResponse(root=msg.ResponseData)
|
|
13933
|
+
|
|
13934
|
+
# trace.
|
|
13935
|
+
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
13936
|
+
return result
|
|
13937
|
+
|
|
13938
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
13939
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
13940
|
+
except Exception as ex:
|
|
13941
|
+
|
|
13942
|
+
# format unhandled exception.
|
|
13943
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
13944
|
+
|
|
13945
|
+
finally:
|
|
13946
|
+
|
|
13947
|
+
# trace.
|
|
13948
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
13949
|
+
|
|
13950
|
+
|
|
13951
|
+
def ZeroconfAddUser(self,
|
|
13952
|
+
actionUrl:str,
|
|
13953
|
+
getInfoResponse:ZeroconfGetInfo,
|
|
13954
|
+
username:str,
|
|
13955
|
+
password:str,
|
|
13956
|
+
) -> ZeroconfResponse:
|
|
13957
|
+
"""
|
|
13958
|
+
Add a user to a Spotify Connect device by calling the Spotify Zeroconf API `addUser` endpoint.
|
|
13959
|
+
|
|
13960
|
+
Args:
|
|
13961
|
+
actionUrl (str):
|
|
13962
|
+
The Zeroconf action url to issue the request to.
|
|
13963
|
+
Example: `http://192.168.1.80:8200/zc?action=addUser&version=1.0`
|
|
13964
|
+
|
|
13965
|
+
Returns:
|
|
13966
|
+
An `ZeroconfResponse` object that contains the response.
|
|
13967
|
+
|
|
13968
|
+
Raises:
|
|
13969
|
+
SpotifyWebApiError:
|
|
13970
|
+
If the Spotify Web API request was for a non-authorization service
|
|
13971
|
+
and the response contains error information.
|
|
13972
|
+
SpotifApiError:
|
|
13973
|
+
If the method fails for any other reason.
|
|
13974
|
+
|
|
13975
|
+
<details>
|
|
13976
|
+
<summary>Sample Code</summary>
|
|
13977
|
+
```python
|
|
13978
|
+
.. include:: ../docs/include/samplecode/SpotifyClient/ZeroconfGetInformation.py
|
|
13979
|
+
```
|
|
13980
|
+
</details>
|
|
13981
|
+
"""
|
|
13982
|
+
apiMethodName:str = 'ZeroconfAddUser'
|
|
13983
|
+
apiMethodParms:SIMethodParmListContext = None
|
|
13984
|
+
result:ZeroconfResponse = None
|
|
13985
|
+
|
|
13986
|
+
try:
|
|
13987
|
+
|
|
13988
|
+
# trace.
|
|
13989
|
+
apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
|
|
13990
|
+
apiMethodParms.AppendKeyValue("actionUrl", actionUrl)
|
|
13991
|
+
apiMethodParms.AppendKeyValue("getInfoResponse", getInfoResponse)
|
|
13992
|
+
apiMethodParms.AppendKeyValue("username", username)
|
|
13993
|
+
apiMethodParms.AppendKeyValue("password", password)
|
|
13994
|
+
_logsi.LogMethodParmList(SILevel.Verbose, "Get Spotify Zeroconf addUser response", apiMethodParms)
|
|
13995
|
+
|
|
13996
|
+
raise NotImplemented()
|
|
13997
|
+
|
|
13998
|
+
# build credentials object.
|
|
13999
|
+
self.credentials = ZeroconfCredentials(username, password)
|
|
14000
|
+
|
|
14001
|
+
# build authentication blob.
|
|
14002
|
+
builder = ZeroconfBlobBuilder(self.credentials, getInfoResponse.DeviceId, getInfoResponse.PublicKey)
|
|
14003
|
+
blob = builder.build()
|
|
14004
|
+
|
|
14005
|
+
# # call zeroconf to add the user to the device.
|
|
14006
|
+
# r = self._add_user(
|
|
14007
|
+
# self.credentials.username.decode('ascii'),
|
|
14008
|
+
# int_to_b64str(builder.dh_keys.public_key),
|
|
14009
|
+
# blob)
|
|
14010
|
+
|
|
14011
|
+
# def _add_user(self, username: str, client_key: str, blob: str): # -> bool
|
|
14012
|
+
# respone = requests.post(
|
|
14013
|
+
# self.uri,
|
|
14014
|
+
# headers={
|
|
14015
|
+
# 'Content-Type': 'application/x-www-form-urlencoded'
|
|
14016
|
+
# },
|
|
14017
|
+
# params={
|
|
14018
|
+
# 'action': 'addUser',
|
|
14019
|
+
# 'userName': username,
|
|
14020
|
+
# 'clientKey': client_key,
|
|
14021
|
+
# 'blob': blob
|
|
14022
|
+
# }
|
|
14023
|
+
# )
|
|
14024
|
+
# return respone
|
|
14025
|
+
|
|
14026
|
+
# build spotify zeroconf addUser parameters.
|
|
14027
|
+
urlParms:dict = \
|
|
14028
|
+
{
|
|
14029
|
+
'userName': self.credentials.username.decode('ascii'),
|
|
14030
|
+
'clientKey': int_to_b64str(builder.dh_keys.public_key),
|
|
14031
|
+
'blob': blob,
|
|
14032
|
+
'deviceId': getInfoResponse.DeviceId,
|
|
14033
|
+
'deviceName': getInfoResponse.RemoteName,
|
|
14034
|
+
'loginId': 'xxxxxxxxxxx',
|
|
14035
|
+
}
|
|
14036
|
+
|
|
14037
|
+
# let params = [
|
|
14038
|
+
# 3 ("action", "addUser"),
|
|
14039
|
+
# 3 ("userName", username),
|
|
14040
|
+
# 3 ("blob", blob),
|
|
14041
|
+
# 3 ("clientKey", my_public_key),
|
|
14042
|
+
# ("deviceId", &device_id),
|
|
14043
|
+
# ("deviceName", "spotify-connect"),
|
|
14044
|
+
# ("loginId", &login_id),
|
|
14045
|
+
|
|
14046
|
+
|
|
14047
|
+
# execute spotify zeroconf api request.
|
|
14048
|
+
msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, actionUrl)
|
|
14049
|
+
msg.UrlParameters = urlParms
|
|
14050
|
+
self.MakeRequest('POST', msg)
|
|
14051
|
+
|
|
14052
|
+
# process results.
|
|
14053
|
+
result = ZeroconfResponse(root=msg.ResponseData)
|
|
14054
|
+
|
|
14055
|
+
# trace.
|
|
14056
|
+
_logsi.LogObject(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
14057
|
+
return result
|
|
14058
|
+
|
|
14059
|
+
except SpotifyWebApiError: raise # pass handled exceptions on thru
|
|
14060
|
+
except SpotifyWebApiAuthenticationError: raise # pass handled exceptions on thru
|
|
14061
|
+
except Exception as ex:
|
|
14062
|
+
|
|
14063
|
+
# format unhandled exception.
|
|
14064
|
+
raise SpotifyApiError(SAAppMessages.UNHANDLED_EXCEPTION.format(apiMethodName, str(ex)), ex, logsi=_logsi)
|
|
14065
|
+
|
|
14066
|
+
finally:
|
|
14067
|
+
|
|
14068
|
+
# trace.
|
|
14069
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|