spotifywebapiPython 1.0.265__py3-none-any.whl → 1.0.267__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.
- spotifywebapipython/const.py +6 -1
- spotifywebapipython/docs/__init__.html +14 -2
- spotifywebapipython/docs/index.html +2 -2
- spotifywebapipython/docs/search.js +1 -1
- spotifywebapipython/docs/spotifywebapipython/const.html +20 -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 +2 -2
- spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html +2 -2
- spotifywebapipython/docs/spotifywebapipython/spotifymediatypes.html +2 -2
- spotifywebapipython/docs/spotifywebapipython/spotifytypeprefixes.html +2 -2
- spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html +2 -2
- spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html +2 -2
- spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html +2 -2
- spotifywebapipython/models/playerlastplayedinfo.py +61 -0
- spotifywebapipython/models/playlist.py +5 -0
- spotifywebapipython/models/playlistsimplified.py +5 -0
- spotifywebapipython/spotifyclient.py +166 -4
- {spotifywebapipython-1.0.265.dist-info → spotifywebapipython-1.0.267.dist-info}/METADATA +1 -1
- {spotifywebapipython-1.0.265.dist-info → spotifywebapipython-1.0.267.dist-info}/RECORD +26 -26
- {spotifywebapipython-1.0.265.dist-info → spotifywebapipython-1.0.267.dist-info}/LICENSE +0 -0
- {spotifywebapipython-1.0.265.dist-info → spotifywebapipython-1.0.267.dist-info}/WHEEL +0 -0
- {spotifywebapipython-1.0.265.dist-info → spotifywebapipython-1.0.267.dist-info}/top_level.txt +0 -0
|
@@ -4,6 +4,8 @@ from datetime import datetime
|
|
|
4
4
|
import json
|
|
5
5
|
from io import BytesIO
|
|
6
6
|
from oauthlib.oauth2 import BackendApplicationClient, WebApplicationClient
|
|
7
|
+
import os.path
|
|
8
|
+
import platformdirs
|
|
7
9
|
import random
|
|
8
10
|
from soco import SoCo
|
|
9
11
|
from soco.core import (
|
|
@@ -51,6 +53,7 @@ from .const import (
|
|
|
51
53
|
SPOTIFY_DESKTOP_APP_CLIENT_ID,
|
|
52
54
|
SPOTIFY_DEFAULT_MARKET,
|
|
53
55
|
SPOTIFY_WEBAPI_URL_BASE,
|
|
56
|
+
SPOTIFYWEBAPIPYTHON_CONFIG_FILE,
|
|
54
57
|
SPOTIFYWEBAPIPYTHON_TOKEN_CACHE_FILE,
|
|
55
58
|
TRACE_METHOD_RESULT,
|
|
56
59
|
TRACE_METHOD_RESULT_TYPE,
|
|
@@ -69,6 +72,8 @@ CACHE_SOURCE_CACHED:str = "cached"
|
|
|
69
72
|
CACHE_SOURCE_CURRENT:str = "current"
|
|
70
73
|
CACHE_KEY_GETSPOTIFYCONNECTDEVICES:str = "GetSpotifyConnectDevices"
|
|
71
74
|
|
|
75
|
+
CONFIG_DATA_KEY_PLAYERLASTPLAYEDINFO:str = "player_last_played_info"
|
|
76
|
+
|
|
72
77
|
MUSIC_SOURCE_SPOTIFY_LOCAL_QUEUE:str = "SPOTIFY_LOCAL_QUEUE"
|
|
73
78
|
MUSIC_SOURCE_SPOTIFY_CONNECT:str = "SPOTIFY_CONNECT"
|
|
74
79
|
|
|
@@ -218,11 +223,12 @@ class SpotifyClient:
|
|
|
218
223
|
self._AuthToken:SpotifyAuthToken = None
|
|
219
224
|
self._AuthClient:AuthClient = None
|
|
220
225
|
self._ConfigurationCache:dict = {}
|
|
226
|
+
self._ConfigurationDataPath:str = None
|
|
221
227
|
self._DefaultDeviceId:str = None
|
|
222
228
|
self._HasSpotifyWebPlayerCredentials:bool = False
|
|
223
229
|
self._IsDisposed:bool = False
|
|
224
230
|
self._Manager:PoolManager = manager
|
|
225
|
-
self._PlayerLastPlayedInfo:PlayerLastPlayedInfo =
|
|
231
|
+
self._PlayerLastPlayedInfo:PlayerLastPlayedInfo = None
|
|
226
232
|
self._SpotifyConnectUsername:str = spotifyConnectUsername
|
|
227
233
|
self._SpotifyConnectPassword:str = spotifyConnectPassword
|
|
228
234
|
self._SpotifyConnectLoginId:str = spotifyConnectLoginId
|
|
@@ -253,6 +259,15 @@ class SpotifyClient:
|
|
|
253
259
|
block=True # limit number of connections to the device.
|
|
254
260
|
)
|
|
255
261
|
|
|
262
|
+
|
|
263
|
+
# verify token storage directory exists.
|
|
264
|
+
if tokenStorageDir is None:
|
|
265
|
+
tokenStorageDir = platformdirs.site_config_dir('SpotifyWebApiPython', ensure_exists=True, appauthor=False)
|
|
266
|
+
os.makedirs(tokenStorageDir, exist_ok=True) # succeeds even if directory exists.
|
|
267
|
+
|
|
268
|
+
# set configuration data path.
|
|
269
|
+
self._ConfigurationDataPath = os.path.join(tokenStorageDir, SPOTIFYWEBAPIPYTHON_CONFIG_FILE)
|
|
270
|
+
|
|
256
271
|
# create the zeroconf client if one was not specified.
|
|
257
272
|
if zeroconfClient is None:
|
|
258
273
|
_logsi.LogVerbose("Creating new Zeroconf instance for discovery")
|
|
@@ -921,6 +936,129 @@ class SpotifyClient:
|
|
|
921
936
|
|
|
922
937
|
|
|
923
938
|
|
|
939
|
+
def _LoadConfigurationData(
|
|
940
|
+
self,
|
|
941
|
+
dataKey:str,
|
|
942
|
+
defaultValue=None,
|
|
943
|
+
) -> object:
|
|
944
|
+
"""
|
|
945
|
+
Loads a data key value from the configuration data file.
|
|
946
|
+
|
|
947
|
+
Args:
|
|
948
|
+
dataKey (str):
|
|
949
|
+
Data key to retrieve the value for.
|
|
950
|
+
defaultValue (object):
|
|
951
|
+
A default object to return if the specified data key was not found (default is null).
|
|
952
|
+
|
|
953
|
+
Returns:
|
|
954
|
+
The value previously stored for the specified dataKey, if found in the file; otherwise, null.
|
|
955
|
+
|
|
956
|
+
This method will not raise any exceptions.
|
|
957
|
+
"""
|
|
958
|
+
apiMethodName:str = '_LoadConfigurationData'
|
|
959
|
+
|
|
960
|
+
try:
|
|
961
|
+
|
|
962
|
+
# trace.
|
|
963
|
+
_logsi.EnterMethod(SILevel.Debug, apiMethodName)
|
|
964
|
+
_logsi.LogVerbose("Config data storage key: \"%s\"" % (dataKey))
|
|
965
|
+
_logsi.LogVerbose("Config data storage file path: \"%s\"" % (self._ConfigurationDataPath))
|
|
966
|
+
|
|
967
|
+
# does the config data file exist?
|
|
968
|
+
if os.path.exists(self._ConfigurationDataPath):
|
|
969
|
+
|
|
970
|
+
# open the config data storage file, and load it's contents.
|
|
971
|
+
_logsi.LogVerbose("Opening config data storage file")
|
|
972
|
+
with open(self._ConfigurationDataPath, 'r') as f:
|
|
973
|
+
|
|
974
|
+
dataKeys = json.load(f)
|
|
975
|
+
|
|
976
|
+
# if config data key exists then return its data; otherwise, return the default.
|
|
977
|
+
if dataKey in dataKeys:
|
|
978
|
+
_logsi.LogDictionary(SILevel.Verbose, "Data was loaded from config data storage file for key: \"%s\"" % (dataKey), dataKeys[dataKey], prettyPrint=True)
|
|
979
|
+
return dataKeys[dataKey]
|
|
980
|
+
else:
|
|
981
|
+
_logsi.LogVerbose("DataKey was not found in config data storage file for key: \"%s\"" % (dataKey))
|
|
982
|
+
return defaultValue
|
|
983
|
+
|
|
984
|
+
else:
|
|
985
|
+
|
|
986
|
+
_logsi.LogVerbose("Config data storage file was not found: \"%s\"" % (self._ConfigurationDataPath))
|
|
987
|
+
return defaultValue
|
|
988
|
+
|
|
989
|
+
except Exception as ex:
|
|
990
|
+
|
|
991
|
+
# trace.
|
|
992
|
+
_logsi.LogException("Could not load config data from disk (exception will be ignored)", ex)
|
|
993
|
+
return defaultValue
|
|
994
|
+
|
|
995
|
+
finally:
|
|
996
|
+
|
|
997
|
+
# trace.
|
|
998
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
999
|
+
|
|
1000
|
+
|
|
1001
|
+
def _SaveConfigurationData(
|
|
1002
|
+
self,
|
|
1003
|
+
dataKey:str,
|
|
1004
|
+
dataValue=None,
|
|
1005
|
+
) -> None:
|
|
1006
|
+
"""
|
|
1007
|
+
Saves a data key value to the configuration data file.
|
|
1008
|
+
|
|
1009
|
+
Args:
|
|
1010
|
+
dataKey (str):
|
|
1011
|
+
Data key to store the value for.
|
|
1012
|
+
dataValue (object):
|
|
1013
|
+
Data value to save.
|
|
1014
|
+
|
|
1015
|
+
This method will not raise any exceptions.
|
|
1016
|
+
"""
|
|
1017
|
+
apiMethodName:str = '_SaveConfigurationData'
|
|
1018
|
+
|
|
1019
|
+
try:
|
|
1020
|
+
|
|
1021
|
+
# trace.
|
|
1022
|
+
_logsi.EnterMethod(SILevel.Debug, apiMethodName)
|
|
1023
|
+
_logsi.LogVerbose("Config data storage key: \"%s\"" % (dataKey))
|
|
1024
|
+
_logsi.LogVerbose("Config data storage file path: \"%s\"" % (self._ConfigurationDataPath))
|
|
1025
|
+
if (isinstance(dataValue, dict)):
|
|
1026
|
+
_logsi.LogDictionary(SILevel.Verbose, "Config data storage value (pretty print)", dataValue, prettyPrint=True)
|
|
1027
|
+
else:
|
|
1028
|
+
_logsi.LogValue(SILevel.Verbose, "Config data storage value (non-dict)", dataValue)
|
|
1029
|
+
|
|
1030
|
+
dataKeys:dict = {}
|
|
1031
|
+
|
|
1032
|
+
# does the config data storage file exist?
|
|
1033
|
+
if os.path.exists(self._ConfigurationDataPath):
|
|
1034
|
+
|
|
1035
|
+
# open the config data storage file, and load it's contents.
|
|
1036
|
+
#_logsi.LogVerbose("Loading config data storage file contents")
|
|
1037
|
+
with open(self._ConfigurationDataPath, 'r') as f:
|
|
1038
|
+
dataKeys = json.load(f)
|
|
1039
|
+
|
|
1040
|
+
if dataValue is not None:
|
|
1041
|
+
|
|
1042
|
+
# store the config data for the key.
|
|
1043
|
+
#_logsi.LogVerbose("Updating config key value in config data storage")
|
|
1044
|
+
dataKeys[dataKey] = dataValue
|
|
1045
|
+
|
|
1046
|
+
# save the config data storage file changes.
|
|
1047
|
+
_logsi.LogVerbose("Saving config key data to disk: \"%s\"" % (dataKey))
|
|
1048
|
+
with open(self._ConfigurationDataPath, 'w') as f:
|
|
1049
|
+
json.dump(dataKeys, f, indent=4, sort_keys=True)
|
|
1050
|
+
|
|
1051
|
+
except Exception as ex:
|
|
1052
|
+
|
|
1053
|
+
# trace.
|
|
1054
|
+
_logsi.LogException("Could not store config key data to disk: \"%s\" (exception will be ignored)" % (dataKey), ex)
|
|
1055
|
+
|
|
1056
|
+
finally:
|
|
1057
|
+
|
|
1058
|
+
# trace.
|
|
1059
|
+
_logsi.LeaveMethod(SILevel.Debug, apiMethodName)
|
|
1060
|
+
|
|
1061
|
+
|
|
924
1062
|
def _ResolveDeviceObject(
|
|
925
1063
|
self,
|
|
926
1064
|
device:str | SpotifyConnectDevice,
|
|
@@ -1016,6 +1154,10 @@ class SpotifyClient:
|
|
|
1016
1154
|
_logsi.LogVerbose("Spotify Connect LoginId not specified on class constructor; using Spotify UserProfile ID value \"%s\"" % (self._UserProfile.Id), colorValue=SIColors.Coral)
|
|
1017
1155
|
self._SpotifyConnectLoginId = self._UserProfile.Id
|
|
1018
1156
|
|
|
1157
|
+
# retrieve player last played info for the user from config data file.
|
|
1158
|
+
playerLastPlayedData:dict = self._LoadConfigurationData(f"{self._SpotifyConnectLoginId}/{CONFIG_DATA_KEY_PLAYERLASTPLAYEDINFO}", PlayerLastPlayedInfo())
|
|
1159
|
+
self._PlayerLastPlayedInfo = PlayerLastPlayedInfo.FromDictionary(playerLastPlayedData)
|
|
1160
|
+
|
|
1019
1161
|
try:
|
|
1020
1162
|
|
|
1021
1163
|
# were Spotify Web Player cookie credentials specified on the class constructor?
|
|
@@ -1124,6 +1266,10 @@ class SpotifyClient:
|
|
|
1124
1266
|
# ensure the object exists.
|
|
1125
1267
|
if (self._SpotifyConnectDirectory is not None):
|
|
1126
1268
|
|
|
1269
|
+
# store player last played info for the user to config data file.
|
|
1270
|
+
if (self._PlayerLastPlayedInfo) and (not self._PlayerLastPlayedInfo.IsEmpty):
|
|
1271
|
+
self._SaveConfigurationData(f"{self._SpotifyConnectLoginId}/{CONFIG_DATA_KEY_PLAYERLASTPLAYEDINFO}", self._PlayerLastPlayedInfo.ToDictionary())
|
|
1272
|
+
|
|
1127
1273
|
# is the task alive?
|
|
1128
1274
|
if (self._SpotifyConnectDirectory.is_alive()):
|
|
1129
1275
|
|
|
@@ -14879,12 +15025,28 @@ class SpotifyClient:
|
|
|
14879
15025
|
else:
|
|
14880
15026
|
|
|
14881
15027
|
# yes - play previously played content.
|
|
14882
|
-
if (self.PlayerLastPlayedInfo.Context is not None):
|
|
14883
|
-
|
|
14884
|
-
|
|
15028
|
+
if (self.PlayerLastPlayedInfo.Context) and (self.PlayerLastPlayedInfo.Context.Uri is not None):
|
|
15029
|
+
|
|
15030
|
+
try:
|
|
15031
|
+
|
|
15032
|
+
# try playing the track within the specified context. this will fail with a
|
|
15033
|
+
# "403 restriction violated" error if the specified track is not in the playlist
|
|
15034
|
+
# context, which can happen if the playlist has played through all of it's items.
|
|
15035
|
+
_logsi.LogVerbose("Resuming last played context and track instead of transferring playback")
|
|
15036
|
+
self.PlayerMediaPlayContext(self.PlayerLastPlayedInfo.Context.Uri, self.PlayerLastPlayedInfo.Item.Uri, None, self.PlayerLastPlayedInfo.ProgressMS, scDevice, shuffle=False)
|
|
15037
|
+
|
|
15038
|
+
except SpotifyWebApiError as ex:
|
|
15039
|
+
|
|
15040
|
+
if ((ex.Message or "").lower().find("restriction violated") > -1):
|
|
15041
|
+
_logsi.LogVerbose("Resuming last played track, as the context has been completely played through and the track is not part of the context")
|
|
15042
|
+
self.PlayerMediaPlayTracks(self.PlayerLastPlayedInfo.Item.Uri, self.PlayerLastPlayedInfo.ProgressMS, scDevice, shuffle=False)
|
|
15043
|
+
else:
|
|
15044
|
+
raise
|
|
15045
|
+
|
|
14885
15046
|
else:
|
|
14886
15047
|
_logsi.LogVerbose("Resuming last played track instead of transferring playback")
|
|
14887
15048
|
self.PlayerMediaPlayTracks(self.PlayerLastPlayedInfo.Item.Uri, self.PlayerLastPlayedInfo.ProgressMS, scDevice, shuffle=False)
|
|
15049
|
+
|
|
14888
15050
|
return scDevice
|
|
14889
15051
|
|
|
14890
15052
|
# is the resolved device already active?
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
spotifywebapipython/__init__.py,sha256=ka7F2AsT-UU7KSYKBnfgl5Trojcep5aQspLutg8D-2k,1306
|
|
2
|
-
spotifywebapipython/const.py,sha256=
|
|
2
|
+
spotifywebapipython/const.py,sha256=DUvCGdYTk2uD3hQo3wvt9Bg-q1knW4Ma4vjrQRK9JAY,4100
|
|
3
3
|
spotifywebapipython/saappmessages.py,sha256=mVprjpd5CdD8kYeAkLzRvMvIQPmaYtH4UCP5my3QhSk,5065
|
|
4
4
|
spotifywebapipython/sautils.py,sha256=j3f_Lu3Tb5D7-Gd2rJ2Ep901W-4XDp6Vq6XXVl8DX5I,8098
|
|
5
5
|
spotifywebapipython/spotifyapierror.py,sha256=23_CYlxWN0BceYYCLpBpunl55vEwPr_wFf34l74xzeA,1855
|
|
6
6
|
spotifywebapipython/spotifyapimessage.py,sha256=wCnW8jYMLS3x9kjyXPgXXZqaf1HeMTTXzU8u_Dm5pfA,8447
|
|
7
7
|
spotifywebapipython/spotifyauthtoken.py,sha256=iVg2Pa5mfMqYe4qgc5H8td6JzJlaDqk4vMEhH5LmtfI,9289
|
|
8
|
-
spotifywebapipython/spotifyclient.py,sha256=
|
|
8
|
+
spotifywebapipython/spotifyclient.py,sha256=XFMj4_58ZUkMg-zjO79FhaT2g2-1GuoBpooZ1vtLwVM,900471
|
|
9
9
|
spotifywebapipython/spotifydiscovery.py,sha256=cyysxl8PQj9yGHVbaqhSF3SStlrp-NvfGAudM-dDmg0,20290
|
|
10
10
|
spotifywebapipython/spotifymediatypes.py,sha256=hMjkxhbfTtks0_P8BKmY7qg3EmB2zhH3RT0DbEpb_2s,1628
|
|
11
11
|
spotifywebapipython/spotifytypeprefixes.py,sha256=3yfpxKF7jF694qBuo-PbKYvm70YwwdBoGj9enOpWsAg,1375
|
|
12
12
|
spotifywebapipython/spotifywebapiauthenticationerror.py,sha256=5A0MKvYo3Ypv0ZeSSfLHuFLwzoUUu044bBoUgMfNXNw,3940
|
|
13
13
|
spotifywebapipython/spotifywebapierror.py,sha256=5cga9213J_nFQ0UX4vSn3dpyinASKTRiH0wAR4nLjvs,3147
|
|
14
14
|
spotifywebapipython/spotifywebplayertoken.py,sha256=axj1j1lM7COiiZfpElkJRdnk4AmE6bAQcjKshUIz1Nk,35813
|
|
15
|
-
spotifywebapipython/docs/__init__.html,sha256=
|
|
15
|
+
spotifywebapipython/docs/__init__.html,sha256=s048vIlh5VWGCNJCEgayy5lTRC0quFnO1hOI7VLNTpI,188025
|
|
16
16
|
spotifywebapipython/docs/codecopy.js,sha256=ryuoZwLIL03YitjjFzn49UO5ta7-OBos6LNA3qHhFzs,3120
|
|
17
|
-
spotifywebapipython/docs/index.html,sha256=
|
|
18
|
-
spotifywebapipython/docs/search.js,sha256=
|
|
17
|
+
spotifywebapipython/docs/index.html,sha256=5M7a40-WmxC1d4J8CNQJ7sLhXhJ2XH0BHw7rkQwms-o,48779
|
|
18
|
+
spotifywebapipython/docs/search.js,sha256=4EK8UxqIoxgewQRMUXMJdHk5ocKEJW5fvw3GucKDYQQ,9143687
|
|
19
19
|
spotifywebapipython/docs/spotifywebapipython.ico,sha256=YImj39fqqSPSuB2-sMDlUYDd6YwRfQeJRtq4FjwWglg,16410
|
|
20
20
|
spotifywebapipython/docs/spotifywebapipython_OLD.ico,sha256=YIv5LjcD4bTIJQSOr8jjwbWaeB3QkElRwkTOePiGbZo,14904
|
|
21
|
-
spotifywebapipython/docs/spotifywebapipython/const.html,sha256=
|
|
22
|
-
spotifywebapipython/docs/spotifywebapipython/saappmessages.html,sha256=
|
|
23
|
-
spotifywebapipython/docs/spotifywebapipython/sautils.html,sha256=
|
|
24
|
-
spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html,sha256=
|
|
25
|
-
spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html,sha256=
|
|
26
|
-
spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html,sha256=
|
|
27
|
-
spotifywebapipython/docs/spotifywebapipython/spotifyclient.html,sha256=
|
|
28
|
-
spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html,sha256=
|
|
29
|
-
spotifywebapipython/docs/spotifywebapipython/spotifymediatypes.html,sha256=
|
|
30
|
-
spotifywebapipython/docs/spotifywebapipython/spotifytypeprefixes.html,sha256=
|
|
31
|
-
spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html,sha256=
|
|
32
|
-
spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html,sha256=
|
|
33
|
-
spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html,sha256
|
|
21
|
+
spotifywebapipython/docs/spotifywebapipython/const.html,sha256=cgUELgvlZRSDUbPoGwM5XiP0HZRHBB9azrTU4Xc6WhE,60537
|
|
22
|
+
spotifywebapipython/docs/spotifywebapipython/saappmessages.html,sha256=nXfJsGuqRwiwtoeDy64uFoaQb9dxiQNMv6Tde4LtBgo,62358
|
|
23
|
+
spotifywebapipython/docs/spotifywebapipython/sautils.html,sha256=_XOJvMk79P-N0Ri6HULZGSKrDHMWG477hJzpcsH_owM,61063
|
|
24
|
+
spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html,sha256=tvimNZWSmRTMEiCW8nvy2RrW27bfFYPF0m9sYW947cE,48054
|
|
25
|
+
spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html,sha256=gSSI5SnGSQnLKgsyKda8IaaIGtLb86zlcUa7eFrzDvM,59210
|
|
26
|
+
spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html,sha256=olS17goY-oYI13fKoP5TLQ1B2KQb-4zKIDCqNew7MwI,59256
|
|
27
|
+
spotifywebapipython/docs/spotifywebapipython/spotifyclient.html,sha256=TlDs7PZsT9kilzE-nTn-ITuPgcdGDLg3f6Cs6b5w92Y,1667177
|
|
28
|
+
spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html,sha256=cddR1DRDow1347RalY1Eg5z-M8k9xfsw1g7c0c3jXKE,57662
|
|
29
|
+
spotifywebapipython/docs/spotifywebapipython/spotifymediatypes.html,sha256=0YaABXfShIrQvYs8lD7JvxVvja-hFyiHKMcDgkb0UVk,51532
|
|
30
|
+
spotifywebapipython/docs/spotifywebapipython/spotifytypeprefixes.html,sha256=ZSff8WavXkZX669dMslO2MG16zi_3Y7YY8za70DQLjA,52401
|
|
31
|
+
spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html,sha256=0TRd6-4yjaj6bdLO_kWYetBz_GCB9vMdoK17iFu9VR8,52174
|
|
32
|
+
spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html,sha256=UFApm7G5Qj3yv6DWsNEvEVI2C64jvnLjqJlfNtSqIp4,50592
|
|
33
|
+
spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html,sha256=3-A7BGhw-6IvmwLulIJn5E7bCmzWIlaY6VtxiNBN2pU,62204
|
|
34
34
|
spotifywebapipython/models/__init__.py,sha256=RwRQhUX-6EUs8XvStVFpR8EPwoqIAz9K6ref-28qHKI,4423
|
|
35
35
|
spotifywebapipython/models/album.py,sha256=U3Pdw0-EL33LdkeiN31fjZ23rlLk6DNGV8jRmZU7EyQ,5170
|
|
36
36
|
spotifywebapipython/models/albumpagesaved.py,sha256=SBYMhkh5ZsMrRAXl-cm9zsxMDh8gO190ENq6Py2TyGY,2417
|
|
@@ -72,15 +72,15 @@ spotifywebapipython/models/narrator.py,sha256=8gkYk8YkWX7m0ErDs9pwkWbXKkGmCMCFVP
|
|
|
72
72
|
spotifywebapipython/models/owner.py,sha256=RokGhciF6TV43svWzeqyvKClhm1YuT0jW5XTx54ZEsI,4543
|
|
73
73
|
spotifywebapipython/models/pageobject.py,sha256=KEQhaapYL-7eSxc2gHGqZnozBJs3wJ888W1wLZwRCD0,11045
|
|
74
74
|
spotifywebapipython/models/playeractions.py,sha256=GaqEBcmHev8eoCXb51xt8O9trqeOhIpIysjlKYWOBY0,6564
|
|
75
|
-
spotifywebapipython/models/playerlastplayedinfo.py,sha256=
|
|
75
|
+
spotifywebapipython/models/playerlastplayedinfo.py,sha256=BuFHRagjrrRgXnEYAxyziSHpMP4k-E3i97-SzCPutTk,13056
|
|
76
76
|
spotifywebapipython/models/playerplaystate.py,sha256=v5uzD-ck6SvMpWASKbXsAHrDC6-uhZglpszVXXLNQ3g,15231
|
|
77
77
|
spotifywebapipython/models/playerqueueinfo.py,sha256=BryoQ7UjiuUxNRQrIW7bl2_S0FaIeKwYyG1cVSZXemk,7204
|
|
78
78
|
spotifywebapipython/models/playhistory.py,sha256=GO2rM1H6O5BvKuCDKq7p7rb1vBk7JF-QoHeU9nJ_4i0,3853
|
|
79
79
|
spotifywebapipython/models/playhistorypage.py,sha256=kwBbpQ2HPURxyg6BTbAdOVeMPVGlwDVj8sxfgQGYmek,2430
|
|
80
|
-
spotifywebapipython/models/playlist.py,sha256
|
|
80
|
+
spotifywebapipython/models/playlist.py,sha256=-QxQ9ljk1ZnYiZ7ypAB3jDe2H6e8PxQWf3cRNu-0qHI,3935
|
|
81
81
|
spotifywebapipython/models/playlistpage.py,sha256=XfItVPK3MP4cEjzv8bmqboXIsSEvaZyroEuP2_7vIuM,2438
|
|
82
82
|
spotifywebapipython/models/playlistpagesimplified.py,sha256=kZZHHpaGnqNG7SMQ5B8dHAxLV-m2VLzoepIgySLNGuY,3197
|
|
83
|
-
spotifywebapipython/models/playlistsimplified.py,sha256=
|
|
83
|
+
spotifywebapipython/models/playlistsimplified.py,sha256=k4--UMBNpyGds-dBnMfQBMp1ED55d8baD2eN-eFXUFg,10571
|
|
84
84
|
spotifywebapipython/models/playlisttrack.py,sha256=0SeHgeZZRRvRCjmFg98tzTZGEO9gc5fooMVuXZp3WXw,4229
|
|
85
85
|
spotifywebapipython/models/playlisttracksummary.py,sha256=hOBNsK3y1SUMwyNrOJZbcxjtGk50_6mIibP2JTDXWSA,2088
|
|
86
86
|
spotifywebapipython/models/recommendationseed.py,sha256=uLPZZ_pERIuOXJrjmdqyfE9OwDK2RwOUyMJNlWVwE_o,4107
|
|
@@ -137,8 +137,8 @@ spotifywebapipython/zeroconfapi/zeroconfgetinfo.py,sha256=APayso_F7lCsdzzrkescgd
|
|
|
137
137
|
spotifywebapipython/zeroconfapi/zeroconfgetinfoalias.py,sha256=FZJM23HIPJSfhXIC3-EuS1XhawheoG5maSp7__k4yBo,2932
|
|
138
138
|
spotifywebapipython/zeroconfapi/zeroconfgetinfodrmmediaformat.py,sha256=c5uk8ljsIuBK3w2jahHKQuoWvm245LOjUBitetXx5Mo,2347
|
|
139
139
|
spotifywebapipython/zeroconfapi/zeroconfresponse.py,sha256=mAPIDj5MG53x8peiScrp7OJblwy_o_Sto4wqE0rGujU,6445
|
|
140
|
-
spotifywebapipython-1.0.
|
|
141
|
-
spotifywebapipython-1.0.
|
|
142
|
-
spotifywebapipython-1.0.
|
|
143
|
-
spotifywebapipython-1.0.
|
|
144
|
-
spotifywebapipython-1.0.
|
|
140
|
+
spotifywebapipython-1.0.267.dist-info/LICENSE,sha256=KGcc9g0zwqNLcWnSn_ezv1UtKyhMENFhvtixpxUPNsE,1177
|
|
141
|
+
spotifywebapipython-1.0.267.dist-info/METADATA,sha256=EN_dE0UByBc8xC8PuRQ7pm6xa9jOUybeUxILtuxDxR4,11644
|
|
142
|
+
spotifywebapipython-1.0.267.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
|
143
|
+
spotifywebapipython-1.0.267.dist-info/top_level.txt,sha256=jTBLFlijKTesYh2dteAz4vb17qjaqWKeDjpnnwTcrjs,20
|
|
144
|
+
spotifywebapipython-1.0.267.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{spotifywebapipython-1.0.265.dist-info → spotifywebapipython-1.0.267.dist-info}/top_level.txt
RENAMED
|
File without changes
|