spotifywebapiPython 1.0.52__py3-none-any.whl → 1.0.54__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.52.dist-info → spotifywebapiPython-1.0.54.dist-info}/METADATA +1 -1
- {spotifywebapiPython-1.0.52.dist-info → spotifywebapiPython-1.0.54.dist-info}/RECORD +22 -22
- spotifywebapipython/const.py +1 -1
- spotifywebapipython/docs/__init__.html +15 -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 +29 -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 +42 -7
- spotifywebapipython/docs/spotifywebapiPython/spotifydiscovery.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifywebapiauthenticationerror.html +2 -2
- spotifywebapipython/docs/spotifywebapiPython/spotifywebapierror.html +2 -2
- spotifywebapipython/sautils.py +31 -0
- spotifywebapipython/spotifyclient.py +99 -89
- spotifywebapipython/zeroconfapi/zeroconfconnect.py +52 -13
- {spotifywebapiPython-1.0.52.dist-info → spotifywebapiPython-1.0.54.dist-info}/LICENSE +0 -0
- {spotifywebapiPython-1.0.52.dist-info → spotifywebapiPython-1.0.54.dist-info}/WHEEL +0 -0
- {spotifywebapiPython-1.0.52.dist-info → spotifywebapiPython-1.0.54.dist-info}/top_level.txt +0 -0
|
@@ -15,7 +15,7 @@ from zeroconf import Zeroconf
|
|
|
15
15
|
from .oauthcli import AuthClient
|
|
16
16
|
from .models import *
|
|
17
17
|
from .models import UserProfile as UserProfileCurrentUser
|
|
18
|
-
from .sautils import export, GetUnixTimestampMSFromUtcNow, _xmlGetInnerText
|
|
18
|
+
from .sautils import export, GetUnixTimestampMSFromUtcNow, _xmlGetInnerText, validateDelay
|
|
19
19
|
from .saappmessages import SAAppMessages
|
|
20
20
|
from .spotifyapierror import SpotifyApiError
|
|
21
21
|
from .spotifyapimessage import SpotifyApiMessage
|
|
@@ -631,32 +631,6 @@ class SpotifyClient:
|
|
|
631
631
|
return result
|
|
632
632
|
|
|
633
633
|
|
|
634
|
-
def _ValidateDelay(self, delay:float, default:float=0.5, maxDelay:float=10) -> float:
|
|
635
|
-
"""
|
|
636
|
-
Validates a delay value.
|
|
637
|
-
|
|
638
|
-
Args:
|
|
639
|
-
delay (int):
|
|
640
|
-
The delay value to validate.
|
|
641
|
-
default (int):
|
|
642
|
-
The default delay value to set if the user-input delay is not valid.
|
|
643
|
-
maxDelay (int):
|
|
644
|
-
The maximum delay value allowed.
|
|
645
|
-
Default is 10.
|
|
646
|
-
"""
|
|
647
|
-
if (isinstance(delay,int)):
|
|
648
|
-
delay = float(delay)
|
|
649
|
-
|
|
650
|
-
if (not isinstance(delay,float)) or (delay < 0):
|
|
651
|
-
result = default
|
|
652
|
-
elif (delay > maxDelay):
|
|
653
|
-
result = maxDelay
|
|
654
|
-
else:
|
|
655
|
-
result = delay
|
|
656
|
-
|
|
657
|
-
return result
|
|
658
|
-
|
|
659
|
-
|
|
660
634
|
def _ValidateMarket(self,
|
|
661
635
|
market:str,
|
|
662
636
|
) -> str:
|
|
@@ -5945,10 +5919,10 @@ class SpotifyClient:
|
|
|
5945
5919
|
def PlayerActivateDevices(
|
|
5946
5920
|
self,
|
|
5947
5921
|
verifyUserContext:bool=False,
|
|
5948
|
-
delay:float=0.
|
|
5922
|
+
delay:float=0.25
|
|
5949
5923
|
) -> str:
|
|
5950
5924
|
"""
|
|
5951
|
-
Activates all Spotify Connect player devices, and (optionally) switches the active user
|
|
5925
|
+
Activates all static Spotify Connect player devices, and (optionally) switches the active user
|
|
5952
5926
|
context to the current user context.
|
|
5953
5927
|
|
|
5954
5928
|
Args:
|
|
@@ -5961,7 +5935,7 @@ class SpotifyClient:
|
|
|
5961
5935
|
Time delay (in seconds) to wait AFTER issuing the final Connect command (if necessary).
|
|
5962
5936
|
This delay will give the spotify web api time to process the device list change before
|
|
5963
5937
|
another command is issued.
|
|
5964
|
-
Default is 0.
|
|
5938
|
+
Default is 0.25; value range is 0 - 10.
|
|
5965
5939
|
|
|
5966
5940
|
Returns:
|
|
5967
5941
|
A string that contains status text.
|
|
@@ -5985,6 +5959,10 @@ class SpotifyClient:
|
|
|
5985
5959
|
The user context switch is bypassed if the `verifyUserContext` argument is False. If the user context
|
|
5986
5960
|
is to be switched, then a Disconnect will be issued if a user context is active on the device followed
|
|
5987
5961
|
by a Connect to the user context specified on the class constructor.
|
|
5962
|
+
|
|
5963
|
+
Dynamic Spotify Connect devices are not processed by this method, as they are temporary devices and are
|
|
5964
|
+
already active and in the device list. These devices are not found in Zeroconf discovery process, and only
|
|
5965
|
+
exist in the player device list. These are usually Spotify Connect web or mobile players with temporary device id's.
|
|
5988
5966
|
|
|
5989
5967
|
<details>
|
|
5990
5968
|
<summary>Sample Code</summary>
|
|
@@ -6012,7 +5990,7 @@ class SpotifyClient:
|
|
|
6012
5990
|
raise SpotifyZeroconfApiError(SAAppMessages.ARGUMENT_REQUIRED_ERROR % (apiMethodName, 'SpotifyConnectUsername'), logsi=_logsi)
|
|
6013
5991
|
|
|
6014
5992
|
# validations.
|
|
6015
|
-
delay =
|
|
5993
|
+
delay = validateDelay(delay, 0.25, 10)
|
|
6016
5994
|
if (not isinstance(verifyUserContext, bool)):
|
|
6017
5995
|
verifyUserContext = False
|
|
6018
5996
|
|
|
@@ -6049,7 +6027,7 @@ class SpotifyClient:
|
|
|
6049
6027
|
|
|
6050
6028
|
# does our Spotify Connect user account need to take control of the device?
|
|
6051
6029
|
# if not, then we are done.
|
|
6052
|
-
elif (deviceActiveUser == self._SpotifyConnectUsername.lower())
|
|
6030
|
+
elif (deviceActiveUser == self._SpotifyConnectUsername.lower()) or (deviceActiveUser == self.UserProfile.Id.lower()):
|
|
6053
6031
|
_logsi.LogVerbose("Spotify Connect user context '%s' was verified for Device id '%s'; switch not necessary" % (deviceActiveUser, deviceIdResult))
|
|
6054
6032
|
status = status + "user context switch not needed"
|
|
6055
6033
|
|
|
@@ -6072,23 +6050,18 @@ class SpotifyClient:
|
|
|
6072
6050
|
# the current user context before connecting a different user.
|
|
6073
6051
|
if (info.HasActiveUser):
|
|
6074
6052
|
_logsi.LogVerbose("Spotify Connect user context '%s' is being disconnected for Device id '%s'" % (deviceActiveUser, deviceIdResult))
|
|
6075
|
-
zcfResult = zconn.Disconnect()
|
|
6053
|
+
zcfResult = zconn.Disconnect(delay)
|
|
6076
6054
|
status = status + 'disconnected from user context "%s";' % deviceActiveUser
|
|
6077
|
-
|
|
6055
|
+
|
|
6078
6056
|
# connect the device to OUR Spotify Connect user context.
|
|
6079
6057
|
# note that the result here only indicates that the connect was submitted - NOT that it was successful!
|
|
6080
6058
|
_logsi.LogVerbose("Spotify Connect user context '%s' is being connected for Device id '%s'" % (self._SpotifyConnectUsername, deviceIdResult))
|
|
6081
|
-
zcfResult = zconn.Connect(self._SpotifyConnectUsername, self._SpotifyConnectPassword)
|
|
6059
|
+
zcfResult = zconn.Connect(self._SpotifyConnectUsername, self._SpotifyConnectPassword, delay)
|
|
6082
6060
|
status = status + 'connected to user context "%s"' % self._SpotifyConnectUsername
|
|
6083
6061
|
|
|
6084
6062
|
# trace.
|
|
6085
6063
|
_logsi.LogVerbose("Spotify Connect user context switch from '%s' to '%s' was requested for Device id '%s'" % (deviceActiveUser, self._SpotifyConnectUsername, deviceIdResult))
|
|
6086
6064
|
|
|
6087
|
-
# give spotify web api time to process the change and add the device to the device list.
|
|
6088
|
-
if delay > 0:
|
|
6089
|
-
_logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % delay)
|
|
6090
|
-
time.sleep(delay)
|
|
6091
|
-
|
|
6092
6065
|
# append device status to results.
|
|
6093
6066
|
result = "%s%s\n" % (result, MSG_RESULT % (info.RemoteName, info.DeviceId, info.ActiveUser, status))
|
|
6094
6067
|
|
|
@@ -6243,6 +6216,11 @@ class SpotifyClient:
|
|
|
6243
6216
|
SpotifApiError:
|
|
6244
6217
|
If the method fails for any other reason.
|
|
6245
6218
|
|
|
6219
|
+
Note that this method will only return the devices for which the current user
|
|
6220
|
+
context has control of, or other available devices that do not have an active
|
|
6221
|
+
user context assigned. Use the `GetSpotifyConnectDevices` method to retrieve
|
|
6222
|
+
a complete list of devices that are available to all users.
|
|
6223
|
+
|
|
6246
6224
|
The `ConfigurationCache` is updated with the results of this method. Use the
|
|
6247
6225
|
`refresh` argument (with False value) to retrieve the cached value and avoid
|
|
6248
6226
|
the spotify web api request. This results in better performance.
|
|
@@ -7899,10 +7877,18 @@ class SpotifyClient:
|
|
|
7899
7877
|
|
|
7900
7878
|
def GetSpotifyConnectDevices(
|
|
7901
7879
|
self,
|
|
7880
|
+
refresh:bool=True
|
|
7902
7881
|
) -> SpotifyConnectDevices:
|
|
7903
7882
|
"""
|
|
7904
7883
|
Get information about all available Spotify Connect player devices.
|
|
7905
7884
|
|
|
7885
|
+
This method requires the `user-read-playback-state` scope.
|
|
7886
|
+
|
|
7887
|
+
Args:
|
|
7888
|
+
refresh (bool):
|
|
7889
|
+
True (default) to return real-time information from the spotify zeroconf api and
|
|
7890
|
+
update the cache; otherwise, False to just return the cached value.
|
|
7891
|
+
|
|
7906
7892
|
Returns:
|
|
7907
7893
|
A `SpotifyConnectDevices` object that contain the discovery results
|
|
7908
7894
|
as well as the `getInfo` result for each found device.
|
|
@@ -7925,6 +7911,10 @@ class SpotifyClient:
|
|
|
7925
7911
|
process, but still exist in the player device list. These are usually Spotify Connect
|
|
7926
7912
|
web or mobile players with temporary device id's.
|
|
7927
7913
|
|
|
7914
|
+
The `ConfigurationCache` is updated with the results of this method. Use the
|
|
7915
|
+
`refresh` argument (with False value) to retrieve the cached value and avoid
|
|
7916
|
+
the spotify web api request. This results in better performance.
|
|
7917
|
+
|
|
7928
7918
|
<details>
|
|
7929
7919
|
<summary>Sample Code</summary>
|
|
7930
7920
|
```python
|
|
@@ -7934,50 +7924,62 @@ class SpotifyClient:
|
|
|
7934
7924
|
"""
|
|
7935
7925
|
apiMethodName:str = 'GetSpotifyConnectDevices'
|
|
7936
7926
|
result:SpotifyConnectDevices = SpotifyConnectDevices()
|
|
7927
|
+
cacheDesc:str = CACHE_SOURCE_CURRENT
|
|
7937
7928
|
|
|
7938
7929
|
try:
|
|
7939
7930
|
|
|
7940
7931
|
# trace.
|
|
7941
7932
|
_logsi.EnterMethod(SILevel.Debug, apiMethodName)
|
|
7942
7933
|
|
|
7943
|
-
#
|
|
7944
|
-
|
|
7945
|
-
|
|
7946
|
-
|
|
7947
|
-
|
|
7948
|
-
|
|
7934
|
+
# can we use the cached value?
|
|
7935
|
+
if (not refresh) and (apiMethodName in self._ConfigurationCache):
|
|
7936
|
+
|
|
7937
|
+
result = self._ConfigurationCache[apiMethodName]
|
|
7938
|
+
cacheDesc = CACHE_SOURCE_CACHED
|
|
7939
|
+
|
|
7940
|
+
else:
|
|
7941
|
+
|
|
7942
|
+
# discover Spotify Connect devices on the network, waiting up to the specified timeout
|
|
7943
|
+
# for all devices to be discovered. this will return all Spotify Connect devices that
|
|
7944
|
+
# are currently powered on, and are registered to Zeroconf / mDNS.
|
|
7945
|
+
_logsi.LogVerbose("Discovering Spotify Connect devices on the local network")
|
|
7946
|
+
discovery:SpotifyDiscovery = SpotifyDiscovery(self._ZeroconfClient, printToConsole=False)
|
|
7947
|
+
discovery.DiscoverDevices(timeout=self._SpotifyConnectDiscoveryTimeout)
|
|
7949
7948
|
|
|
7950
|
-
|
|
7951
|
-
|
|
7952
|
-
|
|
7953
|
-
|
|
7954
|
-
|
|
7955
|
-
|
|
7956
|
-
|
|
7957
|
-
|
|
7958
|
-
|
|
7959
|
-
|
|
7960
|
-
|
|
7961
|
-
|
|
7962
|
-
|
|
7963
|
-
|
|
7964
|
-
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
7970
|
-
|
|
7971
|
-
|
|
7972
|
-
|
|
7949
|
+
# process all discovered devices.
|
|
7950
|
+
discoverResult:ZeroconfDiscoveryResult
|
|
7951
|
+
for discoverResult in discovery.DiscoveryResults:
|
|
7952
|
+
|
|
7953
|
+
# get the id from the device via the zeroconf API getInfo endpoint, as the id is not
|
|
7954
|
+
# returned in the zeroconf discovery result.
|
|
7955
|
+
zconn:ZeroconfConnect = ZeroconfConnect(discoverResult.HostIpv4Address,
|
|
7956
|
+
discoverResult.HostIpPort,
|
|
7957
|
+
discoverResult.SpotifyConnectCPath,
|
|
7958
|
+
useSSL=False)
|
|
7959
|
+
info:ZeroconfGetInfo = zconn.GetInformation()
|
|
7960
|
+
|
|
7961
|
+
# create new spotify connect device object.
|
|
7962
|
+
scDevice:SpotifyConnectDevice = SpotifyConnectDevice()
|
|
7963
|
+
scDevice.DiscoveryResult = discoverResult
|
|
7964
|
+
scDevice.DeviceInfo = info
|
|
7965
|
+
result.Items.append(scDevice)
|
|
7966
|
+
|
|
7967
|
+
# we will also call the GetPlayerDevices method, in case we have any dynamic devices.
|
|
7968
|
+
# dynamic devices are Spotify Connect devices that are not found in Zeroconf discovery
|
|
7969
|
+
# process, but still exist in the player device list. these are usually Spotify Connect
|
|
7970
|
+
# web or mobile players with temporary device id's.
|
|
7971
|
+
devices:list[Device] = self.GetPlayerDevices(True)
|
|
7973
7972
|
|
|
7974
|
-
|
|
7975
|
-
|
|
7976
|
-
|
|
7977
|
-
|
|
7973
|
+
device:Device
|
|
7974
|
+
for device in devices:
|
|
7975
|
+
if not result.ContainsDeviceId(device.Id):
|
|
7976
|
+
result.AddDynamicDevice(device, self.UserProfile.Id)
|
|
7977
|
+
|
|
7978
|
+
# update cache.
|
|
7979
|
+
self._ConfigurationCache[apiMethodName] = result
|
|
7978
7980
|
|
|
7979
7981
|
# trace.
|
|
7980
|
-
_logsi.LogArray(SILevel.Verbose,
|
|
7982
|
+
_logsi.LogArray(SILevel.Verbose, TRACE_METHOD_RESULT_TYPE_CACHED % (apiMethodName, type(result).__name__, cacheDesc), result)
|
|
7981
7983
|
return result
|
|
7982
7984
|
|
|
7983
7985
|
except SpotifyZeroconfApiError: raise # pass handled exceptions on thru
|
|
@@ -9422,7 +9424,7 @@ class SpotifyClient:
|
|
|
9422
9424
|
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect device pause playback", apiMethodParms)
|
|
9423
9425
|
|
|
9424
9426
|
# validations.
|
|
9425
|
-
delay =
|
|
9427
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
9426
9428
|
|
|
9427
9429
|
# check for device name; convert to an id if a name was supplied.
|
|
9428
9430
|
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -9555,7 +9557,7 @@ class SpotifyClient:
|
|
|
9555
9557
|
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect device play context", apiMethodParms)
|
|
9556
9558
|
|
|
9557
9559
|
# validations.
|
|
9558
|
-
delay =
|
|
9560
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
9559
9561
|
|
|
9560
9562
|
# check for device name; convert to an id if a name was supplied.
|
|
9561
9563
|
#deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -9663,7 +9665,7 @@ class SpotifyClient:
|
|
|
9663
9665
|
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect device play track favorites", apiMethodParms)
|
|
9664
9666
|
|
|
9665
9667
|
# validations.
|
|
9666
|
-
delay =
|
|
9668
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
9667
9669
|
|
|
9668
9670
|
# get current users favorite tracks.
|
|
9669
9671
|
tracks:TrackPageSaved = self.GetTrackFavorites(limitTotal=200)
|
|
@@ -9774,7 +9776,7 @@ class SpotifyClient:
|
|
|
9774
9776
|
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect device play tracks", apiMethodParms)
|
|
9775
9777
|
|
|
9776
9778
|
# validations.
|
|
9777
|
-
delay =
|
|
9779
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
9778
9780
|
|
|
9779
9781
|
# build a list of all item uri's.
|
|
9780
9782
|
# remove any leading / trailing spaces in case user put a space between the items.
|
|
@@ -9885,7 +9887,7 @@ class SpotifyClient:
|
|
|
9885
9887
|
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect device resume playback", apiMethodParms)
|
|
9886
9888
|
|
|
9887
9889
|
# validations.
|
|
9888
|
-
delay =
|
|
9890
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
9889
9891
|
|
|
9890
9892
|
# check for device name; convert to an id if a name was supplied.
|
|
9891
9893
|
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -9982,7 +9984,7 @@ class SpotifyClient:
|
|
|
9982
9984
|
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect device seek position", apiMethodParms)
|
|
9983
9985
|
|
|
9984
9986
|
# validations.
|
|
9985
|
-
delay =
|
|
9987
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
9986
9988
|
|
|
9987
9989
|
# check for device name; convert to an id if a name was supplied.
|
|
9988
9990
|
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -10074,7 +10076,7 @@ class SpotifyClient:
|
|
|
10074
10076
|
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect device skip next", apiMethodParms)
|
|
10075
10077
|
|
|
10076
10078
|
# validations.
|
|
10077
|
-
delay =
|
|
10079
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
10078
10080
|
|
|
10079
10081
|
# check for device name; convert to an id if a name was supplied.
|
|
10080
10082
|
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -10163,7 +10165,7 @@ class SpotifyClient:
|
|
|
10163
10165
|
_logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect device skip previous", apiMethodParms)
|
|
10164
10166
|
|
|
10165
10167
|
# validations.
|
|
10166
|
-
delay =
|
|
10168
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
10167
10169
|
|
|
10168
10170
|
# check for device name; convert to an id if a name was supplied.
|
|
10169
10171
|
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -10206,6 +10208,7 @@ class SpotifyClient:
|
|
|
10206
10208
|
deviceValue:str,
|
|
10207
10209
|
verifyUserContext:bool=True,
|
|
10208
10210
|
verifyTimeout:float=5.0,
|
|
10211
|
+
delay:float=0.25
|
|
10209
10212
|
) -> str:
|
|
10210
10213
|
"""
|
|
10211
10214
|
Resolves a Spotify Connect device identifier from a specified device id, name, alias id,
|
|
@@ -10225,6 +10228,11 @@ class SpotifyClient:
|
|
|
10225
10228
|
Connect device list. This value is only used if a Connect command has to be
|
|
10226
10229
|
issued to activate the device.
|
|
10227
10230
|
Default is 5; value range is 0 - 10.
|
|
10231
|
+
delay (float):
|
|
10232
|
+
Time delay (in seconds) to wait AFTER issuing any command to the device.
|
|
10233
|
+
This delay will give the spotify zeroconf api time to process the change before
|
|
10234
|
+
another command is issued.
|
|
10235
|
+
Default is 0.25; value range is 0 - 10.
|
|
10228
10236
|
|
|
10229
10237
|
Returns:
|
|
10230
10238
|
A device Id for the deviceValue if one could be resolved;
|
|
@@ -10273,6 +10281,7 @@ class SpotifyClient:
|
|
|
10273
10281
|
apiMethodParms.AppendKeyValue("deviceValue", deviceValue)
|
|
10274
10282
|
apiMethodParms.AppendKeyValue("verifyUserContext", verifyUserContext)
|
|
10275
10283
|
apiMethodParms.AppendKeyValue("verifyTimeout", verifyTimeout)
|
|
10284
|
+
apiMethodParms.AppendKeyValue("delay", delay)
|
|
10276
10285
|
_logsi.LogMethodParmList(SILevel.Verbose, "Resolving Spotify Connect Player Device Id", apiMethodParms)
|
|
10277
10286
|
|
|
10278
10287
|
# if device value not specified then we are done.
|
|
@@ -10281,7 +10290,8 @@ class SpotifyClient:
|
|
|
10281
10290
|
return None
|
|
10282
10291
|
|
|
10283
10292
|
# validations.
|
|
10284
|
-
|
|
10293
|
+
delay = validateDelay(delay, 0.25, 10)
|
|
10294
|
+
verifyTimeout = validateDelay(verifyTimeout, 5, 10)
|
|
10285
10295
|
if (not isinstance(verifyUserContext, bool)):
|
|
10286
10296
|
verifyUserContext = True
|
|
10287
10297
|
|
|
@@ -10376,7 +10386,7 @@ class SpotifyClient:
|
|
|
10376
10386
|
# the current user context before connecting a different user.
|
|
10377
10387
|
if (info.HasActiveUser):
|
|
10378
10388
|
_logsi.LogVerbose("Spotify Connect user context '%s' is being disconnected for Device id '%s'" % (deviceActiveUser, deviceIdResult))
|
|
10379
|
-
zcfResult = zconn.Disconnect()
|
|
10389
|
+
zcfResult = zconn.Disconnect(delay)
|
|
10380
10390
|
|
|
10381
10391
|
# connect the device to OUR Spotify Connect user context.
|
|
10382
10392
|
# note that the result here only indicates that the connect was submitted - NOT that it was successful!
|
|
@@ -10490,7 +10500,7 @@ class SpotifyClient:
|
|
|
10490
10500
|
_logsi.LogMethodParmList(SILevel.Verbose, "Set Spotify Connect device set repeat mode", apiMethodParms)
|
|
10491
10501
|
|
|
10492
10502
|
# validations.
|
|
10493
|
-
delay =
|
|
10503
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
10494
10504
|
|
|
10495
10505
|
# check for device name; convert to an id if a name was supplied.
|
|
10496
10506
|
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -10589,7 +10599,7 @@ class SpotifyClient:
|
|
|
10589
10599
|
_logsi.LogMethodParmList(SILevel.Verbose, "Set Spotify Connect device set shuffle mode", apiMethodParms)
|
|
10590
10600
|
|
|
10591
10601
|
# validations.
|
|
10592
|
-
delay =
|
|
10602
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
10593
10603
|
|
|
10594
10604
|
# check for device name; convert to an id if a name was supplied.
|
|
10595
10605
|
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -10687,7 +10697,7 @@ class SpotifyClient:
|
|
|
10687
10697
|
_logsi.LogMethodParmList(SILevel.Verbose, "Set Spotify Connect device set volume level", apiMethodParms)
|
|
10688
10698
|
|
|
10689
10699
|
# validations.
|
|
10690
|
-
delay =
|
|
10700
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
10691
10701
|
|
|
10692
10702
|
# check for device name; convert to an id if a name was supplied.
|
|
10693
10703
|
deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -10785,7 +10795,7 @@ class SpotifyClient:
|
|
|
10785
10795
|
_logsi.LogMethodParmList(SILevel.Verbose, "Transfer playback to a new Spotify Connect device", apiMethodParms)
|
|
10786
10796
|
|
|
10787
10797
|
# validations.
|
|
10788
|
-
delay =
|
|
10798
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
10789
10799
|
|
|
10790
10800
|
# check for device name; convert to an id if a name was supplied.
|
|
10791
10801
|
#deviceId = self.PlayerConvertDeviceNameToId(deviceId)
|
|
@@ -10891,7 +10901,7 @@ class SpotifyClient:
|
|
|
10891
10901
|
_logsi.LogMethodParmList(SILevel.Verbose, "Checks if a Spotify Connect device is active, and activate one if not", apiMethodParms)
|
|
10892
10902
|
|
|
10893
10903
|
# validations.
|
|
10894
|
-
delay =
|
|
10904
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
10895
10905
|
|
|
10896
10906
|
# get current Spotify Connect player state.
|
|
10897
10907
|
result = self.GetPlayerPlaybackState()
|
|
@@ -12,8 +12,11 @@ from .spotifyzeroconfapierror import SpotifyZeroconfApiError
|
|
|
12
12
|
from .zeroconfresponse import ZeroconfResponse
|
|
13
13
|
from .zeroconfgetinfo import ZeroconfGetInfo
|
|
14
14
|
from ..saappmessages import SAAppMessages
|
|
15
|
-
from ..sautils import export
|
|
15
|
+
from ..sautils import export, validateDelay
|
|
16
16
|
from ..spotifyapierror import SpotifyApiError
|
|
17
|
+
from ..const import (
|
|
18
|
+
TRACE_MSG_DELAY_DEVICE,
|
|
19
|
+
)
|
|
17
20
|
|
|
18
21
|
# get smartinspect logger reference; create a new session for this module name.
|
|
19
22
|
from smartinspectpython.siauto import SIAuto, SILevel, SISession, SIMethodParmListContext, SISourceId
|
|
@@ -261,10 +264,12 @@ class ZeroconfConnect:
|
|
|
261
264
|
return responseData
|
|
262
265
|
|
|
263
266
|
|
|
264
|
-
def Connect(
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
267
|
+
def Connect(
|
|
268
|
+
self,
|
|
269
|
+
username:str,
|
|
270
|
+
password:str,
|
|
271
|
+
delay:float=0.50
|
|
272
|
+
) -> ZeroconfResponse:
|
|
268
273
|
"""
|
|
269
274
|
Calls the `addUser` Spotify Zeroconf API endpoint to issue a call to SpConnectionLoginBlob. If successful,
|
|
270
275
|
the associated device id is added to the Spotify Connect active device list for the specified user account.
|
|
@@ -277,6 +282,11 @@ class ZeroconfConnect:
|
|
|
277
282
|
on the manufacturer device.
|
|
278
283
|
password (str):
|
|
279
284
|
Spotify Connect user password to login with.
|
|
285
|
+
delay (float):
|
|
286
|
+
Time delay (in seconds) to wait AFTER issuing the command to the device.
|
|
287
|
+
This delay will give the spotify zeroconf api time to process the change before
|
|
288
|
+
another command is issued.
|
|
289
|
+
Default is 0.50; value range is 0 - 10.
|
|
280
290
|
|
|
281
291
|
Returns:
|
|
282
292
|
A `ZeroconfResponse` object that indicates success or failure (see notes below).
|
|
@@ -321,6 +331,7 @@ class ZeroconfConnect:
|
|
|
321
331
|
apiMethodParms.AppendKeyValue("Version", self._Version)
|
|
322
332
|
apiMethodParms.AppendKeyValue("Uri", self._Uri)
|
|
323
333
|
apiMethodParms.AppendKeyValue("username", username)
|
|
334
|
+
apiMethodParms.AppendKeyValue("delay", delay)
|
|
324
335
|
_logsi.LogMethodParmList(SILevel.Verbose, "Connecting device to Spotify Connect using specified Username and Password", apiMethodParms)
|
|
325
336
|
|
|
326
337
|
# validations.
|
|
@@ -328,6 +339,7 @@ class ZeroconfConnect:
|
|
|
328
339
|
raise SpotifyApiError(SAAppMessages.ARGUMENT_REQUIRED_ERROR % (apiMethodName, 'username'), logsi=_logsi)
|
|
329
340
|
if (password is None) or (not isinstance(password,str)):
|
|
330
341
|
raise SpotifyApiError(SAAppMessages.ARGUMENT_REQUIRED_ERROR % (apiMethodName, 'password'), logsi=_logsi)
|
|
342
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
331
343
|
|
|
332
344
|
# get the current device id from the device via Spotify ZeroConf API `getInfo` endpoint.
|
|
333
345
|
info:ZeroconfGetInfo = self.GetInformation()
|
|
@@ -342,7 +354,8 @@ class ZeroconfConnect:
|
|
|
342
354
|
self._Uri,
|
|
343
355
|
timeout=10,
|
|
344
356
|
headers={
|
|
345
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
357
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
358
|
+
'Connection': 'close'
|
|
346
359
|
},
|
|
347
360
|
data={
|
|
348
361
|
'action': 'addUser',
|
|
@@ -361,6 +374,13 @@ class ZeroconfConnect:
|
|
|
361
374
|
|
|
362
375
|
# trace.
|
|
363
376
|
_logsi.LogObject(SILevel.Verbose, '%s result - type="%s"' % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
377
|
+
|
|
378
|
+
# give spotify zeroconf api time to process the change.
|
|
379
|
+
if delay > 0:
|
|
380
|
+
_logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % delay)
|
|
381
|
+
time.sleep(delay)
|
|
382
|
+
|
|
383
|
+
# return result to caller.
|
|
364
384
|
return result
|
|
365
385
|
|
|
366
386
|
except SpotifyZeroconfApiError: raise # pass handled exceptions on thru
|
|
@@ -380,10 +400,20 @@ class ZeroconfConnect:
|
|
|
380
400
|
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
381
401
|
|
|
382
402
|
|
|
383
|
-
def Disconnect(
|
|
403
|
+
def Disconnect(
|
|
404
|
+
self,
|
|
405
|
+
delay:float=0.50
|
|
406
|
+
) -> ZeroconfResponse:
|
|
384
407
|
"""
|
|
385
408
|
Calls the `resetUsers` Spotify Zeroconf API endpoint to issue a call to SpConnectionLogout.
|
|
386
409
|
|
|
410
|
+
Args:
|
|
411
|
+
delay (float):
|
|
412
|
+
Time delay (in seconds) to wait AFTER issuing the command to the device.
|
|
413
|
+
This delay will give the spotify zeroconf api time to process the change before
|
|
414
|
+
another command is issued.
|
|
415
|
+
Default is 0.50; value range is 0 - 10.
|
|
416
|
+
|
|
387
417
|
Returns:
|
|
388
418
|
A `ZeroconfResponse` object that indicates success or failure (see notes below).
|
|
389
419
|
|
|
@@ -415,14 +445,19 @@ class ZeroconfConnect:
|
|
|
415
445
|
apiMethodParms.AppendKeyValue("CPath", self._CPath)
|
|
416
446
|
apiMethodParms.AppendKeyValue("Version", self._Version)
|
|
417
447
|
apiMethodParms.AppendKeyValue("Uri", self._Uri)
|
|
448
|
+
apiMethodParms.AppendKeyValue("delay", delay)
|
|
418
449
|
_logsi.LogMethodParmList(SILevel.Verbose, "Disconnecting device from Spotify Connect", apiMethodParms)
|
|
419
450
|
|
|
451
|
+
# validations.
|
|
452
|
+
delay = validateDelay(delay, 0.50, 10)
|
|
453
|
+
|
|
420
454
|
# execute spotify zeroconf api request.
|
|
421
455
|
response = requests.post(
|
|
422
456
|
self._Uri,
|
|
423
457
|
timeout=10,
|
|
424
458
|
headers={
|
|
425
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
459
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
460
|
+
'Connection': 'close'
|
|
426
461
|
},
|
|
427
462
|
data={
|
|
428
463
|
'action': 'resetUsers',
|
|
@@ -436,12 +471,15 @@ class ZeroconfConnect:
|
|
|
436
471
|
# process results.
|
|
437
472
|
result = ZeroconfResponse(root=responseData)
|
|
438
473
|
|
|
439
|
-
# just in case user tries to issue a connect immediately after this, give the device
|
|
440
|
-
# a little time to reset the connection so the subsequent connect does not fail.
|
|
441
|
-
time.sleep(0.5)
|
|
442
|
-
|
|
443
474
|
# trace.
|
|
444
475
|
_logsi.LogObject(SILevel.Verbose, '%s result - type="%s"' % (apiMethodName, type(result).__name__), result, excludeNonPublic=True)
|
|
476
|
+
|
|
477
|
+
# give spotify zeroconf api time to process the change.
|
|
478
|
+
if delay > 0:
|
|
479
|
+
_logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % delay)
|
|
480
|
+
time.sleep(delay)
|
|
481
|
+
|
|
482
|
+
# return result to caller.
|
|
445
483
|
return result
|
|
446
484
|
|
|
447
485
|
except SpotifyZeroconfApiError: raise # pass handled exceptions on thru
|
|
@@ -520,7 +558,8 @@ class ZeroconfConnect:
|
|
|
520
558
|
self._Uri,
|
|
521
559
|
timeout=10,
|
|
522
560
|
headers={
|
|
523
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
561
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
562
|
+
'Connection': 'close'
|
|
524
563
|
},
|
|
525
564
|
params={
|
|
526
565
|
'action': 'getInfo',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|