spotifywebapiPython 1.0.242__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/__init__.py +35 -0
- spotifywebapipython/const.py +114 -0
- spotifywebapipython/docs/__init__.html +2156 -0
- spotifywebapipython/docs/codecopy.js +70 -0
- spotifywebapipython/docs/index.html +514 -0
- spotifywebapipython/docs/search.js +46 -0
- spotifywebapipython/docs/spotifywebapipython/const.html +636 -0
- spotifywebapipython/docs/spotifywebapipython/saappmessages.html +540 -0
- spotifywebapipython/docs/spotifywebapipython/sautils.html +620 -0
- spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html +341 -0
- spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html +598 -0
- spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html +612 -0
- spotifywebapipython/docs/spotifywebapipython/spotifyclient.html +16557 -0
- spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html +518 -0
- spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html +421 -0
- spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html +400 -0
- spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html +635 -0
- spotifywebapipython/docs/spotifywebapipython.ico +0 -0
- spotifywebapipython/docs/spotifywebapipython_OLD.ico +0 -0
- spotifywebapipython/models/__init__.py +121 -0
- spotifywebapipython/models/album.py +170 -0
- spotifywebapipython/models/albumpagesaved.py +85 -0
- spotifywebapipython/models/albumpagesimplified.py +88 -0
- spotifywebapipython/models/albumsaved.py +102 -0
- spotifywebapipython/models/albumsimplified.py +308 -0
- spotifywebapipython/models/artist.py +146 -0
- spotifywebapipython/models/artistinfo.py +282 -0
- spotifywebapipython/models/artistinfotourevent.py +127 -0
- spotifywebapipython/models/artistpage.py +70 -0
- spotifywebapipython/models/artistsimplified.py +163 -0
- spotifywebapipython/models/audiobook.py +87 -0
- spotifywebapipython/models/audiobookpagesimplified.py +88 -0
- spotifywebapipython/models/audiobooksimplified.py +362 -0
- spotifywebapipython/models/audiofeatures.py +333 -0
- spotifywebapipython/models/author.py +67 -0
- spotifywebapipython/models/category.py +168 -0
- spotifywebapipython/models/categorypage.py +70 -0
- spotifywebapipython/models/chapter.py +84 -0
- spotifywebapipython/models/chapterpagesimplified.py +88 -0
- spotifywebapipython/models/chaptersimplified.py +387 -0
- spotifywebapipython/models/context.py +113 -0
- spotifywebapipython/models/copyright.py +79 -0
- spotifywebapipython/models/device.py +301 -0
- spotifywebapipython/models/episode.py +84 -0
- spotifywebapipython/models/episodepagesaved.py +85 -0
- spotifywebapipython/models/episodepagesimplified.py +88 -0
- spotifywebapipython/models/episodesaved.py +99 -0
- spotifywebapipython/models/episodesimplified.py +370 -0
- spotifywebapipython/models/explicitcontent.py +80 -0
- spotifywebapipython/models/externalids.py +91 -0
- spotifywebapipython/models/externalurls.py +104 -0
- spotifywebapipython/models/followers.py +81 -0
- spotifywebapipython/models/imageobject.py +193 -0
- spotifywebapipython/models/imagevibrantcolors.py +182 -0
- spotifywebapipython/models/linkedfrom.py +165 -0
- spotifywebapipython/models/narrator.py +67 -0
- spotifywebapipython/models/owner.py +162 -0
- spotifywebapipython/models/pageobject.py +343 -0
- spotifywebapipython/models/playeractions.py +196 -0
- spotifywebapipython/models/playerlastplayedinfo.py +334 -0
- spotifywebapipython/models/playerplaystate.py +467 -0
- spotifywebapipython/models/playerqueueinfo.py +207 -0
- spotifywebapipython/models/playhistory.py +136 -0
- spotifywebapipython/models/playhistorypage.py +85 -0
- spotifywebapipython/models/playlist.py +125 -0
- spotifywebapipython/models/playlistpage.py +85 -0
- spotifywebapipython/models/playlistpagesimplified.py +107 -0
- spotifywebapipython/models/playlistsimplified.py +334 -0
- spotifywebapipython/models/playlisttrack.py +143 -0
- spotifywebapipython/models/playlisttracksummary.py +80 -0
- spotifywebapipython/models/recommendationseed.py +135 -0
- spotifywebapipython/models/restrictions.py +86 -0
- spotifywebapipython/models/resumepoint.py +79 -0
- spotifywebapipython/models/searchresponse.py +391 -0
- spotifywebapipython/models/searchresultbase.py +299 -0
- spotifywebapipython/models/show.py +87 -0
- spotifywebapipython/models/showpagesaved.py +85 -0
- spotifywebapipython/models/showpagesimplified.py +88 -0
- spotifywebapipython/models/showsaved.py +99 -0
- spotifywebapipython/models/showsimplified.py +320 -0
- spotifywebapipython/models/spotifyconnectdevice.py +321 -0
- spotifywebapipython/models/spotifyconnectdevices.py +441 -0
- spotifywebapipython/models/track.py +142 -0
- spotifywebapipython/models/trackpage.py +110 -0
- spotifywebapipython/models/trackpagesaved.py +85 -0
- spotifywebapipython/models/trackpagesimplified.py +88 -0
- spotifywebapipython/models/trackrecommendations.py +88 -0
- spotifywebapipython/models/tracksaved.py +99 -0
- spotifywebapipython/models/tracksimplified.py +398 -0
- spotifywebapipython/models/userprofile.py +184 -0
- spotifywebapipython/models/userprofilesimplified.py +206 -0
- spotifywebapipython/models/zeroconfdiscoveryresult.py +592 -0
- spotifywebapipython/models/zeroconfproperty.py +93 -0
- spotifywebapipython/oauthcli/__init__.py +7 -0
- spotifywebapipython/oauthcli/authclient.py +1229 -0
- spotifywebapipython/saappmessages.py +86 -0
- spotifywebapipython/sautils.py +285 -0
- spotifywebapipython/spotifyapierror.py +66 -0
- spotifywebapipython/spotifyapimessage.py +269 -0
- spotifywebapipython/spotifyauthtoken.py +264 -0
- spotifywebapipython/spotifyclient.py +17885 -0
- spotifywebapipython/spotifyconnect/__init__.py +19 -0
- spotifywebapipython/spotifyconnect/spotifyconnectdeviceeventargs.py +67 -0
- spotifywebapipython/spotifyconnect/spotifyconnectdirectorytask.py +2564 -0
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastapptask.py +467 -0
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastcontroller.py +701 -0
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastlistener.py +359 -0
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastmultizonelistener.py +212 -0
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfexceptions.py +20 -0
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconflistener.py +335 -0
- spotifywebapipython/spotifydiscovery.py +473 -0
- spotifywebapipython/spotifymediatypes.py +53 -0
- spotifywebapipython/spotifywebapiauthenticationerror.py +122 -0
- spotifywebapipython/spotifywebapierror.py +106 -0
- spotifywebapipython/spotifywebplayertoken.py +743 -0
- spotifywebapipython/vibrant/__init__.py +17 -0
- spotifywebapipython/vibrant/generator.py +261 -0
- spotifywebapipython/vibrant/image.py +100 -0
- spotifywebapipython/vibrant/main.py +34 -0
- spotifywebapipython/vibrant/models.py +93 -0
- spotifywebapipython/vibrant/utils.py +56 -0
- 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 +1327 -0
- spotifywebapipython/zeroconfapi/zeroconfgetinfo.py +572 -0
- spotifywebapipython/zeroconfapi/zeroconfgetinfoalias.py +109 -0
- spotifywebapipython/zeroconfapi/zeroconfgetinfodrmmediaformat.py +90 -0
- spotifywebapipython/zeroconfapi/zeroconfresponse.py +195 -0
- spotifywebapipython-1.0.242.dist-info/LICENSE +22 -0
- spotifywebapipython-1.0.242.dist-info/METADATA +219 -0
- spotifywebapipython-1.0.242.dist-info/RECORD +138 -0
- spotifywebapipython-1.0.242.dist-info/WHEEL +5 -0
- spotifywebapipython-1.0.242.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
# external package imports.
|
|
2
|
+
|
|
3
|
+
# our package imports.
|
|
4
|
+
from ..sautils import export
|
|
5
|
+
from .zeroconfgetinfoalias import ZeroconfGetInfoAlias
|
|
6
|
+
from .zeroconfgetinfodrmmediaformat import ZeroconfGetInfoDrmMediaFormat
|
|
7
|
+
from .zeroconfresponse import ZeroconfResponse
|
|
8
|
+
|
|
9
|
+
@export
|
|
10
|
+
class ZeroconfGetInfo(ZeroconfResponse):
|
|
11
|
+
"""
|
|
12
|
+
Spotify Zeroconf API GetInfo response object.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, root:dict=None) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Initializes a new instance of the class.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
root (dict):
|
|
21
|
+
Spotify Web API JSON response in dictionary format, used to load object
|
|
22
|
+
attributes; otherwise, None to not load attributes.
|
|
23
|
+
"""
|
|
24
|
+
# initialize base class.
|
|
25
|
+
super().__init__(root=root)
|
|
26
|
+
|
|
27
|
+
# initialize our attributes.
|
|
28
|
+
self._AccountReq:str = None
|
|
29
|
+
self._ActiveUser:str = ""
|
|
30
|
+
self._Aliases:list[ZeroconfGetInfoAlias] = []
|
|
31
|
+
self._Availability:str = ""
|
|
32
|
+
self._BrandDisplayName:str = None
|
|
33
|
+
self._ClientId:str = None
|
|
34
|
+
self._DeviceId:str = ""
|
|
35
|
+
self._DeviceType:str = None
|
|
36
|
+
self._GroupStatus:str = None
|
|
37
|
+
self._LibraryVersion:str = None
|
|
38
|
+
self._ModelDisplayName:str = None
|
|
39
|
+
self._ProductId:str = None
|
|
40
|
+
self._PublicKey:str = None
|
|
41
|
+
self._RemoteName:str = None
|
|
42
|
+
self._ResolverVersion:str = None
|
|
43
|
+
self._Scope:str = None
|
|
44
|
+
self._SupportedCapabilities:int = None
|
|
45
|
+
self._SupportedDrmMediaFormats:list[ZeroconfGetInfoDrmMediaFormat] = []
|
|
46
|
+
self._TokenType:str = None
|
|
47
|
+
self._Version:str = None
|
|
48
|
+
self._VoiceSupport:str = None
|
|
49
|
+
|
|
50
|
+
if (root is None):
|
|
51
|
+
|
|
52
|
+
pass
|
|
53
|
+
|
|
54
|
+
else:
|
|
55
|
+
|
|
56
|
+
self._AccountReq = root.get('accountReq', None)
|
|
57
|
+
self._ActiveUser = root.get('activeUser', "")
|
|
58
|
+
self._Availability = root.get('availability', "")
|
|
59
|
+
self._BrandDisplayName = root.get('brandDisplayName', None)
|
|
60
|
+
self._ClientId = root.get('clientID', None)
|
|
61
|
+
self._DeviceId = root.get('deviceID', "")
|
|
62
|
+
self._DeviceType = root.get('deviceType', None)
|
|
63
|
+
self._GroupStatus = root.get('groupStatus', None)
|
|
64
|
+
self._LibraryVersion = root.get('libraryVersion', None)
|
|
65
|
+
self._ModelDisplayName = root.get('modelDisplayName', None)
|
|
66
|
+
self._ProductId = root.get('productID', None)
|
|
67
|
+
self._PublicKey = root.get('publicKey', None)
|
|
68
|
+
self._RemoteName = root.get('remoteName', None)
|
|
69
|
+
self._ResolverVersion = root.get('resolverVersion', None)
|
|
70
|
+
self._Scope = root.get('scope', None)
|
|
71
|
+
self._SupportedCapabilities = root.get('supported_capabilities', None)
|
|
72
|
+
self._TokenType = root.get('tokenType', None)
|
|
73
|
+
self._Version = root.get('version', None)
|
|
74
|
+
self._VoiceSupport = root.get('voiceSupport', None)
|
|
75
|
+
|
|
76
|
+
# process all collections and objects.
|
|
77
|
+
#items:list = root.get('aliases', [{ "id":"aliasId","isGroup": False, "name":"aliasName" }]) # simulate an alias value (used for testing).
|
|
78
|
+
items:list = root.get('aliases',None)
|
|
79
|
+
if items is not None:
|
|
80
|
+
for item in items:
|
|
81
|
+
self._Aliases.append(ZeroconfGetInfoAlias(root=item))
|
|
82
|
+
|
|
83
|
+
items:list = root.get('supported_drm_media_formats',None)
|
|
84
|
+
if items is not None:
|
|
85
|
+
for item in items:
|
|
86
|
+
self._SupportedDrmMediaFormats.append(ZeroconfGetInfoDrmMediaFormat(root=item))
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def __repr__(self) -> str:
|
|
90
|
+
return self.ToString()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def __str__(self) -> str:
|
|
94
|
+
return self.ToString()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def AccountReq(self) -> str:
|
|
99
|
+
"""
|
|
100
|
+
? (e.g. "DONTCARE").
|
|
101
|
+
"""
|
|
102
|
+
return self._AccountReq
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def ActiveUser(self) -> str:
|
|
107
|
+
"""
|
|
108
|
+
Canonical username of the logged in user (e.g. "31l77y2123456789012345678901").
|
|
109
|
+
|
|
110
|
+
This value will be an empty string if there is no user logged into the device.
|
|
111
|
+
"""
|
|
112
|
+
return self._ActiveUser
|
|
113
|
+
|
|
114
|
+
@ActiveUser.setter
|
|
115
|
+
def ActiveUser(self, value:str):
|
|
116
|
+
"""
|
|
117
|
+
Sets the ActiveUser property value.
|
|
118
|
+
"""
|
|
119
|
+
if (isinstance(value, str)) or (value is None):
|
|
120
|
+
self._ActiveUser = value or ""
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def Aliases(self) -> list[ZeroconfGetInfoAlias]:
|
|
125
|
+
"""
|
|
126
|
+
Device alias information, IF the device supports aliases.
|
|
127
|
+
|
|
128
|
+
Using ZeroConf, it is possible to announce multiple "virtual devices" from a device.
|
|
129
|
+
This allows the eSDK device to expose, for instance, multiroom zones as ZeroConf devices.
|
|
130
|
+
|
|
131
|
+
Device aliases will show up as separate devices in the Spotify app.
|
|
132
|
+
|
|
133
|
+
A maximum of 8 aliases are supported (SP_MAX_DEVICE_ALIASES).
|
|
134
|
+
|
|
135
|
+
Please refer to the `RemoteName` property for more information.
|
|
136
|
+
"""
|
|
137
|
+
return self._Aliases
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@property
|
|
141
|
+
def Availability(self) -> str:
|
|
142
|
+
"""
|
|
143
|
+
The SpZeroConfVars availability field returned by SpZeroConfGetVars.
|
|
144
|
+
|
|
145
|
+
The following are values that I have encountered thus far:
|
|
146
|
+
- "" - Device is available and ready for use.
|
|
147
|
+
- "UNAVAILABLE" - Device is unavailable, and should probably be rebooted.
|
|
148
|
+
- "NOT-LOADED" - Spotify SDK / API is not loaded.
|
|
149
|
+
|
|
150
|
+
The maximum length of the availability string (SP_MAX_AVAILABILITY_LENGTH)
|
|
151
|
+
is 15 characters (not counting terminating NULL).
|
|
152
|
+
"""
|
|
153
|
+
return self._Availability
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def BrandDisplayName(self) -> str:
|
|
158
|
+
"""
|
|
159
|
+
A UTF-8-encoded brand name of the hardware device, for hardware integrations (e.g. "Bose", "Onkyo", etc).
|
|
160
|
+
|
|
161
|
+
The maximum length of the brand display name (SP_MAX_BRAND_NAME_LENGTH)
|
|
162
|
+
is 32 characters (not counting terminating NULL).
|
|
163
|
+
"""
|
|
164
|
+
return self._BrandDisplayName
|
|
165
|
+
|
|
166
|
+
@BrandDisplayName.setter
|
|
167
|
+
def BrandDisplayName(self, value:str):
|
|
168
|
+
"""
|
|
169
|
+
Sets the BrandDisplayName property value.
|
|
170
|
+
"""
|
|
171
|
+
if (isinstance(value, str)) or (value is None):
|
|
172
|
+
self._BrandDisplayName = value
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def ClientId(self) -> str:
|
|
177
|
+
"""
|
|
178
|
+
Client id of the application (e.g. "79ebcb219e8e4e123456789000123456").
|
|
179
|
+
|
|
180
|
+
The maximum length of the client ID value (SP_MAX_CLIENT_ID_LENGTH)
|
|
181
|
+
is 32 characters (not counting terminating NULL).
|
|
182
|
+
"""
|
|
183
|
+
return self._ClientId
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@property
|
|
187
|
+
def DeviceId(self) -> str:
|
|
188
|
+
"""
|
|
189
|
+
Unique device ID used for ZeroConf logins (e.g. "30fbc80e35598f3c242f2120413c943dfd9715fe").
|
|
190
|
+
|
|
191
|
+
The maximum length of the device ID value used for ZeroConf logins (SP_MAX_DEVICE_ID_LENGTH)
|
|
192
|
+
is 64 characters (not counting terminating NULL).
|
|
193
|
+
"""
|
|
194
|
+
return self._DeviceId
|
|
195
|
+
|
|
196
|
+
@DeviceId.setter
|
|
197
|
+
def DeviceId(self, value:str):
|
|
198
|
+
"""
|
|
199
|
+
Sets the DeviceId property value.
|
|
200
|
+
"""
|
|
201
|
+
if (isinstance(value, str)) or (value is None):
|
|
202
|
+
self._DeviceId = value or ""
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
@property
|
|
206
|
+
def DeviceType(self) -> str:
|
|
207
|
+
"""
|
|
208
|
+
Type of the device (e.g. "SPEAKER", "AVR", etc).
|
|
209
|
+
|
|
210
|
+
Can be any of the following `SpDeviceType` devices:
|
|
211
|
+
- Computer Laptop or desktop computer device.
|
|
212
|
+
- Tablet Tablet PC device.
|
|
213
|
+
- Smartphone Smartphone device.
|
|
214
|
+
- Speaker Speaker device.
|
|
215
|
+
- TV Television device.
|
|
216
|
+
- AVR Audio/Video receiver device.
|
|
217
|
+
- STB Set-Top Box device.
|
|
218
|
+
- AudioDongle Audio dongle device.
|
|
219
|
+
- GameConsole Game console device.
|
|
220
|
+
- CastVideo Chromecast Video.
|
|
221
|
+
- CastAudio Chromecast Audio.
|
|
222
|
+
- Automobile Automobile.
|
|
223
|
+
- Smartwatch Smartwatch.
|
|
224
|
+
- Chromebook Chromebook.
|
|
225
|
+
|
|
226
|
+
The maximum length of the device type string (SP_MAX_DEVICE_TYPE_LENGTH)
|
|
227
|
+
is 15 characters (not counting terminating NULL).
|
|
228
|
+
"""
|
|
229
|
+
return self._DeviceType
|
|
230
|
+
|
|
231
|
+
@DeviceType.setter
|
|
232
|
+
def DeviceType(self, value:str):
|
|
233
|
+
"""
|
|
234
|
+
Sets the DeviceType property value.
|
|
235
|
+
"""
|
|
236
|
+
if (isinstance(value, str)) or (value is None):
|
|
237
|
+
self._DeviceType = value
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
@property
|
|
241
|
+
def GroupStatus(self) -> str:
|
|
242
|
+
"""
|
|
243
|
+
The SpZeroConfVars group_status field returned by SpZeroConfGetVars (e.g. "NONE").
|
|
244
|
+
|
|
245
|
+
The maximum length of the group status string (SP_MAX_GROUP_STATUS_LENGTH)
|
|
246
|
+
is 15 characters (not counting terminating NULL).
|
|
247
|
+
"""
|
|
248
|
+
return self._GroupStatus
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
@property
|
|
252
|
+
def HasActiveUser(self) -> bool:
|
|
253
|
+
"""
|
|
254
|
+
Returns True if the device has an active user account specified;
|
|
255
|
+
otherwise, False.
|
|
256
|
+
"""
|
|
257
|
+
return (self._ActiveUser != "")
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
@property
|
|
261
|
+
def HasAliases(self) -> bool:
|
|
262
|
+
"""
|
|
263
|
+
Returns True if the device has alias entries defined;
|
|
264
|
+
otherwise, False.
|
|
265
|
+
"""
|
|
266
|
+
return (len(self._Aliases) > 0)
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
@property
|
|
270
|
+
def IsAvailable(self) -> bool:
|
|
271
|
+
"""
|
|
272
|
+
Returns True if the device is available; otherwise, False.
|
|
273
|
+
|
|
274
|
+
Determination is made based upon the `Availability` property value.
|
|
275
|
+
"""
|
|
276
|
+
if (self._Availability is None) or (self._Availability == ""):
|
|
277
|
+
return True
|
|
278
|
+
return False
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def IsBrandSonos(self) -> bool:
|
|
283
|
+
"""
|
|
284
|
+
Returns True if the device is a 'Sonos' branded device; otherwise, False.
|
|
285
|
+
|
|
286
|
+
Determination is made based upon the `BrandDisplayName` property value.
|
|
287
|
+
"""
|
|
288
|
+
result:bool = False
|
|
289
|
+
if (isinstance(self._BrandDisplayName, str)) and (self._BrandDisplayName.lower().strip() == 'sonos'):
|
|
290
|
+
result = True
|
|
291
|
+
return result
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
@property
|
|
295
|
+
def LibraryVersion(self) -> str:
|
|
296
|
+
"""
|
|
297
|
+
Client library version that processed the Zeroconf action (e.g. "3.88.29-gc4d4bb01").
|
|
298
|
+
"""
|
|
299
|
+
return self._LibraryVersion
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
@property
|
|
303
|
+
def ModelDisplayName(self) -> str:
|
|
304
|
+
"""
|
|
305
|
+
A UTF-8-encoded model name of the hardware device, for hardware integrations (e.g. "Soundtouch").
|
|
306
|
+
|
|
307
|
+
The maximum length of the model display name (SP_MAX_MODEL_NAME_LENGTH)
|
|
308
|
+
is 30 characters (not counting terminating NULL).
|
|
309
|
+
"""
|
|
310
|
+
return self._ModelDisplayName
|
|
311
|
+
|
|
312
|
+
@ModelDisplayName.setter
|
|
313
|
+
def ModelDisplayName(self, value:str):
|
|
314
|
+
"""
|
|
315
|
+
Sets the ModelDisplayName property value.
|
|
316
|
+
"""
|
|
317
|
+
if (isinstance(value, str)) or (value is None):
|
|
318
|
+
self._ModelDisplayName = value
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
@property
|
|
322
|
+
def ProductId(self) -> str:
|
|
323
|
+
"""
|
|
324
|
+
An integer enumerating the product for this partner (e.g. 12345).
|
|
325
|
+
"""
|
|
326
|
+
return self._ProductId
|
|
327
|
+
|
|
328
|
+
@ProductId.setter
|
|
329
|
+
def ProductId(self, value:str):
|
|
330
|
+
"""
|
|
331
|
+
Sets the ProductId property value.
|
|
332
|
+
"""
|
|
333
|
+
if (isinstance(value, str)) or (value is None):
|
|
334
|
+
self._ProductId = value
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
@property
|
|
338
|
+
def PublicKey(self) -> str:
|
|
339
|
+
"""
|
|
340
|
+
Public key used in ZeroConf logins (e.g. "G+ZM4irhc...").
|
|
341
|
+
|
|
342
|
+
The maximum length of the public key used in ZeroConf logins (SP_MAX_PUBLIC_KEY_LENGTH)
|
|
343
|
+
is 149 characters (not counting terminating NULL).
|
|
344
|
+
"""
|
|
345
|
+
return self._PublicKey
|
|
346
|
+
|
|
347
|
+
@PublicKey.setter
|
|
348
|
+
def PublicKey(self, value:str):
|
|
349
|
+
"""
|
|
350
|
+
Sets the PublicKey property value.
|
|
351
|
+
"""
|
|
352
|
+
if (isinstance(value, str)) or (value is None):
|
|
353
|
+
self._PublicKey = value
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
@property
|
|
357
|
+
def RemoteName(self) -> str:
|
|
358
|
+
"""
|
|
359
|
+
Name to be displayed for the device (e.g. "BOSE-ST10-1").
|
|
360
|
+
|
|
361
|
+
This value will be null if the response is from a device using device aliases,
|
|
362
|
+
as the displayed name for respective alias is defined in the aliases field.
|
|
363
|
+
|
|
364
|
+
Please refer to the `Aliases` property for more information.
|
|
365
|
+
"""
|
|
366
|
+
return self._RemoteName
|
|
367
|
+
|
|
368
|
+
@RemoteName.setter
|
|
369
|
+
def RemoteName(self, value:str):
|
|
370
|
+
"""
|
|
371
|
+
Sets the RemoteName property value.
|
|
372
|
+
"""
|
|
373
|
+
if (isinstance(value, str)) or (value is None):
|
|
374
|
+
self._RemoteName = value
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
@property
|
|
378
|
+
def ResolverVersion(self) -> str:
|
|
379
|
+
"""
|
|
380
|
+
The SpZeroConfVars resolver_version field returned by SpZeroConfGetVars (e.g. "0").
|
|
381
|
+
"""
|
|
382
|
+
return self._ResolverVersion
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
@property
|
|
386
|
+
def Scope(self) -> str:
|
|
387
|
+
"""
|
|
388
|
+
OAuth scope requested when authenticating with the Spotify backend (e.g. "streaming").
|
|
389
|
+
|
|
390
|
+
The maximum length of the token type string (SP_MAX_SCOPE_LENGTH)
|
|
391
|
+
is 64 characters (not counting terminating NULL).
|
|
392
|
+
"""
|
|
393
|
+
return self._Scope
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
@property
|
|
397
|
+
def SupportedCapabilities(self) -> int:
|
|
398
|
+
"""
|
|
399
|
+
Bitmasked integer representing list of device capabilities (e.g. 0).
|
|
400
|
+
"""
|
|
401
|
+
return self._SupportedCapabilities
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
@property
|
|
405
|
+
def SupportedDrmMediaFormats(self) -> list:
|
|
406
|
+
"""
|
|
407
|
+
The SpZeroConfVars supported_drm_media_formats field returned by SpZeroConfGetVars (e.g. []).
|
|
408
|
+
|
|
409
|
+
A maximum of 8 formats are supported (SP_MAX_SUPPORTED_FORMATS).
|
|
410
|
+
"""
|
|
411
|
+
return self._SupportedDrmMediaFormats
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
@property
|
|
415
|
+
def TokenType(self) -> str:
|
|
416
|
+
"""
|
|
417
|
+
Token type provided by the client:
|
|
418
|
+
- "accesstoken" Access token.
|
|
419
|
+
- "authorization_code" OAuth Authorization Code token.
|
|
420
|
+
- "default" Default access token.
|
|
421
|
+
|
|
422
|
+
The maximum length of the token type string (SP_MAX_TOKEN_TYPE_LENGTH)
|
|
423
|
+
is 30 characters (not counting terminating NULL).
|
|
424
|
+
"""
|
|
425
|
+
return self._TokenType
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
@property
|
|
429
|
+
def Version(self) -> str:
|
|
430
|
+
"""
|
|
431
|
+
ZeroConf API version number (e.g. "2.10.0").
|
|
432
|
+
|
|
433
|
+
The maximum length of the library version string (SP_MAX_VERSION_LENGTH)
|
|
434
|
+
is 30 characters (not counting terminating NULL).
|
|
435
|
+
"""
|
|
436
|
+
return self._Version
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
@property
|
|
440
|
+
def VoiceSupport(self) -> str:
|
|
441
|
+
"""
|
|
442
|
+
Indicates if the device supports voice commands (e.g. "YES").
|
|
443
|
+
"""
|
|
444
|
+
return self._VoiceSupport
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
def Equals(self, obj) -> bool:
|
|
448
|
+
"""
|
|
449
|
+
Returns true if the specified object instance contains the same argument
|
|
450
|
+
values as our object instance values; otherwise, False.
|
|
451
|
+
|
|
452
|
+
Args:
|
|
453
|
+
obj (ZeroconfGetInfo):
|
|
454
|
+
Object instance to compare.
|
|
455
|
+
"""
|
|
456
|
+
result:bool = False
|
|
457
|
+
if (not isinstance(obj, type(self))):
|
|
458
|
+
return result
|
|
459
|
+
|
|
460
|
+
# compare attributes for equality.
|
|
461
|
+
if (self._AccountReq != obj._AccountReq): return result
|
|
462
|
+
if (self._ActiveUser != obj._ActiveUser): return result
|
|
463
|
+
if (self._Availability != obj._Availability): return result
|
|
464
|
+
if (self._BrandDisplayName != obj._BrandDisplayName): return result
|
|
465
|
+
if (self._ClientId != obj._ClientId): return result
|
|
466
|
+
if (self._DeviceId != obj._DeviceId): return result
|
|
467
|
+
if (self._DeviceType != obj._DeviceType): return result
|
|
468
|
+
if (self._GroupStatus != obj._GroupStatus): return result
|
|
469
|
+
if (self._LibraryVersion != obj._LibraryVersion): return result
|
|
470
|
+
if (self._ModelDisplayName != obj._ModelDisplayName): return result
|
|
471
|
+
if (self._ProductId != obj._ProductId): return result
|
|
472
|
+
if (self._PublicKey != obj._PublicKey): return result
|
|
473
|
+
if (self._RemoteName != obj._RemoteName): return result
|
|
474
|
+
if (self._ResolverVersion != obj._ResolverVersion): return result
|
|
475
|
+
if (self._Scope != obj._Scope): return result
|
|
476
|
+
if (self._SupportedCapabilities != obj._SupportedCapabilities): return result
|
|
477
|
+
if (self._TokenType != obj._TokenType): return result
|
|
478
|
+
if (self._Version != obj._Version): return result
|
|
479
|
+
if (self._VoiceSupport != obj._VoiceSupport): return result
|
|
480
|
+
|
|
481
|
+
# don't compare the following:
|
|
482
|
+
# self._Aliases:list[ZeroconfGetInfoAlias] = []
|
|
483
|
+
# self._InteractionIDs:list[str] = []
|
|
484
|
+
# self._SupportedDrmMediaFormats:list[ZeroconfGetInfoDrmMediaFormat] = []
|
|
485
|
+
|
|
486
|
+
# objects attributes are equal.
|
|
487
|
+
return True
|
|
488
|
+
|
|
489
|
+
|
|
490
|
+
def ToDictionary(self) -> dict:
|
|
491
|
+
"""
|
|
492
|
+
Returns a dictionary representation of the class.
|
|
493
|
+
"""
|
|
494
|
+
# get base class result.
|
|
495
|
+
resultBase:dict = super().ToDictionary()
|
|
496
|
+
|
|
497
|
+
# get our attribute results.
|
|
498
|
+
result:dict = \
|
|
499
|
+
{
|
|
500
|
+
'AccountReq': self._AccountReq,
|
|
501
|
+
'ActiveUser': self._ActiveUser,
|
|
502
|
+
'Aliases': [ item.ToDictionary() for item in self._Aliases ],
|
|
503
|
+
'Availability': self._Availability,
|
|
504
|
+
'BrandDisplayName': self._BrandDisplayName,
|
|
505
|
+
'ClientId': self._ClientId,
|
|
506
|
+
'DeviceId': self._DeviceId,
|
|
507
|
+
'DeviceType': self._DeviceType,
|
|
508
|
+
'GroupStatus': self._GroupStatus,
|
|
509
|
+
'LibraryVersion': self._LibraryVersion,
|
|
510
|
+
'ModelDisplayName': self._ModelDisplayName,
|
|
511
|
+
'ProductId': self._ProductId,
|
|
512
|
+
'PublicKey': self._PublicKey,
|
|
513
|
+
'RemoteName': self._RemoteName,
|
|
514
|
+
'ResolverVersion': self._ResolverVersion,
|
|
515
|
+
'Scope': self._Scope,
|
|
516
|
+
'SupportedCapabilities': self._SupportedCapabilities,
|
|
517
|
+
'SupportedDrmMediaFormats': [ item.ToDictionary() for item in self._SupportedDrmMediaFormats ],
|
|
518
|
+
'TokenType': self._TokenType,
|
|
519
|
+
'Version': self._Version,
|
|
520
|
+
'VoiceSupport': self._VoiceSupport,
|
|
521
|
+
# helper property(s), not part of the Spotify Web API interface:
|
|
522
|
+
'HasActiveUser': self.HasActiveUser,
|
|
523
|
+
'HasAliases': self.HasAliases,
|
|
524
|
+
'IsAvailable': self.IsAvailable,
|
|
525
|
+
'IsBrandSonos': self.IsBrandSonos,
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
# combine base class results with these results.
|
|
529
|
+
resultBase.update(result)
|
|
530
|
+
|
|
531
|
+
# return an unsorted dictionary.
|
|
532
|
+
return resultBase
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
def ToString(self, includeTitle:bool=True) -> str:
|
|
536
|
+
"""
|
|
537
|
+
Returns a displayable string representation of the class.
|
|
538
|
+
|
|
539
|
+
Args:
|
|
540
|
+
includeTitle (str):
|
|
541
|
+
True to include the class name title prefix.
|
|
542
|
+
"""
|
|
543
|
+
msg:str = ''
|
|
544
|
+
if includeTitle:
|
|
545
|
+
msg = 'ZeroconfGetInfo: '
|
|
546
|
+
|
|
547
|
+
# get base class result.
|
|
548
|
+
msg = '%s%s' % (msg, super().ToString(False))
|
|
549
|
+
|
|
550
|
+
# get our attribute results.
|
|
551
|
+
if self._AccountReq is not None: msg = '%s\n AccountReq="%s"' % (msg, str(self._AccountReq))
|
|
552
|
+
if self._ActiveUser is not None: msg = '%s\n ActiveUser="%s"' % (msg, str(self._ActiveUser))
|
|
553
|
+
if self._Aliases is not None: msg = '%s\n Aliases=%s' % (msg, str(self._Aliases))
|
|
554
|
+
if self._Availability is not None: msg = '%s\n Availability="%s"' % (msg, str(self._Availability))
|
|
555
|
+
if self._BrandDisplayName is not None: msg = '%s\n BrandDisplayName="%s"' % (msg, str(self._BrandDisplayName))
|
|
556
|
+
if self._ClientId is not None: msg = '%s\n ClientId="%s"' % (msg, str(self._ClientId))
|
|
557
|
+
if self._DeviceId is not None: msg = '%s\n DeviceId="%s"' % (msg, str(self._DeviceId))
|
|
558
|
+
if self._DeviceType is not None: msg = '%s\n DeviceType="%s"' % (msg, str(self._DeviceType))
|
|
559
|
+
if self._GroupStatus is not None: msg = '%s\n GroupStatus="%s"' % (msg, str(self._GroupStatus))
|
|
560
|
+
if self._LibraryVersion is not None: msg = '%s\n LibraryVersion="%s"' % (msg, str(self._LibraryVersion))
|
|
561
|
+
if self._ModelDisplayName is not None: msg = '%s\n ModelDisplayName="%s"' % (msg, str(self._ModelDisplayName))
|
|
562
|
+
if self._ProductId is not None: msg = '%s\n ProductId="%s"' % (msg, str(self._ProductId))
|
|
563
|
+
if self._PublicKey is not None: msg = '%s\n PublicKey="%s"' % (msg, str(self._PublicKey))
|
|
564
|
+
if self._RemoteName is not None: msg = '%s\n RemoteName="%s"' % (msg, str(self._RemoteName))
|
|
565
|
+
if self._ResolverVersion is not None: msg = '%s\n ResolverVersion="%s"' % (msg, str(self._ResolverVersion))
|
|
566
|
+
if self._Scope is not None: msg = '%s\n Scope="%s"' % (msg, str(self._Scope))
|
|
567
|
+
if self._SupportedCapabilities is not None: msg = '%s\n SupportedCapabilities="%s"' % (msg, str(self._SupportedCapabilities))
|
|
568
|
+
if self._SupportedDrmMediaFormats is not None: msg = '%s\n SupportedDrmMediaFormats=%s' % (msg, str(self._SupportedDrmMediaFormats))
|
|
569
|
+
if self._TokenType is not None: msg = '%s\n TokenType="%s"' % (msg, str(self._TokenType))
|
|
570
|
+
if self._Version is not None: msg = '%s\n Version="%s"' % (msg, str(self._Version))
|
|
571
|
+
if self._VoiceSupport is not None: msg = '%s\n VoiceSupport="%s"' % (msg, str(self._VoiceSupport))
|
|
572
|
+
return msg
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# external package imports.
|
|
2
|
+
|
|
3
|
+
# our package imports.
|
|
4
|
+
from ..sautils import export
|
|
5
|
+
|
|
6
|
+
@export
|
|
7
|
+
class ZeroconfGetInfoAlias:
|
|
8
|
+
"""
|
|
9
|
+
Spotify Zeroconf API GetInfo Alias object.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, root:dict=None) -> None:
|
|
13
|
+
"""
|
|
14
|
+
Initializes a new instance of the class.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
root (dict):
|
|
18
|
+
Spotify Web API JSON response in dictionary format, used to load object
|
|
19
|
+
attributes; otherwise, None to not load attributes.
|
|
20
|
+
"""
|
|
21
|
+
self._Id:str = None
|
|
22
|
+
self._IsGroup:bool = None
|
|
23
|
+
self._Name:str = None
|
|
24
|
+
|
|
25
|
+
if (root is None):
|
|
26
|
+
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
else:
|
|
30
|
+
|
|
31
|
+
self._Id = root.get('id', None)
|
|
32
|
+
self._IsGroup = root.get('isGroup', None)
|
|
33
|
+
self._Name = root.get('name', None)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def __repr__(self) -> str:
|
|
37
|
+
return self.ToString()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def __str__(self) -> str:
|
|
41
|
+
return self.ToString()
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def Id(self) -> str:
|
|
46
|
+
"""
|
|
47
|
+
Unique identifier of the alias (e.g. '1', '2', etc).
|
|
48
|
+
|
|
49
|
+
Note that this appears to be different than the `ZeroconfGetInfo.DeviceId` value.
|
|
50
|
+
Spotify Connect documentation is sparse, but I believe it's just a number from 1-8,
|
|
51
|
+
with eight being the maximum number of allowable alias names.
|
|
52
|
+
"""
|
|
53
|
+
return self._Id
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def IsGroup(self) -> bool:
|
|
58
|
+
"""
|
|
59
|
+
True if the alias is a group; otherwise, False.
|
|
60
|
+
"""
|
|
61
|
+
return self._IsGroup
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def Name(self) -> str:
|
|
66
|
+
"""
|
|
67
|
+
Display name of the alias (e.g. "Kitchen Speakers").
|
|
68
|
+
"""
|
|
69
|
+
return self._Name
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@property
|
|
73
|
+
def Title(self) -> str:
|
|
74
|
+
"""
|
|
75
|
+
Alias name and id value (e.g. '"Kitchen Speakers" (1)').
|
|
76
|
+
"""
|
|
77
|
+
return '"%s" (%s)' % (self._Name, self._Id)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def ToDictionary(self) -> dict:
|
|
81
|
+
"""
|
|
82
|
+
Returns a dictionary representation of the class.
|
|
83
|
+
"""
|
|
84
|
+
result:dict = \
|
|
85
|
+
{
|
|
86
|
+
'Id': self._Id,
|
|
87
|
+
'IsGroup': self._IsGroup,
|
|
88
|
+
'Name': self._Name,
|
|
89
|
+
'Title': self.Title,
|
|
90
|
+
}
|
|
91
|
+
return result
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def ToString(self, includeTitle:bool=False) -> str:
|
|
95
|
+
"""
|
|
96
|
+
Returns a displayable string representation of the class.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
includeTitle (str):
|
|
100
|
+
True to include the class name title prefix.
|
|
101
|
+
"""
|
|
102
|
+
msg:str = ''
|
|
103
|
+
if includeTitle:
|
|
104
|
+
msg = 'ZeroconfGetInfoAlias:'
|
|
105
|
+
|
|
106
|
+
if self._Name is not None: msg = '%s\n Name="%s"' % (msg, str(self._Name))
|
|
107
|
+
if self._Id is not None: msg = '%s\n Id="%s"' % (msg, str(self._Id))
|
|
108
|
+
if self._IsGroup is not None: msg = '%s\n IsGroup="%s"' % (msg, str(self._IsGroup))
|
|
109
|
+
return msg
|