spotifywebapiPython 1.0.293__py3-none-any.whl → 1.0.294__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 (24) hide show
  1. spotifywebapipython/const.py +1 -1
  2. spotifywebapipython/docs/__init__.html +9 -3
  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 +137 -70
  19. spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastlistener.py +1 -1
  20. {spotifywebapipython-1.0.293.dist-info → spotifywebapipython-1.0.294.dist-info}/METADATA +1 -1
  21. {spotifywebapipython-1.0.293.dist-info → spotifywebapipython-1.0.294.dist-info}/RECORD +24 -24
  22. {spotifywebapipython-1.0.293.dist-info → spotifywebapipython-1.0.294.dist-info}/LICENSE +0 -0
  23. {spotifywebapipython-1.0.293.dist-info → spotifywebapipython-1.0.294.dist-info}/WHEEL +0 -0
  24. {spotifywebapipython-1.0.293.dist-info → spotifywebapipython-1.0.294.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
1
1
  # external package imports.
2
2
  from abc import abstractmethod
3
3
  import copy
4
+ from collections import Counter
4
5
  from datetime import datetime
5
6
  import hashlib
6
7
  from pychromecast import APP_MEDIA_RECEIVER, CastBrowser, CastInfo, Chromecast, get_chromecast_from_cast_info, get_chromecast_from_host
@@ -512,7 +513,6 @@ class SpotifyConnectDirectoryTask(threading.Thread):
512
513
  def _VerifyMultizoneGroupLeader(
513
514
  self,
514
515
  scDevice: SpotifyConnectDevice,
515
- discoveryResult: ZeroconfDiscoveryResult,
516
516
  ) -> None:
517
517
  """
518
518
  Verifies the current leader for a cast group is connected and available.
@@ -520,94 +520,169 @@ class SpotifyConnectDirectoryTask(threading.Thread):
520
520
  Args:
521
521
  scDevice (SpotifyConnectDevice):
522
522
  SpotifyConnectDevice object that contains discovery result details.
523
- discoveryResult (ZeroconfDiscoveryResult):
524
- Newly discovered zeroconf updates for the device.
523
+
524
+ This method should be called from a method that syncronizes access via lock
525
+ (using `self._SpotifyConnectDevices_RLock`), as it could possibly modify the
526
+ SpotifyConnectDevices collection.
525
527
  """
528
+
529
+ member_summary:list[str] = []
530
+ member_hosts:list[str] = []
531
+ timeout:float = 2.0
532
+ group_uuid:UUID = UUID(scDevice.DiscoveryResult.Key)
533
+
526
534
  try:
527
535
 
528
- leaderIP:str|None = None
536
+ # get a list of device IP addresses that are members of the group, and also log
537
+ # a user-friendly trace line for debugging.
529
538
 
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.
539
+ # trace.
540
+ _logsi.LogObject(SILevel.Verbose, "Verifying Chromecast Multizone group leader for Cast Group: %s [UUID=%s]" % (scDevice.Title, group_uuid), scDevice.DiscoveryResult, excludeNonPublic=True, colorValue=SIColors.Coral)
533
541
 
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.
542
+ # get multizone controller reference for the group.
543
+ castMultizoneController:MultizoneController = self._CastMultiZoneControllers.get(str(group_uuid), None)
544
+ if (castMultizoneController is not None):
538
545
 
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):
546
+ # process all members, building a list of their host addresses.
547
+ for member in castMultizoneController.members:
548
+ scMemberDevice:SpotifyConnectDevice = self._SpotifyConnectDevices.GetDeviceByDiscoveryKey(member)
549
+ if (scMemberDevice is None):
550
+ member_summary.append(member)
551
+ else:
552
+ member_summary.append("%s [ip=%s]" % (scMemberDevice.Title, scMemberDevice.DiscoveryResult.HostIpTitle))
553
+ member_hosts.append(scMemberDevice.DiscoveryResult.HostIpAddress)
542
554
 
543
- # get the assumed group leader device reference.
544
- castDevice:Chromecast = groupInfo.get('chromecast', None)
545
- if (castDevice):
555
+ # trace.
556
+ _logsi.LogArray(SILevel.Verbose, "Chromecast Multizone group member summary: \"%s\" (count=%d)" % (scDevice.Title, len(member_summary)), member_summary, colorValue=SIColors.Coral)
546
557
 
547
- if (castDevice.socket_client) and (castDevice.socket_client.is_connected):
548
- leaderIP = castDevice.socket_client.host
558
+ # process each member in the group, retrieving it's multi-zone status.
549
559
 
