spotifywebapiPython 1.0.35__py3-none-any.whl → 1.0.147__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.35.dist-info → spotifywebapiPython-1.0.147.dist-info}/LICENSE +1 -1
- {spotifywebapiPython-1.0.35.dist-info → spotifywebapiPython-1.0.147.dist-info}/METADATA +7 -6
- spotifywebapiPython-1.0.147.dist-info/RECORD +117 -0
- spotifywebapipython/__init__.py +2 -0
- spotifywebapipython/const.py +19 -1
- spotifywebapipython/docs/__init__.html +799 -3
- spotifywebapipython/docs/index.html +21 -3
- spotifywebapipython/docs/search.js +1 -1
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/const.html +72 -4
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/saappmessages.html +77 -3
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/sautils.html +63 -3
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/spotifyapierror.html +3 -3
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/spotifyapimessage.html +20 -3
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/spotifyauthtoken.html +39 -3
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/spotifyclient.html +2553 -364
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/spotifydiscovery.html +85 -52
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/spotifywebapiauthenticationerror.html +3 -3
- spotifywebapipython/docs/{spotifywebapiPython → spotifywebapipython}/spotifywebapierror.html +3 -3
- spotifywebapipython/models/__init__.py +8 -0
- spotifywebapipython/models/albumpagesaved.py +2 -1
- spotifywebapipython/models/albumpagesimplified.py +2 -1
- spotifywebapipython/models/albumsimplified.py +4 -5
- spotifywebapipython/models/artist.py +4 -5
- spotifywebapipython/models/artistinfo.py +282 -0
- spotifywebapipython/models/artistinfotourevent.py +127 -0
- spotifywebapipython/models/artistpage.py +2 -1
- spotifywebapipython/models/artistsimplified.py +4 -0
- spotifywebapipython/models/audiobookpagesimplified.py +2 -1
- spotifywebapipython/models/audiobooksimplified.py +4 -5
- spotifywebapipython/models/category.py +16 -0
- spotifywebapipython/models/categorypage.py +2 -1
- spotifywebapipython/models/chapterpagesimplified.py +2 -1
- spotifywebapipython/models/chaptersimplified.py +6 -7
- spotifywebapipython/models/context.py +1 -3
- spotifywebapipython/models/device.py +85 -2
- spotifywebapipython/models/episodepagesaved.py +2 -1
- spotifywebapipython/models/episodepagesimplified.py +2 -1
- spotifywebapipython/models/episodesaved.py +2 -2
- spotifywebapipython/models/episodesimplified.py +5 -6
- spotifywebapipython/models/imageobject.py +98 -0
- spotifywebapipython/models/pageobject.py +29 -4
- spotifywebapipython/models/playeractions.py +33 -11
- spotifywebapipython/models/playerplaystate.py +128 -13
- spotifywebapipython/models/playerqueueinfo.py +61 -4
- spotifywebapipython/models/playhistorypage.py +2 -1
- spotifywebapipython/models/playlist.py +6 -3
- spotifywebapipython/models/playlistpage.py +2 -1
- spotifywebapipython/models/playlistpagesimplified.py +2 -1
- spotifywebapipython/models/playlistsimplified.py +49 -7
- spotifywebapipython/models/playlisttrack.py +1 -0
- spotifywebapipython/models/playlisttracksummary.py +3 -1
- spotifywebapipython/models/searchresponse.py +1 -1
- spotifywebapipython/models/showpagesaved.py +2 -1
- spotifywebapipython/models/showpagesimplified.py +2 -1
- spotifywebapipython/models/showsaved.py +2 -2
- spotifywebapipython/models/showsimplified.py +8 -5
- spotifywebapipython/models/spotifyconnectdevice.py +188 -0
- spotifywebapipython/models/spotifyconnectdevices.py +628 -0
- spotifywebapipython/models/track.py +2 -1
- spotifywebapipython/models/trackpage.py +42 -1
- spotifywebapipython/models/trackpagesaved.py +2 -1
- spotifywebapipython/models/trackpagesimplified.py +2 -1
- spotifywebapipython/models/trackrecommendations.py +5 -5
- spotifywebapipython/models/tracksimplified.py +10 -3
- spotifywebapipython/models/userprofile.py +25 -1
- spotifywebapipython/models/userprofilesimplified.py +4 -5
- spotifywebapipython/models/zeroconfdiscoveryresult.py +599 -0
- spotifywebapipython/models/zeroconfproperty.py +93 -0
- spotifywebapipython/oauthcli/authclient.py +119 -19
- spotifywebapipython/saappmessages.py +21 -1
- spotifywebapipython/sautils.py +88 -1
- spotifywebapipython/spotifyapimessage.py +18 -1
- spotifywebapipython/spotifyauthtoken.py +26 -0
- spotifywebapipython/spotifyclient.py +4311 -525
- spotifywebapipython/spotifyconnectdeviceeventargs.py +67 -0
- spotifywebapipython/spotifydiscovery.py +326 -136
- spotifywebapipython/zeroconfapi/__init__.py +23 -0
- spotifywebapipython/zeroconfapi/authenticationtypes.py +38 -0
- spotifywebapipython/zeroconfapi/blobbuilder.py +370 -0
- spotifywebapipython/zeroconfapi/credentials.py +37 -0
- spotifywebapipython/zeroconfapi/cryptodiffiehellman.py +89 -0
- spotifywebapipython/zeroconfapi/helpers.py +64 -0
- spotifywebapipython/zeroconfapi/spotifyzeroconfapierror.py +108 -0
- spotifywebapipython/zeroconfapi/zeroconfconnect.py +1315 -0
- spotifywebapipython/zeroconfapi/zeroconfgetinfo.py +619 -0
- spotifywebapipython/zeroconfapi/zeroconfgetinfoalias.py +105 -0
- spotifywebapipython/zeroconfapi/zeroconfgetinfodrmmediaformat.py +90 -0
- spotifywebapipython/zeroconfapi/zeroconfresponse.py +141 -0
- spotifywebapiPython-1.0.35.dist-info/RECORD +0 -98
- {spotifywebapiPython-1.0.35.dist-info → spotifywebapiPython-1.0.147.dist-info}/WHEEL +0 -0
- {spotifywebapiPython-1.0.35.dist-info → spotifywebapiPython-1.0.147.dist-info}/top_level.txt +0 -0
|
@@ -28,6 +28,7 @@ class PlayerPlayState:
|
|
|
28
28
|
"""
|
|
29
29
|
self._Actions:PlayerActions = None
|
|
30
30
|
self._Context:Context = None
|
|
31
|
+
self._ItemType:str = None
|
|
31
32
|
self._CurrentlyPlayingType:str = None
|
|
32
33
|
self._Device:Device = None
|
|
33
34
|
self._Item:object = None
|
|
@@ -37,6 +38,9 @@ class PlayerPlayState:
|
|
|
37
38
|
self._ShuffleState:bool = None
|
|
38
39
|
self._SmartShuffle:bool = None
|
|
39
40
|
self._Timestamp:int = None
|
|
41
|
+
|
|
42
|
+
# helper properties, not part of the Spotify Web API interface.
|
|
43
|
+
self._IsEmpty:bool = True
|
|
40
44
|
|
|
41
45
|
if (root is None):
|
|
42
46
|
|
|
@@ -55,7 +59,9 @@ class PlayerPlayState:
|
|
|
55
59
|
# process all collections and objects.
|
|
56
60
|
item:dict = root.get('actions',None)
|
|
57
61
|
if item is not None:
|
|
58
|
-
|
|
62
|
+
disallows:dict = item.get('disallows')
|
|
63
|
+
if disallows is not None:
|
|
64
|
+
self._Actions = PlayerActions(root=disallows)
|
|
59
65
|
|
|
60
66
|
item:dict = root.get('context',None)
|
|
61
67
|
if item is not None:
|
|
@@ -72,7 +78,31 @@ class PlayerPlayState:
|
|
|
72
78
|
elif self._CurrentlyPlayingType == 'episode':
|
|
73
79
|
self._Item = Episode(root=item)
|
|
74
80
|
|
|
75
|
-
|
|
81
|
+
# if root contains keys, then assume it is NOT empty.
|
|
82
|
+
if (len(root) > 0):
|
|
83
|
+
self._IsEmpty = False
|
|
84
|
+
|
|
85
|
+
# post load validations.
|
|
86
|
+
if self._Actions is None:
|
|
87
|
+
self._Actions = PlayerActions()
|
|
88
|
+
if self._Device is None:
|
|
89
|
+
self._Device = Device()
|
|
90
|
+
if self._CurrentlyPlayingType is None:
|
|
91
|
+
self._CurrentlyPlayingType = 'unknown'
|
|
92
|
+
if self._IsPlaying is None:
|
|
93
|
+
self._IsPlaying = False
|
|
94
|
+
if self._ProgressMS is None:
|
|
95
|
+
self._ProgressMS = 0
|
|
96
|
+
if self._RepeatState is None:
|
|
97
|
+
self._RepeatState = 'off'
|
|
98
|
+
if self._ShuffleState is None:
|
|
99
|
+
self._ShuffleState = False
|
|
100
|
+
if self._SmartShuffle is None:
|
|
101
|
+
self._SmartShuffle = False
|
|
102
|
+
if self._Timestamp is None:
|
|
103
|
+
self._Timestamp = 0
|
|
104
|
+
|
|
105
|
+
|
|
76
106
|
def __repr__(self) -> str:
|
|
77
107
|
return self.ToString()
|
|
78
108
|
|
|
@@ -126,6 +156,27 @@ class PlayerPlayState:
|
|
|
126
156
|
return self._Item
|
|
127
157
|
|
|
128
158
|
|
|
159
|
+
@property
|
|
160
|
+
def ItemType(self) -> str:
|
|
161
|
+
"""
|
|
162
|
+
The type of the currently playing episode; can be null.
|
|
163
|
+
This value will be null if the `Item` property value is null.
|
|
164
|
+
|
|
165
|
+
If not null, it can be one of `audiobook` or `podcast`.
|
|
166
|
+
|
|
167
|
+
Note that this is not a Spotify Web API property; it is loaded from our API so
|
|
168
|
+
that the type of episode can be determined programatically (e.g. audiobook or podcast).
|
|
169
|
+
"""
|
|
170
|
+
return self._ItemType
|
|
171
|
+
|
|
172
|
+
@ItemType.setter
|
|
173
|
+
def ItemType(self, value:str):
|
|
174
|
+
"""
|
|
175
|
+
Sets the ItemType property value.
|
|
176
|
+
"""
|
|
177
|
+
self._ItemType = value
|
|
178
|
+
|
|
179
|
+
|
|
129
180
|
@property
|
|
130
181
|
def IsAdvertisement(self) -> bool:
|
|
131
182
|
"""
|
|
@@ -136,6 +187,39 @@ class PlayerPlayState:
|
|
|
136
187
|
return False
|
|
137
188
|
|
|
138
189
|
|
|
190
|
+
@property
|
|
191
|
+
def IsEmpty(self) -> bool:
|
|
192
|
+
"""
|
|
193
|
+
True if Spotify playstate returned an empty response; otherwise, false.
|
|
194
|
+
|
|
195
|
+
Note that for Sonos devices, the Spotify Web API reports an empty playstate since
|
|
196
|
+
the SoCo API is actually controlling player.
|
|
197
|
+
|
|
198
|
+
This is a helper property, and is not part of the Spotify Web API specification.
|
|
199
|
+
"""
|
|
200
|
+
return self._IsEmpty
|
|
201
|
+
|
|
202
|
+
@IsEmpty.setter
|
|
203
|
+
def IsEmpty(self, value:bool):
|
|
204
|
+
"""
|
|
205
|
+
Sets the IsEmpty property value.
|
|
206
|
+
"""
|
|
207
|
+
if isinstance(value, bool):
|
|
208
|
+
self._IsEmpty = value
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@property
|
|
212
|
+
def IsMuted(self) -> bool:
|
|
213
|
+
"""
|
|
214
|
+
True if the player device volume is zero (muted) OR there is no device;
|
|
215
|
+
otherwise, false.
|
|
216
|
+
"""
|
|
217
|
+
if self._Device is None:
|
|
218
|
+
return True
|
|
219
|
+
else:
|
|
220
|
+
return self._Device.IsMuted
|
|
221
|
+
|
|
222
|
+
|
|
139
223
|
@property
|
|
140
224
|
def IsPlaying(self) -> bool:
|
|
141
225
|
"""
|
|
@@ -148,7 +232,7 @@ class PlayerPlayState:
|
|
|
148
232
|
"""
|
|
149
233
|
Sets the IsPlaying property value.
|
|
150
234
|
"""
|
|
151
|
-
if
|
|
235
|
+
if isinstance(value, bool):
|
|
152
236
|
self._IsPlaying = value
|
|
153
237
|
|
|
154
238
|
|
|
@@ -159,9 +243,9 @@ class PlayerPlayState:
|
|
|
159
243
|
|
|
160
244
|
The `RepeatState` property contains the actual repeat setting.
|
|
161
245
|
"""
|
|
162
|
-
if self._RepeatState
|
|
163
|
-
return
|
|
164
|
-
return
|
|
246
|
+
if self._RepeatState != 'off':
|
|
247
|
+
return True
|
|
248
|
+
return False
|
|
165
249
|
|
|
166
250
|
|
|
167
251
|
@property
|
|
@@ -169,9 +253,19 @@ class PlayerPlayState:
|
|
|
169
253
|
"""
|
|
170
254
|
True if shuffle play is enabled; otherwise, False.
|
|
171
255
|
"""
|
|
172
|
-
if self.ShuffleState
|
|
173
|
-
return
|
|
174
|
-
return
|
|
256
|
+
if (self.ShuffleState == 'on') or (self.ShuffleState == True):
|
|
257
|
+
return True
|
|
258
|
+
return False
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
@property
|
|
262
|
+
def IsSmartShuffleEnabled(self) -> bool:
|
|
263
|
+
"""
|
|
264
|
+
True if smart shuffle play is enabled; otherwise, False.
|
|
265
|
+
"""
|
|
266
|
+
if (self.SmartShuffle == 'on' or self.SmartShuffle == True):
|
|
267
|
+
return True
|
|
268
|
+
return False
|
|
175
269
|
|
|
176
270
|
|
|
177
271
|
@property
|
|
@@ -181,6 +275,14 @@ class PlayerPlayState:
|
|
|
181
275
|
"""
|
|
182
276
|
return self._ProgressMS
|
|
183
277
|
|
|
278
|
+
@ProgressMS.setter
|
|
279
|
+
def ProgressMS(self, value:int):
|
|
280
|
+
"""
|
|
281
|
+
Sets the ProgressMS property value.
|
|
282
|
+
"""
|
|
283
|
+
if isinstance(value, int):
|
|
284
|
+
self._ProgressMS = value
|
|
285
|
+
|
|
184
286
|
|
|
185
287
|
@property
|
|
186
288
|
def RepeatState(self) -> str:
|
|
@@ -191,17 +293,17 @@ class PlayerPlayState:
|
|
|
191
293
|
|
|
192
294
|
|
|
193
295
|
@property
|
|
194
|
-
def ShuffleState(self) ->
|
|
296
|
+
def ShuffleState(self) -> bool:
|
|
195
297
|
"""
|
|
196
|
-
If shuffle is
|
|
298
|
+
If shuffle is enabled, True or False.
|
|
197
299
|
"""
|
|
198
300
|
return self._ShuffleState
|
|
199
301
|
|
|
200
302
|
|
|
201
303
|
@property
|
|
202
|
-
def SmartShuffle(self) ->
|
|
304
|
+
def SmartShuffle(self) -> bool:
|
|
203
305
|
"""
|
|
204
|
-
If smart shuffle is
|
|
306
|
+
If smart shuffle is enabled, True or False.
|
|
205
307
|
"""
|
|
206
308
|
return self._SmartShuffle
|
|
207
309
|
|
|
@@ -237,6 +339,14 @@ class PlayerPlayState:
|
|
|
237
339
|
"""
|
|
238
340
|
return self._Timestamp
|
|
239
341
|
|
|
342
|
+
@Timestamp.setter
|
|
343
|
+
def Timestamp(self, value:int):
|
|
344
|
+
"""
|
|
345
|
+
Sets the Timestamp property value.
|
|
346
|
+
"""
|
|
347
|
+
if isinstance(value, int):
|
|
348
|
+
self._Timestamp = value
|
|
349
|
+
|
|
240
350
|
|
|
241
351
|
def ToDictionary(self) -> dict:
|
|
242
352
|
"""
|
|
@@ -260,6 +370,7 @@ class PlayerPlayState:
|
|
|
260
370
|
|
|
261
371
|
result:dict = \
|
|
262
372
|
{
|
|
373
|
+
'is_empty': self._IsEmpty,
|
|
263
374
|
'actions': actions,
|
|
264
375
|
'context': context,
|
|
265
376
|
'currently_playing_type': self._CurrentlyPlayingType,
|
|
@@ -270,6 +381,7 @@ class PlayerPlayState:
|
|
|
270
381
|
'shuffle_state': self._ShuffleState,
|
|
271
382
|
'smart_shuffle': self._SmartShuffle,
|
|
272
383
|
'timestamp': self._Timestamp,
|
|
384
|
+
'item_type': self._ItemType,
|
|
273
385
|
'item': item,
|
|
274
386
|
}
|
|
275
387
|
return result
|
|
@@ -282,13 +394,16 @@ class PlayerPlayState:
|
|
|
282
394
|
msg:str = 'PlayerPlayState:'
|
|
283
395
|
#if self._Actions is not None: msg = '%s\n %s' % (msg, str(self._Actions))
|
|
284
396
|
if self._CurrentlyPlayingType is not None: msg = '%s\n CurrentlyPlayingType="%s"' % (msg, str(self._CurrentlyPlayingType))
|
|
397
|
+
if self._ItemType is not None: msg = '%s\n ItemType="%s"' % (msg, str(self._ItemType))
|
|
285
398
|
if self._Device is not None: msg = '%s\n Device Name="%s"' % (msg, str(self._Device.Name))
|
|
286
399
|
#if self._Context is not None: msg = '%s\n %s' % (msg, str(self._Context))
|
|
287
400
|
#if self._Item is not None: msg = '%s\n %s' % (msg, str(self._Item))
|
|
401
|
+
if self.IsMuted is not None: msg = '%s\n IsMuted="%s"' % (msg, str(self.IsMuted))
|
|
288
402
|
if self._IsPlaying is not None: msg = '%s\n IsPlaying="%s"' % (msg, str(self._IsPlaying))
|
|
289
403
|
if self._ProgressMS is not None: msg = '%s\n ProgressMS="%s"' % (msg, str(self._ProgressMS))
|
|
290
404
|
if self._RepeatState is not None: msg = '%s\n RepeatState="%s"' % (msg, str(self._RepeatState))
|
|
291
405
|
if self._ShuffleState is not None: msg = '%s\n ShuffleState="%s"' % (msg, str(self._ShuffleState))
|
|
292
406
|
if self._SmartShuffle is not None: msg = '%s\n SmartShuffle="%s"' % (msg, str(self._SmartShuffle))
|
|
293
407
|
if self._Timestamp is not None: msg = '%s\n Timestamp="%s"' % (msg, str(self._Timestamp))
|
|
408
|
+
msg = '%s\n IsEmpty="%s"' % (msg, str(self.IsEmpty))
|
|
294
409
|
return msg
|
|
@@ -24,6 +24,7 @@ class PlayerQueueInfo:
|
|
|
24
24
|
"""
|
|
25
25
|
self._CurrentlyPlaying:object = None
|
|
26
26
|
self._CurrentlyPlayingType:str = None
|
|
27
|
+
self._DateLastRefreshed:float = 0
|
|
27
28
|
self._Queue:list[object] = []
|
|
28
29
|
|
|
29
30
|
if (root is None):
|
|
@@ -42,15 +43,25 @@ class PlayerQueueInfo:
|
|
|
42
43
|
elif self._CurrentlyPlayingType == 'episode':
|
|
43
44
|
self._CurrentlyPlaying = Episode(root=item)
|
|
44
45
|
|
|
46
|
+
# for some reason, the Spotify Web API will return up to 10 duplicate items
|
|
47
|
+
# with the same information! for example:
|
|
48
|
+
# - if there is only 1 item in the queue, then 10 duplicate items are returned by the Spotify Web API.
|
|
49
|
+
# - if there are 5 items in the queue, then 5 duplicate items are returned by the Spotify Web API.
|
|
50
|
+
# we will check for this scenario, and only return non-duplicate items if so.
|
|
45
51
|
items:list = root.get('queue',None)
|
|
46
52
|
if items is not None:
|
|
47
53
|
for item in items:
|
|
54
|
+
|
|
48
55
|
itemType = item.get('type','unknown')
|
|
49
56
|
if itemType == 'track':
|
|
50
|
-
|
|
57
|
+
track:Track = Track(root=item)
|
|
58
|
+
if (track) and (not self.ContainsUri(track.Uri)):
|
|
59
|
+
self._Queue.append(track)
|
|
51
60
|
elif itemType == 'episode':
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
episode:Episode = Episode(root=item)
|
|
62
|
+
if (episode) and (not self.ContainsUri(episode.Uri)):
|
|
63
|
+
self._Queue.append(episode)
|
|
64
|
+
|
|
54
65
|
|
|
55
66
|
def __repr__(self) -> str:
|
|
56
67
|
return self.ToString()
|
|
@@ -78,6 +89,30 @@ class PlayerQueueInfo:
|
|
|
78
89
|
return self._CurrentlyPlayingType
|
|
79
90
|
|
|
80
91
|
|
|
92
|
+
@property
|
|
93
|
+
def DateLastRefreshed(self) -> float:
|
|
94
|
+
"""
|
|
95
|
+
Date and time items were was last refreshed, in unix epoch format (e.g. 1669123919.331225).
|
|
96
|
+
A value of zero indicates the date was unknown.
|
|
97
|
+
|
|
98
|
+
Note that this attribute does not exist in the Spotify Web API;
|
|
99
|
+
it was added here for convenience.
|
|
100
|
+
"""
|
|
101
|
+
return self._DateLastRefreshed
|
|
102
|
+
|
|
103
|
+
@DateLastRefreshed.setter
|
|
104
|
+
def DateLastRefreshed(self, value:float):
|
|
105
|
+
"""
|
|
106
|
+
Sets the DateLastRefreshed property value.
|
|
107
|
+
"""
|
|
108
|
+
if (value is None):
|
|
109
|
+
self._DateLastRefreshed = 0
|
|
110
|
+
elif isinstance(value, float):
|
|
111
|
+
self._DateLastRefreshed = value
|
|
112
|
+
elif isinstance(value, int):
|
|
113
|
+
self._DateLastRefreshed = float(value)
|
|
114
|
+
|
|
115
|
+
|
|
81
116
|
@property
|
|
82
117
|
def Queue(self) -> list[object]:
|
|
83
118
|
"""
|
|
@@ -122,6 +157,26 @@ class PlayerQueueInfo:
|
|
|
122
157
|
return result
|
|
123
158
|
|
|
124
159
|
|
|
160
|
+
def ContainsUri(self, uri:str) -> bool:
|
|
161
|
+
"""
|
|
162
|
+
Checks the `Queue` collection to see if an item already exists with the
|
|
163
|
+
specified Uri value.
|
|
164
|
+
|
|
165
|
+
Returns True if the specified Uri value exists in the collection; otherwise, False.
|
|
166
|
+
"""
|
|
167
|
+
result:bool = False
|
|
168
|
+
|
|
169
|
+
if (uri is None):
|
|
170
|
+
return result
|
|
171
|
+
|
|
172
|
+
for item in self._Queue:
|
|
173
|
+
if item.Uri == uri:
|
|
174
|
+
result = True
|
|
175
|
+
break
|
|
176
|
+
|
|
177
|
+
return result
|
|
178
|
+
|
|
179
|
+
|
|
125
180
|
def ToDictionary(self) -> dict:
|
|
126
181
|
"""
|
|
127
182
|
Returns a dictionary representation of the class.
|
|
@@ -132,8 +187,9 @@ class PlayerQueueInfo:
|
|
|
132
187
|
|
|
133
188
|
result:dict = \
|
|
134
189
|
{
|
|
135
|
-
'
|
|
190
|
+
'date_last_refreshed': self._DateLastRefreshed,
|
|
136
191
|
'currently_playing_type': self._CurrentlyPlayingType,
|
|
192
|
+
'currently_playing': currentlyPlaying,
|
|
137
193
|
'queue': [ item.ToDictionary() for item in self._Queue ],
|
|
138
194
|
}
|
|
139
195
|
return result
|
|
@@ -146,4 +202,5 @@ class PlayerQueueInfo:
|
|
|
146
202
|
msg:str = 'PlayerQueueInfo:'
|
|
147
203
|
if self._CurrentlyPlayingType is not None: msg = '%s\n CurrentlyPlayingType="%s"' % (msg, str(self._CurrentlyPlayingType))
|
|
148
204
|
if self.QueueCount is not None: msg = '%s\n QueueCount="%s"' % (msg, str(self.QueueCount))
|
|
205
|
+
msg = '%s\n DateLastRefreshed=%s' % (msg, str(self._DateLastRefreshed))
|
|
149
206
|
return msg
|
|
@@ -39,7 +39,8 @@ class PlayHistoryPage(PageObject):
|
|
|
39
39
|
items:list = root.get('items',None)
|
|
40
40
|
if items is not None:
|
|
41
41
|
for item in items:
|
|
42
|
-
|
|
42
|
+
if item is not None:
|
|
43
|
+
self._Items.append(PlayHistory(root=item))
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
def __repr__(self) -> str:
|
|
@@ -31,7 +31,10 @@ class Playlist(PlaylistSimplified):
|
|
|
31
31
|
|
|
32
32
|
if (root is None):
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
# if not building the class from json response, then initialize various properties as
|
|
35
|
+
# the playlist is probably being built manually.
|
|
36
|
+
self._Followers = Followers()
|
|
37
|
+
self._Tracks = PlaylistPage()
|
|
35
38
|
|
|
36
39
|
else:
|
|
37
40
|
|
|
@@ -73,9 +76,9 @@ class Playlist(PlaylistSimplified):
|
|
|
73
76
|
|
|
74
77
|
def GetTracks(self) -> list[Track]:
|
|
75
78
|
"""
|
|
76
|
-
Gets a list of all tracks contained in the underlying `Items` list.
|
|
79
|
+
Gets a list of all tracks contained in the underlying `Tracks.Items` list.
|
|
77
80
|
|
|
78
|
-
This is a convenience method so one does not have to loop through the `Items`
|
|
81
|
+
This is a convenience method so one does not have to loop through the `Tracks.Items`
|
|
79
82
|
array of PlaylistPage objects to get the list of tracks.
|
|
80
83
|
"""
|
|
81
84
|
result:list[Track] = []
|
|
@@ -39,7 +39,8 @@ class PlaylistPage(PageObject):
|
|
|
39
39
|
items:list = root.get('items',None)
|
|
40
40
|
if items is not None:
|
|
41
41
|
for item in items:
|
|
42
|
-
|
|
42
|
+
if item is not None:
|
|
43
|
+
self._Items.append(PlaylistTrack(root=item))
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
def __repr__(self) -> str:
|
|
@@ -38,7 +38,8 @@ class PlaylistPageSimplified(PageObject):
|
|
|
38
38
|
items:list = root.get('items',None)
|
|
39
39
|
if items is not None:
|
|
40
40
|
for item in items:
|
|
41
|
-
|
|
41
|
+
if item is not None:
|
|
42
|
+
self._Items.append(PlaylistSimplified(root=item))
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
def __repr__(self) -> str:
|
|
@@ -38,7 +38,10 @@ class PlaylistSimplified:
|
|
|
38
38
|
|
|
39
39
|
if (root is None):
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
# if not building the class from json response, then initialize various properties as
|
|
42
|
+
# the playlist is probably being built manually.
|
|
43
|
+
self._ExternalUrls = ExternalUrls()
|
|
44
|
+
self._Tracks = PlaylistTrackSummary()
|
|
42
45
|
|
|
43
46
|
else:
|
|
44
47
|
|
|
@@ -116,6 +119,14 @@ class PlaylistSimplified:
|
|
|
116
119
|
Only returned for modified, verified playlists; otherwise null.
|
|
117
120
|
"""
|
|
118
121
|
return self._Description
|
|
122
|
+
|
|
123
|
+
@Description.setter
|
|
124
|
+
def Description(self, value:str):
|
|
125
|
+
"""
|
|
126
|
+
Sets the Description property value.
|
|
127
|
+
"""
|
|
128
|
+
if isinstance(value, str):
|
|
129
|
+
self._Description = value
|
|
119
130
|
|
|
120
131
|
|
|
121
132
|
@property
|
|
@@ -137,12 +148,20 @@ class PlaylistSimplified:
|
|
|
137
148
|
@property
|
|
138
149
|
def Id(self) -> str:
|
|
139
150
|
"""
|
|
140
|
-
The Spotify
|
|
151
|
+
The Spotify ID for the playlist.
|
|
141
152
|
|
|
142
153
|
Example: `5v5ETK9WFXAnGQ3MRubKuE`
|
|
143
154
|
"""
|
|
144
155
|
return self._Id
|
|
145
156
|
|
|
157
|
+
@Id.setter
|
|
158
|
+
def Id(self, value:str):
|
|
159
|
+
"""
|
|
160
|
+
Sets the Id property value.
|
|
161
|
+
"""
|
|
162
|
+
if isinstance(value, str):
|
|
163
|
+
self._Id = value
|
|
164
|
+
|
|
146
165
|
|
|
147
166
|
@property
|
|
148
167
|
def Images(self) -> list[ImageObject]:
|
|
@@ -159,12 +178,10 @@ class PlaylistSimplified:
|
|
|
159
178
|
@property
|
|
160
179
|
def ImageUrl(self) -> str:
|
|
161
180
|
"""
|
|
162
|
-
|
|
163
|
-
otherwise, null.
|
|
181
|
+
Returns the highest resolution order image from the `Images` list, if images
|
|
182
|
+
are defined; otherwise, null.
|
|
164
183
|
"""
|
|
165
|
-
|
|
166
|
-
return self._Images[0].Url
|
|
167
|
-
return None
|
|
184
|
+
return ImageObject.GetImageHighestResolution(self._Images)
|
|
168
185
|
|
|
169
186
|
|
|
170
187
|
@property
|
|
@@ -174,6 +191,14 @@ class PlaylistSimplified:
|
|
|
174
191
|
"""
|
|
175
192
|
return self._Name
|
|
176
193
|
|
|
194
|
+
@Name.setter
|
|
195
|
+
def Name(self, value:str):
|
|
196
|
+
"""
|
|
197
|
+
Sets the Name property value.
|
|
198
|
+
"""
|
|
199
|
+
if isinstance(value, str):
|
|
200
|
+
self._Name = value
|
|
201
|
+
|
|
177
202
|
|
|
178
203
|
@property
|
|
179
204
|
def Owner(self) -> Owner:
|
|
@@ -219,6 +244,14 @@ class PlaylistSimplified:
|
|
|
219
244
|
"""
|
|
220
245
|
return self._Type
|
|
221
246
|
|
|
247
|
+
@Type.setter
|
|
248
|
+
def Type(self, value:str):
|
|
249
|
+
"""
|
|
250
|
+
Sets the Type property value.
|
|
251
|
+
"""
|
|
252
|
+
if isinstance(value, str):
|
|
253
|
+
self._Type = value
|
|
254
|
+
|
|
222
255
|
|
|
223
256
|
@property
|
|
224
257
|
def Uri(self) -> str:
|
|
@@ -229,6 +262,14 @@ class PlaylistSimplified:
|
|
|
229
262
|
"""
|
|
230
263
|
return self._Uri
|
|
231
264
|
|
|
265
|
+
@Uri.setter
|
|
266
|
+
def Uri(self, value:str):
|
|
267
|
+
"""
|
|
268
|
+
Sets the Uri property value.
|
|
269
|
+
"""
|
|
270
|
+
if isinstance(value, str):
|
|
271
|
+
self._Uri = value
|
|
272
|
+
|
|
232
273
|
|
|
233
274
|
def ToDictionary(self) -> dict:
|
|
234
275
|
"""
|
|
@@ -253,6 +294,7 @@ class PlaylistSimplified:
|
|
|
253
294
|
'external_urls': externalUrls,
|
|
254
295
|
'href': self._Href,
|
|
255
296
|
'id': self._Id,
|
|
297
|
+
'image_url': self.ImageUrl,
|
|
256
298
|
'images': [ item.ToDictionary() for item in self._Images ],
|
|
257
299
|
'name': self._Name,
|
|
258
300
|
'owner': owner,
|
|
@@ -39,7 +39,8 @@ class ShowPageSaved(PageObject):
|
|
|
39
39
|
items:list = root.get('items',None)
|
|
40
40
|
if items is not None:
|
|
41
41
|
for item in items:
|
|
42
|
-
|
|
42
|
+
if item is not None:
|
|
43
|
+
self._Items.append(ShowSaved(root=item))
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
def __repr__(self) -> str:
|
|
@@ -38,7 +38,8 @@ class ShowPageSimplified(PageObject):
|
|
|
38
38
|
items:list = root.get('items',None)
|
|
39
39
|
if items is not None:
|
|
40
40
|
for item in items:
|
|
41
|
-
|
|
41
|
+
if item is not None:
|
|
42
|
+
self._Items.append(ShowSimplified(root=item))
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
def __repr__(self) -> str:
|
|
@@ -51,8 +51,8 @@ class ShowSaved:
|
|
|
51
51
|
|
|
52
52
|
Timestamps are returned in ISO 8601 format as Coordinated Universal Time (UTC) with a zero
|
|
53
53
|
offset: YYYY-MM-DDTHH:MM:SSZ. If the time is imprecise (for example, the date/time of an
|
|
54
|
-
|
|
55
|
-
in an
|
|
54
|
+
episode release), an additional field indicates the precision; see for example, release_date
|
|
55
|
+
in an episode object.
|
|
56
56
|
"""
|
|
57
57
|
return self._AddedAt
|
|
58
58
|
|
|
@@ -130,7 +130,7 @@ class ShowSimplified:
|
|
|
130
130
|
@property
|
|
131
131
|
def Explicit(self) -> bool:
|
|
132
132
|
"""
|
|
133
|
-
Whether or not the show has explicit
|
|
133
|
+
Whether or not the show has explicit content (true = yes it does; false = no it does not OR unknown).
|
|
134
134
|
"""
|
|
135
135
|
return self._Explicit
|
|
136
136
|
|
|
@@ -147,6 +147,7 @@ class ShowSimplified:
|
|
|
147
147
|
def Href(self) -> str:
|
|
148
148
|
"""
|
|
149
149
|
A link to the Web API endpoint providing full details of the show.
|
|
150
|
+
Example: `https://api.spotify.com/v1/shows/3IM0lmZxpFAY7CwMuv9H4g?locale=en-US%2Cen%3Bq%3D0.9`
|
|
150
151
|
"""
|
|
151
152
|
return self._Href
|
|
152
153
|
|
|
@@ -164,6 +165,7 @@ class ShowSimplified:
|
|
|
164
165
|
def Id(self) -> str:
|
|
165
166
|
"""
|
|
166
167
|
The Spotify ID for the show.
|
|
168
|
+
Example: `3IM0lmZxpFAY7CwMuv9H4g`
|
|
167
169
|
"""
|
|
168
170
|
return self._Id
|
|
169
171
|
|
|
@@ -182,10 +184,8 @@ class ShowSimplified:
|
|
|
182
184
|
Gets the first image url in the `Images` list, if images are defined;
|
|
183
185
|
otherwise, null.
|
|
184
186
|
"""
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return None
|
|
188
|
-
|
|
187
|
+
return ImageObject.GetImageHighestResolution(self._Images)
|
|
188
|
+
|
|
189
189
|
|
|
190
190
|
@property
|
|
191
191
|
def IsExternallyHosted(self) -> bool:
|
|
@@ -210,6 +210,8 @@ class ShowSimplified:
|
|
|
210
210
|
def MediaType(self) -> str:
|
|
211
211
|
"""
|
|
212
212
|
The media type of the show.
|
|
213
|
+
|
|
214
|
+
Example: `audio`
|
|
213
215
|
"""
|
|
214
216
|
return self._MediaType
|
|
215
217
|
|
|
@@ -272,6 +274,7 @@ class ShowSimplified:
|
|
|
272
274
|
'href': self._Href,
|
|
273
275
|
'html_description': self._HtmlDescription,
|
|
274
276
|
'id': self._Id,
|
|
277
|
+
'image_url': self.ImageUrl,
|
|
275
278
|
'images': [ item.ToDictionary() for item in self._Images ],
|
|
276
279
|
'is_externally_hosted': self._IsExternallyHosted,
|
|
277
280
|
'languages': [ item for item in self._Languages ],
|