spotifywebapiPython 1.0.291__py3-none-any.whl → 1.0.293__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 (28) hide show
  1. spotifywebapipython/const.py +1 -1
  2. spotifywebapipython/docs/__init__.html +14 -2
  3. spotifywebapipython/docs/index.html +2 -2
  4. spotifywebapipython/docs/search.js +1 -1
  5. spotifywebapipython/docs/spotifywebapipython/const.html +3 -3
  6. spotifywebapipython/docs/spotifywebapipython/saappmessages.html +2 -2
  7. spotifywebapipython/docs/spotifywebapipython/sautils.html +2 -2
  8. spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html +2 -2
  9. spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html +2 -2
  10. spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html +2 -2
  11. spotifywebapipython/docs/spotifywebapipython/spotifyclient.html +2 -2
  12. spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html +2 -2
  13. spotifywebapipython/docs/spotifywebapipython/spotifymediatypes.html +2 -2
  14. spotifywebapipython/docs/spotifywebapipython/spotifytypeprefixes.html +2 -2
  15. spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html +2 -2
  16. spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html +2 -2
  17. spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html +2 -2
  18. spotifywebapipython/spotifyconnect/spotifyconnectdirectorytask.py +205 -35
  19. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastapptask.py +1 -1
  20. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastlistener.py +3 -3
  21. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastmultizonemanagerlistener.py +6 -6
  22. spotifywebapipython/zeroconfapi/zeroconfconnect.py +1 -1
  23. spotifywebapipython/zeroconfapi/zeroconfgetinfo.py +26 -0
  24. {spotifywebapipython-1.0.291.dist-info → spotifywebapipython-1.0.293.dist-info}/METADATA +1 -1
  25. {spotifywebapipython-1.0.291.dist-info → spotifywebapipython-1.0.293.dist-info}/RECORD +28 -28
  26. {spotifywebapipython-1.0.291.dist-info → spotifywebapipython-1.0.293.dist-info}/LICENSE +0 -0
  27. {spotifywebapipython-1.0.291.dist-info → spotifywebapipython-1.0.293.dist-info}/WHEEL +0 -0
  28. {spotifywebapipython-1.0.291.dist-info → spotifywebapipython-1.0.293.dist-info}/top_level.txt +0 -0
@@ -509,6 +509,108 @@ class SpotifyConnectDirectoryTask(threading.Thread):
509
509
  # ignore exception, as nothing can be done about it.
510
510
 
511
511
 