550
- elif (castDevice.cast_info):
551
- leaderIP = castDevice.cast_info.host
560
+ votes: Counter[str] = Counter()
561
+ port_for: dict[str, int] = {}
552
562
 
553
- # do we have a group leader conflict between the multizone manager
554
- # reference and the mDNS service update?
555
- if (leaderIP != discoveryResult.HostIpAddress):
563
+ for host in member_hosts:
556
564
 
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.
565
+ # trace.
566
+ _logsi.LogVerbose("Retrieving Chromecast Multizone group status for member host: %s" % (host), colorValue=SIColors.Coral)
560
567
 
561
- # trace.
562
- _logsi.LogVerbose("Group leader conflict detected for device UUID: \"%s\"" % discoveryResult.Key)
568
+ # get multizone status for the specified group member.
569
+ # note that `get_multizone_status` can return both IPV4 (e.g. "192.168.1.97") and IPV6 (e.g. "::ffff:c0a8:161") addresses!
570
+ status = get_multizone_status(host, timeout=timeout)
563
571
 
564
- try:
572
+ # trace.
573
+ _logsi.LogDictionary(SILevel.Verbose, "Chromecast Multizone group status for member host: %s" % (host), status, prettyPrint=True, colorValue=SIColors.Coral)
574
+
575
+ # if we could not retrieve status, then move on to the next group member.
576
+ if status is None:
577
+ continue
578
+
579
+ # add to the vote count for this host address.
580
+ # a member that is the LEADER answers with its own host and the group's cast_port;
581
+ # a member that is a FOLLOWER answers with the leader's host and no port (pychromecast
582
+ # strips the ':10001' multizone port); right after a re-form, a single member can still
583
+ # say 'self' although it no longer leads, so take the majority.
584
+ for g in status.groups:
585
+ if g.uuid == group_uuid and g.host:
586
+ votes[g.host] += 1
587
+ if g.port:
588
+ port_for[g.host] = g.port
589
+
590
+ # add to the vote count for this host address for dynamic groups as well.
591
+ for g in status.dynamic_groups:
592
+ if g.uuid == group_uuid and g.host:
593
+ votes[g.host] += 1
594
+ if g.port:
595
+ port_for[g.host] = g.port
565
596
 
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)
597
+ # trace.
598
+ _logsi.LogCollection(SILevel.Verbose, "Chromecast Multizone group leader vote summary for Cast Group: %s [UUID=%s]" % (scDevice.Title, group_uuid), votes.most_common(), colorValue=SIColors.Coral)
573
599
 
574
- # if connection was successful, then use it as the leader.
575
- leaderIP = discoveryResult.HostIpAddress
600
+ # we will now verify connectivity to all devices that were resolved
601
+ # as group leaders from the various group members. in most cases, this
602
+ # should be just one device, if they all reported the same leader.
603
+ # if multiple leaders were reported (this can happen while the group is
604
+ # in the midst of reforming), then we will use the host address that was
605
+ # reported the most, using the host address that was reported the least
606
+ # as a fallback in case we could not connect to the most-used address.
576
607
 
577
- except Exception as ex:
608
+ # process all reported leaders, using most reported host address first.
609
+ for host, _ in votes.most_common():
578
610
 
579
- try:
611
+ # trace.
612
+ _logsi.LogVerbose("Verifying connectivity to Chromecast Multizone group leader: %s" % (host), colorValue=SIColors.Coral)
580
613
 
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)
614
+ # ensure we resolved a port for this host.
615
+ port = port_for.get(host)
616
+ if port is None:
588
617
 
589
- # if connection was successful, then use it as the leader.
590
- leaderIP = leaderIP
618
+ # if a port was not resolved for this host, then it points at a host we have not
619
+ # retrieved multizone status for yet - ask it for its port.
591
620
 
592
- except Exception as ex:
621
+ # trace.
622
+ _logsi.LogVerbose("Retrieving Chromecast Multizone group status for member host: %s" % (host), colorValue=SIColors.Coral)
593
623
 
594
- _logsi.LogVerbose("Could not connect to either possible Cast Group leader for device: \"%s\"" % (scDevice.Title))
624
+ # get multizone status for the specified group member.
625
+ # note that `get_multizone_status` can return both IPV4 (e.g. "192.168.1.97") and IPV6 (e.g. "::ffff:c0a8:161") addresses!
626
+ status = get_multizone_status(host, timeout=timeout)
595
627
 
