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.
Files changed (138) hide show
  1. spotifywebapipython/__init__.py +35 -0
  2. spotifywebapipython/const.py +114 -0
  3. spotifywebapipython/docs/__init__.html +2156 -0
  4. spotifywebapipython/docs/codecopy.js +70 -0
  5. spotifywebapipython/docs/index.html +514 -0
  6. spotifywebapipython/docs/search.js +46 -0
  7. spotifywebapipython/docs/spotifywebapipython/const.html +636 -0
  8. spotifywebapipython/docs/spotifywebapipython/saappmessages.html +540 -0
  9. spotifywebapipython/docs/spotifywebapipython/sautils.html +620 -0
  10. spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html +341 -0
  11. spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html +598 -0
  12. spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html +612 -0
  13. spotifywebapipython/docs/spotifywebapipython/spotifyclient.html +16557 -0
  14. spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html +518 -0
  15. spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html +421 -0
  16. spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html +400 -0
  17. spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html +635 -0
  18. spotifywebapipython/docs/spotifywebapipython.ico +0 -0
  19. spotifywebapipython/docs/spotifywebapipython_OLD.ico +0 -0
  20. spotifywebapipython/models/__init__.py +121 -0
  21. spotifywebapipython/models/album.py +170 -0
  22. spotifywebapipython/models/albumpagesaved.py +85 -0
  23. spotifywebapipython/models/albumpagesimplified.py +88 -0
  24. spotifywebapipython/models/albumsaved.py +102 -0
  25. spotifywebapipython/models/albumsimplified.py +308 -0
  26. spotifywebapipython/models/artist.py +146 -0
  27. spotifywebapipython/models/artistinfo.py +282 -0
  28. spotifywebapipython/models/artistinfotourevent.py +127 -0
  29. spotifywebapipython/models/artistpage.py +70 -0
  30. spotifywebapipython/models/artistsimplified.py +163 -0
  31. spotifywebapipython/models/audiobook.py +87 -0
  32. spotifywebapipython/models/audiobookpagesimplified.py +88 -0
  33. spotifywebapipython/models/audiobooksimplified.py +362 -0
  34. spotifywebapipython/models/audiofeatures.py +333 -0
  35. spotifywebapipython/models/author.py +67 -0
  36. spotifywebapipython/models/category.py +168 -0
  37. spotifywebapipython/models/categorypage.py +70 -0
  38. spotifywebapipython/models/chapter.py +84 -0
  39. spotifywebapipython/models/chapterpagesimplified.py +88 -0
  40. spotifywebapipython/models/chaptersimplified.py +387 -0
  41. spotifywebapipython/models/context.py +113 -0
  42. spotifywebapipython/models/copyright.py +79 -0
  43. spotifywebapipython/models/device.py +301 -0
  44. spotifywebapipython/models/episode.py +84 -0
  45. spotifywebapipython/models/episodepagesaved.py +85 -0
  46. spotifywebapipython/models/episodepagesimplified.py +88 -0
  47. spotifywebapipython/models/episodesaved.py +99 -0
  48. spotifywebapipython/models/episodesimplified.py +370 -0
  49. spotifywebapipython/models/explicitcontent.py +80 -0
  50. spotifywebapipython/models/externalids.py +91 -0
  51. spotifywebapipython/models/externalurls.py +104 -0
  52. spotifywebapipython/models/followers.py +81 -0
  53. spotifywebapipython/models/imageobject.py +193 -0
  54. spotifywebapipython/models/imagevibrantcolors.py +182 -0
  55. spotifywebapipython/models/linkedfrom.py +165 -0
  56. spotifywebapipython/models/narrator.py +67 -0
  57. spotifywebapipython/models/owner.py +162 -0
  58. spotifywebapipython/models/pageobject.py +343 -0
  59. spotifywebapipython/models/playeractions.py +196 -0
  60. spotifywebapipython/models/playerlastplayedinfo.py +334 -0
  61. spotifywebapipython/models/playerplaystate.py +467 -0
  62. spotifywebapipython/models/playerqueueinfo.py +207 -0
  63. spotifywebapipython/models/playhistory.py +136 -0
  64. spotifywebapipython/models/playhistorypage.py +85 -0
  65. spotifywebapipython/models/playlist.py +125 -0
  66. spotifywebapipython/models/playlistpage.py +85 -0
  67. spotifywebapipython/models/playlistpagesimplified.py +107 -0
  68. spotifywebapipython/models/playlistsimplified.py +334 -0
  69. spotifywebapipython/models/playlisttrack.py +143 -0
  70. spotifywebapipython/models/playlisttracksummary.py +80 -0
  71. spotifywebapipython/models/recommendationseed.py +135 -0
  72. spotifywebapipython/models/restrictions.py +86 -0
  73. spotifywebapipython/models/resumepoint.py +79 -0
  74. spotifywebapipython/models/searchresponse.py +391 -0
  75. spotifywebapipython/models/searchresultbase.py +299 -0
  76. spotifywebapipython/models/show.py +87 -0
  77. spotifywebapipython/models/showpagesaved.py +85 -0
  78. spotifywebapipython/models/showpagesimplified.py +88 -0
  79. spotifywebapipython/models/showsaved.py +99 -0
  80. spotifywebapipython/models/showsimplified.py +320 -0
  81. spotifywebapipython/models/spotifyconnectdevice.py +321 -0
  82. spotifywebapipython/models/spotifyconnectdevices.py +441 -0
  83. spotifywebapipython/models/track.py +142 -0
  84. spotifywebapipython/models/trackpage.py +110 -0
  85. spotifywebapipython/models/trackpagesaved.py +85 -0
  86. spotifywebapipython/models/trackpagesimplified.py +88 -0
  87. spotifywebapipython/models/trackrecommendations.py +88 -0
  88. spotifywebapipython/models/tracksaved.py +99 -0
  89. spotifywebapipython/models/tracksimplified.py +398 -0
  90. spotifywebapipython/models/userprofile.py +184 -0
  91. spotifywebapipython/models/userprofilesimplified.py +206 -0
  92. spotifywebapipython/models/zeroconfdiscoveryresult.py +592 -0
  93. spotifywebapipython/models/zeroconfproperty.py +93 -0
  94. spotifywebapipython/oauthcli/__init__.py +7 -0
  95. spotifywebapipython/oauthcli/authclient.py +1229 -0
  96. spotifywebapipython/saappmessages.py +86 -0
  97. spotifywebapipython/sautils.py +285 -0
  98. spotifywebapipython/spotifyapierror.py +66 -0
  99. spotifywebapipython/spotifyapimessage.py +269 -0
  100. spotifywebapipython/spotifyauthtoken.py +264 -0
  101. spotifywebapipython/spotifyclient.py +17885 -0
  102. spotifywebapipython/spotifyconnect/__init__.py +19 -0
  103. spotifywebapipython/spotifyconnect/spotifyconnectdeviceeventargs.py +67 -0
  104. spotifywebapipython/spotifyconnect/spotifyconnectdirectorytask.py +2564 -0
  105. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastapptask.py +467 -0
  106. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastcontroller.py +701 -0
  107. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastlistener.py +359 -0
  108. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastmultizonelistener.py +212 -0
  109. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfexceptions.py +20 -0
  110. spotifywebapipython/spotifyconnect/spotifyconnectzeroconflistener.py +335 -0
  111. spotifywebapipython/spotifydiscovery.py +473 -0
  112. spotifywebapipython/spotifymediatypes.py +53 -0
  113. spotifywebapipython/spotifywebapiauthenticationerror.py +122 -0
  114. spotifywebapipython/spotifywebapierror.py +106 -0
  115. spotifywebapipython/spotifywebplayertoken.py +743 -0
  116. spotifywebapipython/vibrant/__init__.py +17 -0
  117. spotifywebapipython/vibrant/generator.py +261 -0
  118. spotifywebapipython/vibrant/image.py +100 -0
  119. spotifywebapipython/vibrant/main.py +34 -0
  120. spotifywebapipython/vibrant/models.py +93 -0
  121. spotifywebapipython/vibrant/utils.py +56 -0
  122. spotifywebapipython/zeroconfapi/__init__.py +23 -0
  123. spotifywebapipython/zeroconfapi/authenticationtypes.py +38 -0
  124. spotifywebapipython/zeroconfapi/blobbuilder.py +370 -0
  125. spotifywebapipython/zeroconfapi/credentials.py +37 -0
  126. spotifywebapipython/zeroconfapi/cryptodiffiehellman.py +89 -0
  127. spotifywebapipython/zeroconfapi/helpers.py +64 -0
  128. spotifywebapipython/zeroconfapi/spotifyzeroconfapierror.py +108 -0
  129. spotifywebapipython/zeroconfapi/zeroconfconnect.py +1327 -0
  130. spotifywebapipython/zeroconfapi/zeroconfgetinfo.py +572 -0
  131. spotifywebapipython/zeroconfapi/zeroconfgetinfoalias.py +109 -0
  132. spotifywebapipython/zeroconfapi/zeroconfgetinfodrmmediaformat.py +90 -0
  133. spotifywebapipython/zeroconfapi/zeroconfresponse.py +195 -0
  134. spotifywebapipython-1.0.242.dist-info/LICENSE +22 -0
  135. spotifywebapipython-1.0.242.dist-info/METADATA +219 -0
  136. spotifywebapipython-1.0.242.dist-info/RECORD +138 -0
  137. spotifywebapipython-1.0.242.dist-info/WHEEL +5 -0
  138. spotifywebapipython-1.0.242.dist-info/top_level.txt +1 -0