512
+ def _VerifyMultizoneGroupLeader(
513
+ self,
514
+ scDevice: SpotifyConnectDevice,
515
+ discoveryResult: ZeroconfDiscoveryResult,
516
+ ) -> None:
517
+ """
518
+ Verifies the current leader for a cast group is connected and available.
519
+
520
+ Args:
521
+ scDevice (SpotifyConnectDevice):
522
+ SpotifyConnectDevice object that contains discovery result details.
523
+ discoveryResult (ZeroconfDiscoveryResult):
524
+ Newly discovered zeroconf updates for the device.
525
+ """
526
+ try:
527
+
528
+ leaderIP:str|None = None
529
+
530
+ # the MultiZoneManager should already have processed any multi-zone updates,
531
+ # including leadership changes; all we need to do now is to get the ChromeCast
532
+ # device reference from it, and retrieve the host IP address.
533
+
534
+ # if the Chromecast device socket client reports a different host IP address
535
+ # than it's CastInfo object, then it means that the multizone manager update
536
+ # is out of sync with the mDNS update! if that is the case, then we need to
537
+ # determine which of the two (if any!) is the active group leader.
538
+
539
+ # get group info from the multizone manager instance.
540
+ groupInfo = self._CastMultiZoneManager._groups.get(scDevice.DiscoveryResult.Key, None)
541
+ if (groupInfo is not None):
542
+
543
+ # get the assumed group leader device reference.
544
+ castDevice:Chromecast = groupInfo.get('chromecast', None)
545
+ if (castDevice):
546
+
547
+ if (castDevice.socket_client) and (castDevice.socket_client.is_connected):
548
+ leaderIP = castDevice.socket_client.host
549
+
550
+ elif (castDevice.cast_info):
551
+ leaderIP = castDevice.cast_info.host
552
+
553
+ # do we have a group leader conflict between the multizone manager
554
+ # reference and the mDNS service update?
555
+ if (leaderIP != discoveryResult.HostIpAddress):
556
+
557
+ # at this point, mDNS information is in conflict with MultiZoneManager information
558
+ # about who the group leader is! we will now query BOTH addresses to see which one
559
+ # responds, and use it as the group leader.
560
+
561
+ # trace.
562
+ _logsi.LogVerbose("Group leader conflict detected for device UUID: \"%s\"" % discoveryResult.Key)
563
+
564
+ try:
565
+
566
+ # connect to the first possible group leader.
567
+ _logsi.LogVerbose("Connecting to possible Cast Group leader #1: \"%s\"" % (discoveryResult.HostIpAddress))
568
+ castDevice = get_chromecast_from_host(
569
+ host=(discoveryResult.HostIpAddress, discoveryResult.HostIpPort, discoveryResult.Key, scDevice.DeviceInfo.ModelDisplayName, scDevice.DeviceInfo.RemoteName),
570
+ tries=1,
571
+ retry_wait=0.5,
572
+ timeout=2)
573
+
574
+ # if connection was successful, then use it as the leader.
575
+ leaderIP = discoveryResult.HostIpAddress
576
+
577
+ except Exception as ex:
578
+
579
+ try:
580
+
581
+ # connect to the first possible group leader.
582
+ _logsi.LogVerbose("Connecting to possible Cast Group leader #2: \"%s\"" % (leaderIP))
583
+ castDevice = get_chromecast_from_host(
584
+ host=(leaderIP, scDevice.DiscoveryResult.HostIpPort, scDevice.DiscoveryResult.Key, scDevice.DeviceInfo.ModelDisplayName, scDevice.DeviceInfo.RemoteName),
585
+ tries=1,
586
+ retry_wait=0.5,
587
+ timeout=2)
588
+
589
+ # if connection was successful, then use it as the leader.
590
+ leaderIP = leaderIP
591
+
592
+ except Exception as ex:
593
+
594
+ _logsi.LogVerbose("Could not connect to either possible Cast Group leader for device: \"%s\"" % (scDevice.Title))
595
+
596
+ # free resources.
597
+ castDevice = None
598
+
599
+ # do we have a group leader change?
600
+ if (leaderIP != scDevice.DiscoveryResult.HostIpAddress):
601
+
602
+ # trace.
603
+ _logsi.LogObject(SILevel.Verbose, "Cast Group leader IP was changed from [%s] to [%s] for device \"%s\"" % (scDevice.DiscoveryResult.HostIpAddress, leaderIP, scDevice.Name), scDevice, excludeNonPublic=True, colorValue=SIColors.ForestGreen)
604
+ scDevice.DiscoveryResult.HostIpAddress = leaderIP
605
+ scDevice.DiscoveryResult.Id = "\"%s\" (%s:%s)" % (scDevice.DiscoveryResult.DeviceName, scDevice.DiscoveryResult.HostIpAddress, scDevice.DiscoveryResult.HostIpPort)
606
+
607
+ except Exception as ex:
608
+
609
+ # trace.
610
+ _logsi.LogException("Chromecast Multizone group leader query exception: %s" % (str(ex)), ex, logToSystemLogger=False)
611
+ # ignore exception, as nothing can be done about it.
612
+
613
+
512
614
  def ActivateCastAppSpotify(
513
615
  self,
514
616
  deviceName:str,
@@ -586,6 +688,13 @@ class SpotifyConnectDirectoryTask(threading.Thread):
586
688
  # match was found; reset device id activated before we activate a device.
587
689
  scDevice.DeviceIdActivated = None
588
690
 
691
+ # is the activation request for a group?
692
+ if (scDevice.DiscoveryResult.IsChromeCastGroup):
693
+
694
+ # verify the current leader of the group.
695
+ # the device collection entry will be updated if a change was detected.
696
+ self._VerifyMultizoneGroupLeader(scDevice, scDevice.DiscoveryResult)
697
+
589
698
  # is this a chromecast device?
590
699
  if (not scDevice.IsChromeCast):
591
700
  raise SpotifyApiError("Device %s is not a Chromecast device; use TransferPlayback instead." % (scDevice.Title), logsi=_logsi)
@@ -1997,17 +2106,27 @@ class SpotifyConnectDirectoryTask(threading.Thread):
1997
2106
  scDevice.DeviceInfo.RemoteName = newDeviceName
1998
2107
  deviceNameChanged = True
1999
2108
 
2000
- # is this a Google Cast Group "update_cast" event?
2001
- # if so, AND the device name did not change, then ignore the update since
2002
- # we want the first device discovered in the group to be the coordinator by default.
2003
- if (zeroconfDiscoveryResult.IsChromeCastGroup) and (not deviceNameChanged) and (serviceType == "update_cast"):
2004
- _logsi.LogObject(SILevel.Verbose, "SpotifyConnectDevice info: \"%s\" (ignored; Cast Group device update)" % (scDevice.Name), scDevice.DiscoveryResult, excludeNonPublic=True)
2005
- _logsi.LogObject(SILevel.Debug, "SpotifyConnectDevice info: %s (NEW DiscoveryResult ignored) [%s]" % (scDevice.Title, zeroconfDiscoveryResult.HostIpTitle), zeroconfDiscoveryResult, excludeNonPublic=True)
2006
- return
2109
+ # is this a Google Cast Group update?
2110
+ if (zeroconfDiscoveryResult.IsChromeCastGroup):
2111
+
2112
+ # is this a Google Cast Group "add_cast" event?
2113
+ # if so, then it's probably a group leadership change that did not issue a call to
2114
+ # "remove_cast" as part of the update. we now have to determine which device in the
2115
+ # group is the new leader, and update the group DiscoveryResult accordingly.
2116
+ if (serviceType == "add_cast"):
2007
2117
 
2008
- # always process changes for Google Cast Group "add_cast" event.
2009
- # if the group coordinator changes, then an "add_cast" event will occur with the
2010
- # new group coordinator device (I think!).
2118
+ # verify the current leader of the group.
2119
+ # the device collection entry will be updated if a change was detected.
2120
+ self._VerifyMultizoneGroupLeader(scDevice, zeroconfDiscoveryResult)
2121
+
2122
+ # is this a Google Cast Group "update_cast" event?
2123
+ # if so, AND the device name did not change, then ignore the update since
2124
+ # we will pickup any group leader changes in the ActivateCastAppSpotify method.
2125
+ elif (serviceType == "update_cast") and (not deviceNameChanged):
2126
+
2127
+ _logsi.LogObject(SILevel.Verbose, "SpotifyConnectDevice info: \"%s\" (ignored; Cast Group device update)" % (scDevice.Name), scDevice.DiscoveryResult, excludeNonPublic=True)
2128
+ _logsi.LogObject(SILevel.Debug, "SpotifyConnectDevice info: %s (NEW DiscoveryResult ignored) [%s]" % (scDevice.Title, zeroconfDiscoveryResult.HostIpTitle), zeroconfDiscoveryResult, excludeNonPublic=True)
2129
+ return
2011
2130
 
2012
2131
  # set zeroconf discovery result properties.
2013
2132
  scDevice.DiscoveryResult = zeroconfDiscoveryResult
@@ -2312,6 +2431,8 @@ class SpotifyConnectDirectoryTask(threading.Thread):
2312
2431
  # syncronize access via lock, as we are accessing the collection.
2313
2432
  with self._SpotifyConnectDevices_RLock:
2314
2433
 
2434
+ zconn:ZeroconfConnect = None
2435
+
2315
2436
  try:
2316
2437
 
2317
2438
  # trace.
@@ -2374,20 +2495,13 @@ class SpotifyConnectDirectoryTask(threading.Thread):
2374
2495
  # retrieve initial spotify connect device information (by ip address).
2375
2496
  scDevice.DeviceInfo = zconn.GetInformation()
2376
2497
  scDevice.Id = scDevice.DeviceInfo.DeviceId
2377
- scDevice.Name = scDevice.DeviceInfo.RemoteName
2498
+ scDevice.Name = scDevice.DeviceInfo.RemoteNameOrAlias
2378
2499
 
2379
2500
  # if service discovery version not set, then use the getInfo version.
2380
2501
  if (zeroconfDiscoveryResult.SpotifyConnectVersion is None):
2381
2502
  if (scDevice.DeviceInfo.Version is not None):
2382
2503
  zeroconfDiscoveryResult.SpotifyConnectVersion = scDevice.DeviceInfo.Version
2383
2504
 
2384
- # if remote name was not specified, then set device name to first alias name.
2385
- # note that we will not reset the RemoteName, as the "" value indicates an alias is in use.
2386
- if ((scDevice.DeviceInfo.RemoteName + "").strip() == ""):
2387
- if (scDevice.DeviceInfo.HasAliases):
2388
- _logsi.LogVerbose("Spotify Connect Zeroconf GetInformation alias name will be utilized for Zeroconf Discovery Result: \"%s\" (%s)" % (zeroconfDiscoveryResult.DeviceName, zeroconfDiscoveryResult.Name))
2389
- scDevice.Name = scDevice.DeviceInfo.Aliases[0].Name
2390
-
2391
2505
  except Exception as ex:
2392
2506
 
2393
2507
  # trace.
@@ -2413,20 +2527,13 @@ class SpotifyConnectDirectoryTask(threading.Thread):
2413
2527
  # retrieve initial spotify connect device information (by dns alias).
2414
2528
  scDevice.DeviceInfo = zconn.GetInformation()
2415
2529
  scDevice.Id = scDevice.DeviceInfo.DeviceId
2416
- scDevice.Name = scDevice.DeviceInfo.RemoteName
2530
+ scDevice.Name = scDevice.DeviceInfo.RemoteNameOrAlias
2417
2531
 
2418
2532
  # if service discovery version not set, then use the getInfo version.
2419
2533
  if (zeroconfDiscoveryResult.SpotifyConnectVersion is None):
2420
2534
  if (scDevice.DeviceInfo.Version is not None):
2421
2535
  zeroconfDiscoveryResult.SpotifyConnectVersion = scDevice.DeviceInfo.Version
2422
2536
 
2423
- # if remote name was not specified, then set device name to first alias name.
2424
- # note that we will not reset the RemoteName, as the "" value indicates an alias is in use.
2425
- if ((scDevice.DeviceInfo.RemoteName + "").strip() == ""):
2426
- if (scDevice.DeviceInfo.HasAliases):
2427
- _logsi.LogVerbose("Spotify Connect Zeroconf GetInformation alias name will be utilized for Zeroconf Discovery Result: \"%s\" (%s)" % (zeroconfDiscoveryResult.DeviceName, zeroconfDiscoveryResult.Name))
2428
- scDevice.Name = scDevice.DeviceInfo.Aliases[0].Name
2429
-
2430
2537
  # update HostIpAddress in discovery result so it knows to use the dns alias
2431
2538
  # instead of the ip address.
2432
2539
  _logsi.LogVerbose("Spotify Connect Zeroconf GetInformation call for Instance Name \"%s\" (%s) was resolved using DNS Server alias; HostIpAddress will be updated with the resolved ip address" % (zeroconfDiscoveryResult.DeviceName, zeroconfDiscoveryResult.Server))
@@ -2526,25 +2633,84 @@ class SpotifyConnectDirectoryTask(threading.Thread):
2526
2633
  scDevice = self._SpotifyConnectDevices.Items[idx]
2527
2634
 
2528
2635
  # were any changes made to the zeroconf discovery results?
2636
+ # this can happen when the Spotify Connect zeroconf server on the device has
2637
+ # been restarted (e.g. "resetUsers" called, etc). if so, then we need to update
2638
+ # the DiscoveryResult since it could possibly point to a different host address
2639
+ # (or port number) for the zeroconf endpoints (e.g. getInfo, addUser, etc). we will
2640
+ # also call "getInfo" to update any Spotify Connect changes (e.g. RemoteName, Id, etc).
2529
2641
  if (not scDevice.DiscoveryResult.Equals(zeroconfDiscoveryResult)):
2530
2642
 
2531
2643
  # trace.
2644
+ _logsi.LogVerbose("Spotify Connect zeroconf DiscoveryResult change detected for device: %s" % (scDevice.Title))
2532
2645
  _logsi.LogObject(SILevel.Debug, "SpotifyConnectDevice info: \"%s\" (OLD DeviceInfo / getInfo)" % (scDevice.Title), scDevice.DeviceInfo, excludeNonPublic=True)
2533
2646
  _logsi.LogObject(SILevel.Debug, "SpotifyConnectDevice info: \"%s\" (OLD DiscoveryResult) [%s]" % (scDevice.Title, scDevice.DiscoveryResult.HostIpTitle), scDevice.DiscoveryResult, excludeNonPublic=True)
2534
2647
 
2535
- # set zeroconf discovery result properties.
2648
+ # preserve various old property values for comparison later.
2649
+ oldDeviceId:str = scDevice.DeviceInfo.DeviceId
2650
+ oldRemoteName:str = scDevice.DeviceInfo.RemoteNameOrAlias
2651
+ oldHostIpPort:int = scDevice.DiscoveryResult.HostIpPort
2652
+ newRemoteName:str = None
2653
+ newDeviceId:str = None
2654
+
2655
+ try:
2656
+
2657
+ # trace.
2658
+ _logsi.LogVerbose("Retrieving Spotify Connect device information: %s [DiscoveryResult change]" % (zeroconfDiscoveryResult.Id))
2659
+
2660
+ # create connection object to retrieve spotify connect device information (via direct ip address).
2661
+ zconn:ZeroconfConnect = ZeroconfConnect(
2662
+ zeroconfDiscoveryResult.HostIpAddress,
2663
+ zeroconfDiscoveryResult.HostIpPort,
2664
+ zeroconfDiscoveryResult.SpotifyConnectCPath,
2665
+ zeroconfDiscoveryResult.SpotifyConnectVersion,
2666
+ useSSL=False,
2667
+ tokenStorageDir=self.SpotifyClientInstance.TokenStorageDir,
2668
+ tokenStorageFile=self.SpotifyClientInstance.TokenStorageFile
2669
+ )
2670
+
2671
+ # retrieve spotify connect device information (by ip address).
2672
+ getInfo:ZeroconfGetInfo = zconn.GetInformation()
2673
+
2674
+ # if service discovery version not set, then use the getInfo version.
2675
+ if (zeroconfDiscoveryResult.SpotifyConnectVersion is None):
2676
+ if (getInfo.Version is not None):
2677
+ zeroconfDiscoveryResult.SpotifyConnectVersion = getInfo.Version
2678
+
2679
+ # update base device info from getInfo details.
2680
+ scDevice.DeviceInfo = getInfo
2681
+
2682
+ # set device name and id values from getInfo response values.
2683
+ newRemoteName = getInfo.RemoteNameOrAlias
2684
+ newDeviceId = getInfo.DeviceId
2685
+
2686
+ except Exception as ex:
2687
+
2688
+ # trace.
2689
+ _logsi.LogVerbose("Could not retrieve Spotify Connect device information; defaulting DeviceID to GetSpotifyDeviceIDFromName \"%s\"" % (zeroconfDiscoveryResult.DeviceName))
2690
+
2691
+ # at this point we don't know for sure what the device name is since getInfo failed.
2692
+ # set device name and id values from serviceinfo discovery values.
2693
+ newRemoteName:str = zeroconfDiscoveryResult.DeviceName
2694
+ newDeviceId:str = self.GetSpotifyDeviceIDFromName(newRemoteName)
2695
+
2696
+ # update zeroconf discovery result properties in the base device object.
2536
2697
  scDevice.DiscoveryResult = zeroconfDiscoveryResult
2537
2698
 
2538
- # did the device name change? if so, then update name and id properties,
2539
- # as well as the corresponding getInfo properties.
2540
- if (scDevice.Name != zeroconfDiscoveryResult.DeviceName):
2541
- newDeviceName:str = zeroconfDiscoveryResult.DeviceName
2542
- newDeviceId:str = self.GetSpotifyDeviceIDFromName(zeroconfDiscoveryResult.DeviceName)
2543
- _logsi.LogVerbose("Spotify Connect Zeroconf SpotifyConnectDevice entry name and id changed from %s to \"%s\" (%s)" % (scDevice.Title, newDeviceName, newDeviceId))
2544
- scDevice.Name = newDeviceName
2699
+ # did the device remote name change? if so, then update base device properties.
2700
+ if (oldRemoteName != newRemoteName):
2701
+ _logsi.LogVerbose("Spotify Connect Zeroconf device RemoteNameAlias changed from \"%s\" to \"%s\"" % (oldRemoteName, newRemoteName))
2702
+ scDevice.Name = newRemoteName
2703
+ scDevice.DeviceInfo.RemoteName = newRemoteName
2704
+
2705
+ # did the device id change?
2706
+ if (oldDeviceId != newDeviceId):
2707
+ _logsi.LogVerbose("Spotify Connect Zeroconf device Id changed from \"%s\" to \"%s\"" % (oldDeviceId, newDeviceId))
2545
2708
  scDevice.Id = newDeviceId
2546
2709
  scDevice.DeviceInfo.DeviceId = newDeviceId
2547
- scDevice.DeviceInfo.RemoteName = newDeviceName
2710
+
2711
+ # did the device zeroconf server listener port change?
2712
+ if (oldHostIpPort != zeroconfDiscoveryResult.HostIpPort):
2713
+ _logsi.LogVerbose("Spotify Connect Zeroconf device HostIpPort changed from \"%s\" to \"%s\"" % (oldHostIpPort, zeroconfDiscoveryResult.HostIpPort))
2548
2714
 
2549
2715
  # update existing Spotify Connect Device in devices collection.
2550
2716
  self._SpotifyConnectDevices.Items[idx] = scDevice
@@ -2576,6 +2742,10 @@ class SpotifyConnectDirectoryTask(threading.Thread):
2576
2742
 
2577
2743
  finally:
2578
2744
 
2745
+ # free resources.
2746
+ if (zconn is not None):
2747
+ zconn = None
2748
+
2579
2749
  # trace.
2580
2750
  _logsi.LeaveMethod(SILevel.Debug)
2581
2751
 
@@ -393,7 +393,7 @@ class SpotifyConnectZeroconfCastAppTask(threading.Thread):
393
393
  loginId:str,
394
394
  ) -> SpotifyAuthToken:
395
395
  """
396
- Retrieve Spotify Desktop authorrization access token from the token cache file.
396
+ Retrieve Spotify Desktop authorization access token from the token cache file.
397
397
  The resulting token will be used to launch the Spotify cast app.
398
398
  """
399
399
  apiMethodName:str = '_GetSpotifyDesktopAuthorizationToken'
@@ -91,10 +91,10 @@ class SpotifyConnectZeroconfCastListener(AbstractCastListener):
91
91
 
92
92
  try:
93
93
 
94
- # is this an MDNSServiceInfo service record? we only want discovery results
95
- # that contain MDNSServiceInfo service information.
94
+ # is this an GoogleCast service record? we only want discovery results
95
+ # that contain GoogleCast service information.
96
96
  if (serviceName.find(ZEROCONF_SERVICETYPE_GOOGLECAST) == -1):
97
- _logsi.LogDebug("Chromecast Zeroconf discovery service notification: \"%s\" (%s)" % (serviceName, "ignored; not MDNSInfo"))
97
+ _logsi.LogDebug("Chromecast Zeroconf discovery service notification: \"%s\" (%s)" % (serviceName, "ignored; not GoogleCast service type"))
98
98
  return None
99
99
 
100
100
  # get chromecast info.
@@ -113,9 +113,9 @@ class SpotifyConnectZeroconfCastMultiZoneManagerListener(MultiZoneManagerListene
113
113
  # trace.
114
114
  _logsi.LogVerbose("Chromecast multizone manager added device \"%s\" to multizone group %s" % (self._CastDevice.cast_info.friendly_name, scDevice.Title), colorValue=SIColors.Lavender)
115
115
 
116
- # # get the current multizone status.
117
- # castMultiZoneStatus:MultizoneStatus = get_multizone_status(scDevice.DiscoveryResult.HostIpAddress, self._CastDevice.cast_info.services, self._ZeroconfInstance, 5)
118
- # _logsi.LogObject(SILevel.Verbose, "Chromecast multizone manager status for group: %s [%s] (get_multizone_status)" % (scDevice.Title, scDevice.DiscoveryResult.HostIpTitle), castMultiZoneStatus, colorValue=SIColors.Lavender)
116
+ # get the current multizone status.
117
+ castMultiZoneStatus:MultizoneStatus = get_multizone_status(scDevice.DiscoveryResult.HostIpAddress, self._CastDevice.cast_info.services, self._ZeroconfInstance, 5)
118
+ _logsi.LogObject(SILevel.Verbose, "Chromecast multizone manager status for group: %s [%s] (get_multizone_status)" % (scDevice.Title, scDevice.DiscoveryResult.HostIpTitle), castMultiZoneStatus, colorValue=SIColors.Lavender)
119
119
 
120
120
  # # build member list with friendly names.
121
121
  # result:list[str] = []
@@ -185,9 +185,9 @@ class SpotifyConnectZeroconfCastMultiZoneManagerListener(MultiZoneManagerListene
185
185
  # trace.
186
186
  _logsi.LogVerbose("Chromecast multizone manager removed device \"%s\" from multizone group %s" % (self._CastDevice.cast_info.friendly_name, scDevice.Title), colorValue=SIColors.Lavender)
187
187
 
188
- # # get the current multizone status.
189
- # castMultiZoneStatus:MultizoneStatus = get_multizone_status(scDevice.DiscoveryResult.HostIpAddress, self._CastDevice.cast_info.services, self._ZeroconfInstance, 5)
190
- # _logsi.LogObject(SILevel.Verbose, "Chromecast multizone manager status for group: %s [%s] (get_multizone_status)" % (scDevice.Title, scDevice.DiscoveryResult.HostIpTitle), castMultiZoneStatus, colorValue=SIColors.Lavender)
188
+ # get the current multizone status.
189
+ castMultiZoneStatus:MultizoneStatus = get_multizone_status(scDevice.DiscoveryResult.HostIpAddress, self._CastDevice.cast_info.services, self._ZeroconfInstance, 5)
190
+ _logsi.LogObject(SILevel.Verbose, "Chromecast multizone manager status for group: %s [%s] (get_multizone_status)" % (scDevice.Title, scDevice.DiscoveryResult.HostIpTitle), castMultiZoneStatus, colorValue=SIColors.Lavender)
191
191
 
192
192
  # # build member list with friendly names.
193
193
  # result:list[str] = []
@@ -1497,7 +1497,7 @@ class ZeroconfConnect:
1497
1497
  result = ZeroconfGetInfo(root=responseData)
1498
1498
 
1499
1499
  # trace.
1500
- _logsi.LogObject(SILevel.Verbose, '%s result (%s) - "%s" (%s)' % (apiMethodName, type(result).__name__, result.RemoteName, result.DeviceId), result, excludeNonPublic=True)
1500
+ _logsi.LogObject(SILevel.Verbose, '%s result (%s) - "%s" (%s)' % (apiMethodName, type(result).__name__, result.RemoteNameOrAlias, result.DeviceId), result, excludeNonPublic=True)
1501
1501
 
1502
1502
  # if result status is not ok, then raise an exception.
1503
1503
  if (result.Status != 101):
@@ -373,6 +373,32 @@ class ZeroconfGetInfo(ZeroconfResponse):
373
373
  if (isinstance(value, str)) or (value is None):
374
374
  self._RemoteName = value
375
375
 
376
+ @property
377
+ def RemoteNameOrAlias(self) -> str:
378
+ """
379
+ Name to be displayed for the device (e.g. "BOSE-ST10-1").
380
+
381
+ If a RemoteName value is not defined, then the first alias name will be
382
+ returned if one is defined.
383
+
384
+ This value will be null if the response does not contain a RemoteName value
385
+ and there are no Aliases defined.
386
+ """
387
+ if (self._RemoteName is not None) and ((self._RemoteName + "").strip() != ""):
388
+
389
+ # if remote name is defined, then return it.
390
+ return self._RemoteName
391
+
392
+ elif (self.HasAliases):
393
+
394
+ # if aliases are defined then return the first alias name.
395
+ return self._Aliases[0].Name
396
+
397
+ else:
398
+
399
+ # otherwise return null.
400
+ return None
401
+
376
402
 
377
403
  @property
378
404
  def ResolverVersion(self) -> str:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spotifywebapipython
3
- Version: 1.0.291
3
+ Version: 1.0.293
4
4
  Summary: Spotify Web API Python3 Library
5
5
  Author: Todd Lucas
6
6
  Author-email: <thlucas@yahoo.com>
@@ -1,5 +1,5 @@
1
1
  spotifywebapipython/__init__.py,sha256=ka7F2AsT-UU7KSYKBnfgl5Trojcep5aQspLutg8D-2k,1306
2
- spotifywebapipython/const.py,sha256=9rxbLXDJzw59PqLGMStvH0LkKUskUKJIzK6NZIPobv8,4100
2
+ spotifywebapipython/const.py,sha256=-MK2XDNRlk4nSX1I6Twnb2dFpTTmbjhhG-pUuU7EVJ8,4100
3
3
  spotifywebapipython/saappmessages.py,sha256=mVprjpd5CdD8kYeAkLzRvMvIQPmaYtH4UCP5my3QhSk,5065
4
4
  spotifywebapipython/sautils.py,sha256=LZF3UvxaBK35WIg1hO37nbW8j1y-M-oOxRbi1dPR39w,8746
5
5
  spotifywebapipython/spotifyapierror.py,sha256=23_CYlxWN0BceYYCLpBpunl55vEwPr_wFf34l74xzeA,1855
@@ -12,25 +12,25 @@ spotifywebapipython/spotifytypeprefixes.py,sha256=3yfpxKF7jF694qBuo-PbKYvm70Ywwd
12
12
  spotifywebapipython/spotifywebapiauthenticationerror.py,sha256=5A0MKvYo3Ypv0ZeSSfLHuFLwzoUUu044bBoUgMfNXNw,3940
13
13
  spotifywebapipython/spotifywebapierror.py,sha256=ctYFvkBPlFFEoM_geP6hzwTyC2mPcrYR_zCCNvsmpwc,3870
14
14
  spotifywebapipython/spotifywebplayertoken.py,sha256=axj1j1lM7COiiZfpElkJRdnk4AmE6bAQcjKshUIz1Nk,35813
15
- spotifywebapipython/docs/__init__.html,sha256=OX7Z3pRXsrJcE4dBZRfUTH7FlNbO2VQ0Q5s-rA6IhcY,198988
15
+ spotifywebapipython/docs/__init__.html,sha256=BbgVYepvDBcuFDlCXiaHEL7zC_AOhE_wzbaSQSHHdZA,199550
16
16
  spotifywebapipython/docs/codecopy.js,sha256=ryuoZwLIL03YitjjFzn49UO5ta7-OBos6LNA3qHhFzs,3120
17
- spotifywebapipython/docs/index.html,sha256=9ZmFtMMTnfqR4NkitgtGJmsuW2l9GV1mJ6os-aYIoIw,48779
18
- spotifywebapipython/docs/search.js,sha256=KcFmbSXBMAfALhzhRUwaTIRPxITkF2ivdOmvnHzARUY,9270564
17
+ spotifywebapipython/docs/index.html,sha256=G7d3zqwSjXIfUzejBK7Mq8mXp5p_jPHibD-fZDdnCQQ,48779
18
+ spotifywebapipython/docs/search.js,sha256=NBEMS22T3h_v3zyLYwTxdYfPjP6DjkGzjwtAiOTBPDM,9277254
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=PS0xTZ34rhZubp1VAaBjjv2Mjf3JGWAoum4lmiHv_hk,60537
22
- spotifywebapipython/docs/spotifywebapipython/saappmessages.html,sha256=raoXyKvcqByUSpSvg5_pOMGMoOT98zcpftn-cmlemfY,62358
23
- spotifywebapipython/docs/spotifywebapipython/sautils.html,sha256=Q5W9gw4WcY1XLUTPEgN56ECzAa_CBMMdC7qH785c2KQ,62031
24
- spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html,sha256=7z-HLVGR2P2fwkcbRa7Kz5r0eA-odNKuFckzeZ4uTyw,48054
25
- spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html,sha256=uLgREDOLTsL6F_4FK9o4c7O2wObx4_alu1xkgt-h5zk,59210
26
- spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html,sha256=VfwPlgMxAySKKpvkp251sJNU2G4oB9PkhHiKktiB68U,59256
27
- spotifywebapipython/docs/spotifywebapipython/spotifyclient.html,sha256=1nyFxawfaYQWnFaDSN_jz6qLSVZJVr-LfMnXbl1U36g,1677607
28
- spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html,sha256=_vzsXcHeKt-EWYuh6lhzS8XSBjgK09hsSpxH_tAlyYY,57662
29
- spotifywebapipython/docs/spotifywebapipython/spotifymediatypes.html,sha256=Ww9rwoFzo_fIOpFDRZRtjzwkDLu1pT6dCxdJMV6j83Y,51532
30
- spotifywebapipython/docs/spotifywebapipython/spotifytypeprefixes.html,sha256=swnWdRAYQlg8LyF1c6mszS-lRGSoCkmF7U7PHxHTZ7A,52401
31
- spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html,sha256=NzuEKI_dRNulmxcaIjCUl1XtVjR2kadYfRq7p7AijEs,52174
32
- spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html,sha256=gYmQbrluxncvtp7burBIdyrCkOWgh6_C4YiUPZ-HirM,51484
33
- spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html,sha256=7lUnYtwT-eXg7EYThoU0KZd1jHX7amol1JVmA-fRKf4,62204
21
+ spotifywebapipython/docs/spotifywebapipython/const.html,sha256=8ChDCvi6QQPh53FVTeAu3WvbcBcH9WULzCO-G-KYJ0s,60537
22
+ spotifywebapipython/docs/spotifywebapipython/saappmessages.html,sha256=DFbB_WMia4awIQRDgVsK_X8TcdAfskruROq2uls9Lfw,62358
23
+ spotifywebapipython/docs/spotifywebapipython/sautils.html,sha256=r22R4943nFwfNOlwbOGOVOJ8V9nGyf77gHeuYDbn01Y,62031
24
+ spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html,sha256=zk6ISCkMNVot-9B2nN4DYsbZofqXEoadk4i2eV97L0c,48054
25
+ spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html,sha256=bSh2AebWNGHHO7kApEKDGjOgrj8JCnlx1Se39XZ1O2U,59210
26
+ spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html,sha256=zjxALxnn7mDoPVLFPZXM0jdpoOS-CoaHvLLl4e2WnBs,59256
27
+ spotifywebapipython/docs/spotifywebapipython/spotifyclient.html,sha256=RsHNAUyjZIN2tEOSADjNX2CGow3RLeftgqLCgluoanM,1677607
28
+ spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html,sha256=gN5dBTv6fmQloEQgRpSw2bKuMQu9eksb_2BYYUPgJZY,57662
29
+ spotifywebapipython/docs/spotifywebapipython/spotifymediatypes.html,sha256=oy0ohUZbpNGqAf51EdnuwtwRpLzHhr2bRDa_DxbuHuc,51532
30
+ spotifywebapipython/docs/spotifywebapipython/spotifytypeprefixes.html,sha256=7qGYuGomj0QLXxSXNiLlQAkyHyzs4R4WiMVyzFn3kkw,52401
31
+ spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html,sha256=NEZDhVACveFhv1xWKJcT9pj1C5CGHgxlWslMKKcfeFQ,52174
32
+ spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html,sha256=n0bFI8907vW8ApggdbpCtPW_M6_gzGx4LgPL9WqpRA8,51484
33
+ spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html,sha256=HqxGXcIapwRbcHvR4lGTRkG4xdn-xrFXr9TZ1Bx8o28,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
@@ -110,12 +110,12 @@ spotifywebapipython/oauthcli/__init__.py,sha256=K37XTxYAKT0n8otCNzWbjgJ10fAPN4WL
110
110
  spotifywebapipython/oauthcli/authclient.py,sha256=qGKa4FLBHHZQyP5ho1sIM_mNmyshQd720YwKcUFQJAw,56207
111
111
  spotifywebapipython/spotifyconnect/__init__.py,sha256=9Xl5KiJFvWLbsdb4YQ0xmF67i36ybpXCCXrWeNsKEvc,1108
112
112
  spotifywebapipython/spotifyconnect/spotifyconnectdeviceeventargs.py,sha256=35hKa0FAaPgy7W8D6MFXmga667pjwXITo8jSj1TDfE8,1988
113
- spotifywebapipython/spotifyconnect/spotifyconnectdirectorytask.py,sha256=Lfaek_fB2UgM1cYmDz8DNLUXcGHJywLYt7EG4ONzLoc,154671
114
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastapptask.py,sha256=tCjqU7ubtfzBENdvqwVB0pMDGHRY_0u6N5OYlI5hbj8,23368
113
+ spotifywebapipython/spotifyconnect/spotifyconnectdirectorytask.py,sha256=1VQG5qY0mSoi0wdPV0ltOrzjtsLlAi79D-br1ve41nE,163817
114
+ spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastapptask.py,sha256=jArxsjAGntTcQD9L9yVuey1L8pw0KvshlNXIBA7PqiI,23367
115
115
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastcontroller.py,sha256=e2wLmFq4393IdVa51w8X5UQl4KfnHRh34DMlxZfl9-g,34218
116
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastlistener.py,sha256=k_Lw52CqNliCrfqMP6s_BHynqHYBOf_NwdrJru6qDFA,16707
116
+ spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastlistener.py,sha256=EBrKZfkiAY-_UiEBXCa7sPpH1lip4Gz1bNwT1fWc1LE,16712
117
117
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastmultizonecontrollerlistener.py,sha256=AA-XxS6AptJWzyO2zsM9DA5ioCncJBKDTpJkr_aN9IM,12352
118
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastmultizonemanagerlistener.py,sha256=k3wMC80Z7jBXYwiw9jq-oixRsum7E_vdHzwEgvcGbiw,18918
118
+ spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastmultizonemanagerlistener.py,sha256=gA-R7nR5cRbHrLVEGIRQILry72MSVpub4pNW-DZHWRY,18906
119
119
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconfexceptions.py,sha256=aesGauxMoKupdTPR5rL2-rXBC3SEvH_9bQQx2Vh-abs,524
120
120
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconflistener.py,sha256=ciN31zub2gk9On-1Gf7xDQpOdCEA3mutYIXpVfuA-w0,16583
121
121
  spotifywebapipython/vibrant/__init__.py,sha256=x3yGfhH0ydjWTSILADuwQXaoLvpkV2EM0T_gyZ5aX38,712
@@ -132,13 +132,13 @@ spotifywebapipython/zeroconfapi/credentials.py,sha256=MIXqZvFNDjoICpZGNXPveHNl9G
132
132
  spotifywebapipython/zeroconfapi/cryptodiffiehellman.py,sha256=k-nMR68GtzODYsQrwCpvFE2XNxv-XUFbMemplldtwp4,3340
133
133
  spotifywebapipython/zeroconfapi/helpers.py,sha256=9lJFOuKYrk-e7SbU94WmFv5oiBq4k5gMS8wE1it4Wbc,1429
134
134
  spotifywebapipython/zeroconfapi/spotifyzeroconfapierror.py,sha256=rTwIrr1qV0UiQS_zBufboyZ3A3yGrdCsTAOiVA5dvzY,3031
135
- spotifywebapipython/zeroconfapi/zeroconfconnect.py,sha256=CypMdxMg2GxlXAnkjHh7kQHrtUUxt_RzIlHh9IOSj9A,79016
136
- spotifywebapipython/zeroconfapi/zeroconfgetinfo.py,sha256=APayso_F7lCsdzzrkescgd-nKukUah3Kjfs-5F2tnvU,21415
135
+ spotifywebapipython/zeroconfapi/zeroconfconnect.py,sha256=JzAKVc7XC_HrTH1IwsuXpcgW0rFlRYocHL8likoYYvQ,79023
136
+ spotifywebapipython/zeroconfapi/zeroconfgetinfo.py,sha256=gTr3J3iVDR_ueP1tg-WHuCOke3eP864WGiESmOOYFUw,22243
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.291.dist-info/LICENSE,sha256=KGcc9g0zwqNLcWnSn_ezv1UtKyhMENFhvtixpxUPNsE,1177
141
- spotifywebapipython-1.0.291.dist-info/METADATA,sha256=7JA6EKAqbQ6RKhUnyJ0w5nx5sJUdLcLa3Ooui-9egz8,11644
142
- spotifywebapipython-1.0.291.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
143
- spotifywebapipython-1.0.291.dist-info/top_level.txt,sha256=jTBLFlijKTesYh2dteAz4vb17qjaqWKeDjpnnwTcrjs,20
144
- spotifywebapipython-1.0.291.dist-info/RECORD,,
140
+ spotifywebapipython-1.0.293.dist-info/LICENSE,sha256=KGcc9g0zwqNLcWnSn_ezv1UtKyhMENFhvtixpxUPNsE,1177
141
+ spotifywebapipython-1.0.293.dist-info/METADATA,sha256=U63TtXsVnTIqv8ziG-gLeCbHLU70sHMVNWpP9Xur2ls,11644
142
+ spotifywebapipython-1.0.293.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
143
+ spotifywebapipython-1.0.293.dist-info/top_level.txt,sha256=jTBLFlijKTesYh2dteAz4vb17qjaqWKeDjpnnwTcrjs,20
144
+ spotifywebapipython-1.0.293.dist-info/RECORD,,