596
- # free resources.
597
- castDevice = None
628
+ # trace.
629
+ _logsi.LogDictionary(SILevel.Verbose, "Chromecast Multizone group status for member host: %s" % (host), status, prettyPrint=True, colorValue=SIColors.Coral)
598
630
 
599
- # do we have a group leader change?
600
- if (leaderIP != scDevice.DiscoveryResult.HostIpAddress):
631
+ if status:
632
+ for g in status.groups:
633
+ if g.uuid == group_uuid and g.host == host and g.port:
634
+ port = g.port
635
+ for g in status.dynamic_groups:
636
+ if g.uuid == group_uuid and g.host == host and g.port:
637
+ port = g.port
638
+
639
+ # verify connectivity if we have a port for this host.
640
+ if port:
641
+
642
+ try:
601
643
 
602
644
  # 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)
645
+ _logsi.LogVerbose("Verifying connection to Chromecast Multizone group leader host candidate: ip=%s, port=%s" % (host, port), colorValue=SIColors.Coral)
646
+
647
+ # connect to the host on the designated port. this should return almost
648
+ # immediately if the device is found on the local network.
649
+ with socket.create_connection((host, port), timeout=timeout):
650
+
651
+ # if it's a good socket connection, then we will treat this host as the
652
+ # group leader; update the devices collection if the addresses are different.
653
+ if (host != scDevice.DiscoveryResult.HostIpAddress):
654
+
655
+ # note that we only care about IPV4 addresses, as `get_multizone_status`
656
+ # can return both IPV4 and IPV6 addresses.
657
+ if (host.count(":")) > 1: # IPV6 address?
658
+ _logsi.LogVerbose("Ignoring Chromecast Multizone group leader candidate address: %s (IPV6 address)" % (host), colorValue=SIColors.Coral)
659
+ else:
660
+ _logsi.LogObject(SILevel.Verbose, "Cast Group leader IP was changed from [%s] to [%s] for Cast Group \"%s\"" % (scDevice.DiscoveryResult.HostIpAddress, host, scDevice.Name), scDevice.DiscoveryResult, excludeNonPublic=True, colorValue=SIColors.ForestGreen)
661
+ scDevice.DiscoveryResult.HostIpAddress = host
662
+ scDevice.DiscoveryResult.Id = "\"%s\" (%s:%s)" % (scDevice.DiscoveryResult.DeviceName, scDevice.DiscoveryResult.HostIpAddress, scDevice.DiscoveryResult.HostIpPort)
663
+
664
+ # connection was good; we are done here.
665
+ _logsi.LogVerbose("Chromecast Multizone group leader host was verified for Cast Group: \"%s\" [%s:%s]" % (scDevice.Name, host, port), colorValue=SIColors.Coral)
666
+ return
667
+
668
+ except Exception as ex:
669
+
670
+ # trace.
671
+ _logsi.LogException("Chromecast Group member [ip=%s, port=%s] could not be reached; moving on to next host" % (host, port, str(ex)), ex, logToSystemLogger=False)
672
+ # ignore exception and check the next available host
673
+
674
+ else:
675
+ _logsi.LogVerbose("Ignoring Chromecast Multizone group leader address: %s (port not found)" % (host), colorValue=SIColors.Coral)
676
+
677
+ # if we make it here, then the cast group leader could not be verified!
678
+
679
+ # trace.
680
+ _logsi.LogVerbose("Could not verify Chromecast Multizone group leader for Cast Group: %s [UUID=%s] - existing host [ip=%s] will be used" % (scDevice.Title, group_uuid, scDevice.DiscoveryResult.HostIpTitle), colorValue=SIColors.Coral)
606
681
 
607
682
  except Exception as ex:
608
683
 
609
684
  # trace.
610
- _logsi.LogException("Chromecast Multizone group leader query exception: %s" % (str(ex)), ex, logToSystemLogger=False)
685
+ _logsi.LogException("Chromecast Multizone group leader verification exception: %s" % (str(ex)), ex, logToSystemLogger=False)
611
686
  # ignore exception, as nothing can be done about it.
612
687
 
613
688
 
@@ -693,7 +768,7 @@ class SpotifyConnectDirectoryTask(threading.Thread):
693
768
 
694
769
  # verify the current leader of the group.
695
770
  # the device collection entry will be updated if a change was detected.
696
- self._VerifyMultizoneGroupLeader(scDevice, scDevice.DiscoveryResult)
771
+ self._VerifyMultizoneGroupLeader(scDevice)
697
772
 