@@ -0,0 +1,335 @@
1
+ # external package imports.
2
+ import threading
3
+ from zeroconf import Zeroconf, ServiceInfo, ServiceStateChange, IPVersion
4
+
5
+ # our package imports.
6
+ from spotifywebapipython.models import ZeroconfProperty, ZeroconfDiscoveryResult
7
+ # note - cannot reference `SpotifyConnectDirectoryTask` due to circular import!
8
+ # from .SpotifyConnectDirectoryTask import SpotifyConnectDirectoryTask
9
+
10
+ # get smartinspect logger reference; create a new session for this module name.
11
+ from smartinspectpython.siauto import SIAuto, SILevel, SISession, SIMethodParmListContext
12
+ import logging
13
+
14
+ _logsi:SISession = SIAuto.Si.GetSession(__name__)
15
+ if (_logsi == None):
16
+ _logsi = SIAuto.Si.AddSession(__name__, True)
17
+ _logsi.SystemLogger = logging.getLogger(__name__)
18
+
19
+ ZEROCONF_SERVICETYPE_SPOTIFYCONNECT:str = "_spotify-connect._tcp.local."
20
+ """
21
+ Spotify Connect Zeroconf service type identifier.
22
+ """
23
+
24
+
25
+ class SpotifyConnectZeroconfListener:
26
+ """
27
+ Spotify Connect Zeroconf Listener class.
28
+
29
+ Listens for Chromecast device connection updates for devices that
30
+ support Spotify Connect.
31
+ """
32
+
33
+ # this class can be tested by issuing the following commands from an MS-DOS
34
+ # command prompt to simulate Zeroconf registration updates.
35
+
36
+ # - add a new Spotify Connect instance registration:
37
+ # > dns-sd -R "MyTestSC1" _spotify-connect._tcp. local 8080 cpath=/zcXXX version=1.0
38
+
39
+ # - update a new Spotify Connect instance registration;
40
+ # - if you change the name, service type, or port number, a NEW registration is created!
41
+ # - for updates, the only thing you can really update is the TXT record properties.
42
+ # > dns-sd -R "MyTestSC1" _spotify-connect._tcp. local 8080 cpath=/zcYYY version=1.0
43
+
44
+ # - remove an existing Spotify Connect instance registration;
45
+ # > the only way to remove an entry is to kill the process the entry was created under!
46
+
47
+
48
+ def __init__(
49
+ self,
50
+ parentDirectory,
51
+ zeroconf_RLock:threading.RLock,
52
+ ) -> None:
53
+ """
54
+ Initializes a new instance of the class.
55
+
56
+ Args:
57
+ parentDirectory (SpotifyConnectDirectoryTask):
58
+ Parent SpotifyConnectDirectoryTask instance.
59
+ zeroconf_RLock (threading.RLock):
60
+ Lock object used to enforce thread-safe updates.
61
+ """
62
+ # invoke base class method.
63
+ super().__init__()
64
+
65
+ # initialize storage.
66
+ self._ParentDirectory = parentDirectory
67
+ self._Zeroconf_RLock:threading.RLock = zeroconf_RLock
68
+
69
+
70
+ def _GetZeroconfDiscoveryResult(
71
+ self,
72
+ zeroconf:Zeroconf,
73
+ serviceType:str,
74
+ serviceName:str,
75
+ serviceStateChange:ServiceStateChange
76
+ ) -> ZeroconfDiscoveryResult:
77
+ """
78
+ Builds a `ZeroconfDiscoveryResult` instance from Zeroconf Service Information data
79
+ when an add or update service state change takes place.
80
+
81
+ Args:
82
+ zeroconf (Zeroconf):
83
+ Zeroconf instance that raised the notification.
84
+ serviceType (str):
85
+ Service type that was affected.
86
+ serviceName (str):
87
+ Service name that was affected.
88
+ serviceStateChange (ServiceStateChange):
89
+ A description of the type of service state change (add, remove, update).
90
+ """
91
+ result:ZeroconfDiscoveryResult = None
92
+
93
+ try:
94
+
95
+ # get service information instance; if none, then we are done.
96
+ deviceName:str = (serviceName.split(".")[0])
97
+ serviceInfo:ServiceInfo = zeroconf.get_service_info(serviceType, serviceName)
98
+ if serviceInfo is None:
99
+ # serviceinfo will be missing if it's a removal, so don't log the "ignored" message in this case.
100
+ if (serviceStateChange != ServiceStateChange.Removed):
101
+ _logsi.LogDebug("Spotify Connect Zeroconf discovery service notification ignored: \"%s\" (%s:%s) - no serviceinfo data" % (serviceName, serviceType, serviceStateChange))
102
+ return result
103
+
104
+ # get list of displayable (parsed) ipv4 addresses; if none, then we are done.
105
+ ipAddressList = serviceInfo.parsed_addresses(IPVersion.V4Only)
106
+ if (ipAddressList is None):
107
+ _logsi.LogDebug("Spotify Connect Zeroconf discovery service notification ignored: \"%s\" (%s:%s) - no IP address list" % (serviceName, serviceInfo.name, serviceStateChange))
108
+ return result
109
+
110
+ # trace.
111
+ _logsi.LogObject(SILevel.Debug, "Spotify Connect Zeroconf service details: \"%s\" (%s) (serviceinfo object)" % (deviceName, serviceInfo.name), serviceInfo)
112
+
113
+ # create new discovery result instance.
114
+ result:ZeroconfDiscoveryResult = ZeroconfDiscoveryResult()
115
+ result.DeviceName = deviceName
116
+ result.Domain = '.local'
117
+ for item in ipAddressList:
118
+ result.HostIpAddresses.append(item)
119
+ result.HostIpPort = serviceInfo.port
120
+ result.HostTTL = serviceInfo.host_ttl
121
+ result.Key = serviceInfo.key
122
+ result.Name = serviceInfo.name
123
+ result.OtherTTL = serviceInfo.other_ttl
124
+ result.Priority = serviceInfo.priority
125
+ result.Server = serviceInfo.server
126
+ result.ServerKey = serviceInfo.server_key
127
+ #result.ServiceInfo = serviceInfo
128
+ result.ServiceType = serviceType
129
+ result.Weight = serviceInfo.weight
130
+ result.Id = "\"%s\" (%s:%s)" % (result.DeviceName, result.HostIpAddress, result.HostIpPort)
131
+
132
+ # process service info propertys.
133
+ # note that the property keys and values must first be decoded to utf-8 encoding.
134
+ if serviceInfo.properties is not None:
135
+ dspProperties:dict = {}
136
+ for key, value in serviceInfo.properties.items():
137
+ keyStr = key.decode('utf-8') or ""
138
+ valueStr = value.decode('utf-8') or ""
139
+ result.Properties.append(ZeroconfProperty(keyStr, valueStr))
140
+ dspProperties[keyStr] = valueStr
141
+ # check for Spotify Connect common properties.
142
+ if keyStr.lower() == 'cpath':
143
+ result.SpotifyConnectCPath = valueStr
144
+ elif keyStr.lower() == 'version':
145
+ result.SpotifyConnectVersion = valueStr
146
+ _logsi.LogDictionary(SILevel.Debug, "Spotify Connect Zeroconf service details: \"%s\" (%s) (serviceinfo properties)" % (deviceName, serviceInfo.name), dspProperties)
147
+
148
+ # trace.
149
+ _logsi.LogObject(SILevel.Debug, "Spotify Connect Zeroconf Discovery Result: %s (object)" % (result.Id), result, excludeNonPublic=True)
150
+
151
+ # return discovery result.
152
+ return result
153
+
154
+ except Exception as ex:
155
+
156
+ # trace.
157
+ _logsi.LogException("Could not load ZeroconfDiscoveryResult instance from Zeroconf serviceinfo object.", ex, logToSystemLogger=False)
158
+
159
+ # ignore exception
160
+ return None
161
+
162
+
163
+ def OnServiceStateChange(
164
+ self,
165
+ zeroconf:Zeroconf,
166
+ service_type:str,
167
+ name:str,
168
+ state_change:ServiceStateChange
169
+ ) -> None:
170
+ """
171
+ Called by the spotify connect zeroconf ServiceBrowser when an mDNS service
172
+ state has changed (e.g. added, removed, or updated).
173
+
174
+ Args:
175
+ zeroconf (Zeroconf):
176
+ Zeroconf instance that raised the notification.
177
+ service_type (str):
178
+ Service type that was affected.
179
+ name (str):
180
+ Service name that was affected.
181
+ state_change (ServiceStateChange):
182
+ The type of service state change (add, remove, update).
183
+ """
184
+ # use lock, as multiple threads could be calling this method simultaneously.
185
+ with self._Zeroconf_RLock:
186
+
187
+ # copy passed parameters to thread-safe storage.
188
+ serviceType:str = service_type
189
+ serviceName:str = name
190
+ serviceStateChange:ServiceStateChange = state_change
191
+
192
+ apiMethodName:str = "OnServiceStateChange"
193
+ apiMethodParms:SIMethodParmListContext = None
194
+
195
+ try:
196
+
197
+ # trace.
198
+ apiMethodParms = _logsi.EnterMethodParmList(SILevel.Debug, apiMethodName)
199
+ apiMethodParms.AppendKeyValue("serviceType", serviceType)
200
+ apiMethodParms.AppendKeyValue("serviceName", serviceName)
201
+ apiMethodParms.AppendKeyValue("serviceStateChange", serviceStateChange)
202
+ _logsi.LogMethodParmList(SILevel.Verbose, "Spotify Connect Zeroconf discovery service notification: \"%s\" (%s)" % (serviceName, str(serviceStateChange)), apiMethodParms)
203
+
204
+ # call method based on serviceStateChange argument value.
205
+ if (serviceStateChange == ServiceStateChange.Added):
206
+ self.add_service(zeroconf, serviceType, serviceName, serviceStateChange)
207
+ return
208
+
209
+ if (serviceStateChange == ServiceStateChange.Removed):
210
+ self.remove_service(zeroconf, serviceType, serviceName, serviceStateChange)
211
+ return
212
+
213
+ if (serviceStateChange == ServiceStateChange.Updated):
214
+ self.update_service(zeroconf, serviceType, serviceName, serviceStateChange)
215
+ return
216
+
217
+ except Exception as ex:
218
+
219
+ # trace.
220
+ _logsi.LogException("Unhandled exception occured while processing Spotify Connect Zeroconf discovery browser ServiceStateChange notification (%s)" % (serviceStateChange), ex, logToSystemLogger=False)
221
+
222
+ # ignore exception, as nothing can be done about it.
223
+
224
+ finally:
225
+
226
+ # trace.
227
+ _logsi.LeaveMethod(SILevel.Debug, apiMethodName)
228
+
229
+
230
+ def add_service(
231
+ self,
232
+ zeroconf:Zeroconf,
233
+ serviceType:str,
234
+ serviceName:str,
235
+ serviceStateChange:ServiceStateChange
236
+ ) -> None:
237
+ """
238
+ Called when an mDNS service is discovered.
239
+
240
+ Args:
241
+ zeroconf (Zeroconf):
242
+ Zeroconf instance that raised the notification.
243
+ serviceType (str):
244
+ Service type that was affected.
245
+ serviceName (str):
246
+ Service name that was affected.
247
+ serviceStateChange (ServiceStateChange):
248
+ A description of the type of service state change (add, remove, update).
249
+
250
+ This method will be called in a thread-safe manner, as the caller is using
251
+ the `Zeroconf_RLock` object to control access.
252
+ """
253
+ # build discovery result instance from service state information.
254
+ # if nothing returned, then don't bother!
255
+ result:ZeroconfDiscoveryResult = self._GetZeroconfDiscoveryResult(zeroconf, serviceType, serviceName, serviceStateChange)
256
+ if (result is None):
257
+ return
258
+
259
+ # let the parent handle the event.
260
+ self._ParentDirectory.OnServiceInfoAddedUpdatedSpotifyConnect(result)
261
+ return
262
+
263
+
264
+ def remove_service(
265
+ self,
266
+ zeroconf:Zeroconf,
267
+ serviceType:str,
268
+ serviceName:str,
269
+ serviceStateChange:ServiceStateChange
270
+ ) -> None:
271
+ """
272
+ Called when an mDNS service is lost.
273
+
274
+ Args:
275
+ zeroconf (Zeroconf):
276
+ Zeroconf instance that raised the notification.
277
+ serviceType (str):
278
+ Service type that was affected.
279
+ serviceName (str):
280
+ Service name that was affected.
281
+ serviceStateChange (ServiceStateChange):
282
+ A description of the type of service state change (add, remove, update).
283
+
284
+ This method will be called in a thread-safe manner, as the caller is using
285
+ the `Zeroconf_RLock` object to control access.
286
+ """
287
+ # for service removal notifications, there will be no zeroconf service info.
288
+ # build discovery result instance from service state information.
289
+ # if nothing returned, then it's ok - build a minimal discovery instance that
290
+ # will contain the necessary details to remove the device entry.
291
+ result:ZeroconfDiscoveryResult = self._GetZeroconfDiscoveryResult(zeroconf, serviceType, serviceName, serviceStateChange)
292
+ if (result is None):
293
+ result = ZeroconfDiscoveryResult()
294
+ result.DeviceName = (serviceName.split(".")[0])
295
+ result.Key = serviceName.lower()
296
+ result.Name = serviceName
297
+ result.ServiceType = serviceType
298
+
299
+ # let the parent handle the event.
300
+ self._ParentDirectory.OnServiceInfoRemovedSpotifyConnect(result)
301
+ return
302
+
303
+
304
+ def update_service(
305
+ self,
306
+ zeroconf:Zeroconf,
307
+ serviceType:str,
308
+ serviceName:str,
309
+ serviceStateChange:ServiceStateChange
310
+ ) -> None:
311
+ """
312
+ Called when an mDNS service is updated.
313
+
314
+ Args:
315
+ zeroconf (Zeroconf):
316
+ Zeroconf instance that raised the notification.
317
+ serviceType (str):
318
+ Service type that was affected.
319
+ serviceName (str):
320
+ Service name that was affected.
321
+ serviceStateChange (ServiceStateChange):
322
+ A description of the type of service state change (add, remove, update).
323
+
324
+ This method will be called in a thread-safe manner, as the caller is using
325
+ the `Zeroconf_RLock` object to control access.
326
+ """
327
+ # build discovery result instance from service state information.
328
+ # if nothing returned, then don't bother!
329
+ result:ZeroconfDiscoveryResult = self._GetZeroconfDiscoveryResult(zeroconf, serviceType, serviceName, serviceStateChange)
330
+ if (result is None):
331
+ return
332
+
333
+ # let the parent handle the event.
334
+ self._ParentDirectory.OnServiceInfoAddedUpdatedSpotifyConnect(result)
335
+ return