698
773
  # is this a chromecast device?
699
774
  if (not scDevice.IsChromeCast):
@@ -867,14 +942,6 @@ class SpotifyConnectDirectoryTask(threading.Thread):
867
942
  retry_wait=0.5,
868
943
  timeout=10)
869
944
 
870
- # don't need this anymore, since we are activating media receiver on each group member.
871
- # left it in here just in case we change our mind.
872
- # # calculate wait timeout for devices to become active, based on number of devices in group.
873
- # if (castMultiZoneStatus.groups is not None):
874
- # groupCount:int = len(castMultiZoneStatus.groups)
875
- # if (groupCount > 1):
876
- # deviceWaitTimeoutSecs = (groupCount * 5.0)
877
-
878
945
  # trace.
879
946
  _logsi.LogVerbose("%s - Waiting %d seconds max for Chromecast group multizone device to activate: %s [ip=%s:%s]" % (self.name, deviceWaitTimeoutSecs, scDevice.Title, groupHost, groupPort), colorValue=SIColors.Coral)
880
947
 
@@ -2117,7 +2184,7 @@ class SpotifyConnectDirectoryTask(threading.Thread):
2117
2184
 
2118
2185
  # verify the current leader of the group.
2119
2186
  # the device collection entry will be updated if a change was detected.
2120
- self._VerifyMultizoneGroupLeader(scDevice, zeroconfDiscoveryResult)
2187
+ self._VerifyMultizoneGroupLeader(scDevice)
2121
2188
 
2122
2189
  # is this a Google Cast Group "update_cast" event?
2123
2190
  # if so, AND the device name did not change, then ignore the update since
@@ -149,7 +149,7 @@ class SpotifyConnectZeroconfCastListener(AbstractCastListener):
149
149
 
150
150
  # ensure IPV4 connection - ignore if IPV6.
151
151
  # Windows OS does not support dual-stack socket handling IPv4 (224.0.0.251) and IPv6 (ff02::fb).
152
- if (castInfoHost.count(":")) > 1:
152
+ if (castInfoHost.count(":")) > 1: #IPV6?
153
153
  _logsi.LogDebug("Chromecast IPV6 device addresses are not supported; device could cause problems: \"%s\" (%s)" % (castInfo.friendly_name, serviceName), colorValue=SIColors.Red)
154
154
 
155
155
  # will still allow this for now, but we might want to ignore IPV6 devices
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spotifywebapipython
3
- Version: 1.0.293
3
+ Version: 1.0.294
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=-MK2XDNRlk4nSX1I6Twnb2dFpTTmbjhhG-pUuU7EVJ8,4100
2
+ spotifywebapipython/const.py,sha256=oj5dY2U2uxxMLiZWij3jeY2VwZzmbqSiHdm1twX9ATw,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=BbgVYepvDBcuFDlCXiaHEL7zC_AOhE_wzbaSQSHHdZA,199550
15
+ spotifywebapipython/docs/__init__.html,sha256=FsnO64WP9HsImXs-AonCUUmUWEOlBajpYqhBYVcjNiE,199713
16
16
  spotifywebapipython/docs/codecopy.js,sha256=ryuoZwLIL03YitjjFzn49UO5ta7-OBos6LNA3qHhFzs,3120
17
- spotifywebapipython/docs/index.html,sha256=G7d3zqwSjXIfUzejBK7Mq8mXp5p_jPHibD-fZDdnCQQ,48779
18
- spotifywebapipython/docs/search.js,sha256=NBEMS22T3h_v3zyLYwTxdYfPjP6DjkGzjwtAiOTBPDM,9277254
17
+ spotifywebapipython/docs/index.html,sha256=rNcPZUg3v7qJZSaXOcuFERqwC5CEm260Kc91BEbXoSg,48779
18
+ spotifywebapipython/docs/search.js,sha256=xdiBYN4bciyd6hIKcrC6l9ySbFg0NjJ3bl6aAFns-7E,9277464
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=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
21
+ spotifywebapipython/docs/spotifywebapipython/const.html,sha256=IsLvA9DVCXJm0ahAFiFqH5fCP_LDErWOknP4_-fIP0w,60537
22
+ spotifywebapipython/docs/spotifywebapipython/saappmessages.html,sha256=5Q_EVCeeIak4bjbiBmzJt2f1P2u6dpRNq_mKWu9JEIs,62358
23
+ spotifywebapipython/docs/spotifywebapipython/sautils.html,sha256=-yv1l4IM__IVWHIIbzRUjCUC7rQJeR2OmDHQY64fH6U,62031
24
+ spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html,sha256=S_mHY212fy_lMKx_xakhFaNaOAI8nJclAnPpKnbSGLM,48054
25
+ spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html,sha256=eiFt3S4N5FtErC-lEnU39m3sA_ISEMr2YOU6EIDahTA,59210
26
+ spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html,sha256=ALxUxbPz9EUt6GxF3C1wghH3iKj-OCvOi1y5cdasaeE,59256
27
+ spotifywebapipython/docs/spotifywebapipython/spotifyclient.html,sha256=bKgbh_ERKgTKypnQH6Gk-M-YTZgk0ihitAhPJpZkaeo,1677607
28
+ spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.html,sha256=Nj2t95BtEXLAoVyzI-unE22CgqbPVzfhu3LEGrnJ5ug,57662
29
+ spotifywebapipython/docs/spotifywebapipython/spotifymediatypes.html,sha256=_Ntks24sCD3968HJtNHkN8IEnpgYW64hH69bY0EN7h0,51532
30
+ spotifywebapipython/docs/spotifywebapipython/spotifytypeprefixes.html,sha256=VccKsPzaqeN00S8Oz91yTetc4VKCfrAxHdm0C3T4ozg,52401
31
+ spotifywebapipython/docs/spotifywebapipython/spotifywebapiauthenticationerror.html,sha256=Z6TRDfiZ2ylfCkKaOGDEk5yoAE8-sc7OaX-GPIjeATM,52174
32
+ spotifywebapipython/docs/spotifywebapipython/spotifywebapierror.html,sha256=z16KGA-IX21EQBfVLw4woYLCMjJe837_mD3jRyYkwkE,51484
33
+ spotifywebapipython/docs/spotifywebapipython/spotifywebplayertoken.html,sha256=RtDWlyO3C3FlR7us4euXW29Spc99HRAw_JTLhJ52axc,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,10 +110,10 @@ 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=1VQG5qY0mSoi0wdPV0ltOrzjtsLlAi79D-br1ve41nE,163817
113
+ spotifywebapipython/spotifyconnect/spotifyconnectdirectorytask.py,sha256=Ha5Ht0PDaXNQJQxCcZEbu5SpDvETHcPgqbkr9l8WfhE,168043
114
114
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastapptask.py,sha256=jArxsjAGntTcQD9L9yVuey1L8pw0KvshlNXIBA7PqiI,23367
115
115
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastcontroller.py,sha256=e2wLmFq4393IdVa51w8X5UQl4KfnHRh34DMlxZfl9-g,34218
116
- spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastlistener.py,sha256=EBrKZfkiAY-_UiEBXCa7sPpH1lip4Gz1bNwT1fWc1LE,16712
116
+ spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastlistener.py,sha256=e7vKob2xim8H3BkxbgPj-eymftKvWgT71tzpskd0sn0,16720
117
117
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastmultizonecontrollerlistener.py,sha256=AA-XxS6AptJWzyO2zsM9DA5ioCncJBKDTpJkr_aN9IM,12352
118
118
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconfcastmultizonemanagerlistener.py,sha256=gA-R7nR5cRbHrLVEGIRQILry72MSVpub4pNW-DZHWRY,18906
119
119
  spotifywebapipython/spotifyconnect/spotifyconnectzeroconfexceptions.py,sha256=aesGauxMoKupdTPR5rL2-rXBC3SEvH_9bQQx2Vh-abs,524
@@ -137,8 +137,8 @@ spotifywebapipython/zeroconfapi/zeroconfgetinfo.py,sha256=gTr3J3iVDR_ueP1tg-WHuC
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.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,,
140
+ spotifywebapipython-1.0.294.dist-info/LICENSE,sha256=KGcc9g0zwqNLcWnSn_ezv1UtKyhMENFhvtixpxUPNsE,1177
141
+ spotifywebapipython-1.0.294.dist-info/METADATA,sha256=aNEmx_UG_r6U79DD-SDB6Fnswiu-1OQll8IW_BGmr6c,11644
142
+ spotifywebapipython-1.0.294.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
143
+ spotifywebapipython-1.0.294.dist-info/top_level.txt,sha256=jTBLFlijKTesYh2dteAz4vb17qjaqWKeDjpnnwTcrjs,20
144
+ spotifywebapipython-1.0.294.dist-info/RECORD,,