spotifywebapiPython 1.0.153__py3-none-any.whl → 1.0.154__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of spotifywebapiPython might be problematic. Click here for more details.

Files changed (21) hide show
  1. {spotifywebapiPython-1.0.153.dist-info → spotifywebapiPython-1.0.154.dist-info}/METADATA +1 -1
  2. {spotifywebapiPython-1.0.153.dist-info → spotifywebapiPython-1.0.154.dist-info}/RECORD +21 -21
  3. spotifywebapipython/const.py +1 -1
  4. spotifywebapipython/docs/__init__.html +9 -2
  5. spotifywebapipython/docs/index.html +2 -2
  6. spotifywebapipython/docs/search.js +1 -1
  7. spotifywebapipython/docs/spotifywebapipython/const.html +3 -3
  8. spotifywebapipython/docs/spotifywebapipython/saappmessages.html +2 -2
  9. spotifywebapipython/docs/spotifywebapipython/sautils.html +2 -2
  10. spotifywebapipython/docs/spotifywebapipython/spotifyapierror.html +2 -2
  11. spotifywebapipython/docs/spotifywebapipython/spotifyapimessage.html +2 -2
  12. spotifywebapipython/docs/spotifywebapipython/spotifyauthtoken.html +2 -2
  13. spotifywebapipython/docs/spotifywebapipython/spotifyclient.html +2 -2
  14. spotifywebapipython/docs/spotifywebapipython/spotifydiscovery.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/spotifyclient.py +179 -60
  19. {spotifywebapiPython-1.0.153.dist-info → spotifywebapiPython-1.0.154.dist-info}/LICENSE +0 -0
  20. {spotifywebapiPython-1.0.153.dist-info → spotifywebapiPython-1.0.154.dist-info}/WHEEL +0 -0
  21. {spotifywebapiPython-1.0.153.dist-info → spotifywebapiPython-1.0.154.dist-info}/top_level.txt +0 -0
@@ -10,6 +10,7 @@ from soco.core import (
10
10
  PLAY_MODE_BY_MEANING as SONOS_PLAY_MODE_BY_MEANING,
11
11
  PLAY_MODES as SONOS_PLAY_MODES,
12
12
  )
13
+ from soco.plugins.sharelink import ShareLinkPlugin
13
14
  import time
14
15
  from typing import Tuple, Callable, Union
15
16
  from urllib3 import PoolManager, Timeout, HTTPResponse
@@ -11697,36 +11698,117 @@ class SpotifyClient:
11697
11698
 
11698
11699
  # validations.
11699
11700
  delay = validateDelay(delay, 0.50, 10)
11701
+ if (positionMS is None) or (positionMS < 0):
11702
+ positionMS = 0
11703
+ if (offsetPosition is None) or (offsetPosition < 0):
11704
+ offsetPosition = 0
11700
11705
 
11701
11706
  # resolve / activate the device object if needed.
11702
11707
  scDevice = self._ResolveDeviceObject(deviceId, False)
11703
11708
 
11704
- # build spotify web api request parameters.
11705
- reqData:dict = \
11706
- {
11707
- 'context_uri': contextUri,
11708
- 'position_ms': positionMS
11709
- }
11710
- if offsetUri is not None:
11711
- reqData['offset'] = { 'uri': offsetUri }
11712
- elif offsetPosition is not None:
11713
- reqData['offset'] = { 'position': offsetPosition }
11709
+ # is this a Sonos device?
11710
+ if (scDevice is not None) and (scDevice.IsSonos):
11714
11711
 
11715
- # formulate url parms; will manually add them since we are adding json body as well.
11716
- urlParms:str = ''
11717
- if (scDevice is not None):
11718
- urlParms = '?device_id=%s' % scDevice.Id
11712
+ # trace.
11713
+ _logsi.LogVerbose("Context will be played on Sonos local queue for device: %s" % (scDevice.Title))
11714
+
11715
+ # Sonos cannot handle playing an artist context!
11716
+ # if this is an artist context, then we will get a list of the artist's albums
11717
+ # and add them to the queue.
11718
+ if (contextUri.find(':artist:') > -1):
11719
+ artistId:str = contextUri.replace('spotify:artist:','')
11720
+ #includeGroups:str = 'album,single,appears_on,compilation'
11721
+ includeGroups:str = 'album'
11722
+ _logsi.LogVerbose("Getting ALL albums for artist id: %s" % (artistId))
11723
+ pageObj:AlbumPageSimplified = self.GetArtistAlbums(artistId, includeGroups, limitTotal=75)
11724
+ contextUri:list = []
11725
+ albumSimplified:AlbumSimplified
11726
+ for albumSimplified in pageObj.Items:
11727
+ contextUri.append(albumSimplified.Uri)
11728
+
11729
+ # build a list of all item uri's.
11730
+ # remove any leading / trailing spaces in case user put a space between the items.
11731
+ arrUris:list[str] = None
11732
+ if isinstance(contextUri, list):
11733
+ arrUris = contextUri
11734
+ else:
11735
+ arrUris = contextUri.split(',')
11736
+ for idx in range(0, len(arrUris)):
11737
+ arrUris[idx] = arrUris[idx].strip()
11719
11738
 
11720
- # execute spotify web api request.
11721
- msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/player/play{url_parms}'.format(url_parms=urlParms))
11722
- msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
11723
- msg.RequestJson = reqData
11724
- self.MakeRequest('PUT', msg)
11739
+ # get the Sonos Controller player instance.
11740
+ sonosPlayer:SoCo = self.SpotifyConnectDirectory.GetSonosPlayer(scDevice)
11741
+
11742
+ # clear the Sonos local queue.
11743
+ _logsi.LogVerbose("Issuing command to Sonos device \"%s\": CLEAR_QUEUE" % (scDevice.Name))
11744
+ sonosPlayer.clear_queue()
11745
+
11746
+ # add all context items to the Sonos local queue.
11747
+ sharelink = ShareLinkPlugin(sonosPlayer)
11748
+ for idx in range(0, len(arrUris)):
11749
+
11750
+ # add context to the Sonos local queue.
11751
+ uri = arrUris[idx].strip()
11752
+ _logsi.LogVerbose("Issuing command to Sonos device \"%s\": ADD_SHARE_LINK_TO_QUEUE (uri=%s)" % (scDevice.Name, uri))
11753
+ sharelink.add_share_link_to_queue(uri)
11754
+
11755
+ # if this is the first item added, then start play of the queue as
11756
+ # it may take awhile to load the rest of the items.
11757
+ if (idx == 0):
11758
+
11759
+ # start playing the Sonos local queue.
11760
+ _logsi.LogVerbose("Issuing command to Sonos device \"%s\": PLAY_FROM_QUEUE (index=%s)" % (scDevice.Name, offsetPosition))
11761
+ sonosPlayer.play_from_queue(index=offsetPosition)
11762
+
11763
+ # # give Sonos Controller time to process the change.
11764
+ # if delay > 0:
11765
+ # _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE_SONOS % delay)
11766
+ # time.sleep(delay)
11767
+
11768
+ # was a track seek position specified?
11769
+ if (positionMS > 0):
11770
+
11771
+ # seek to the position in the track.
11772
+ sonosPosition:str = mediaPositionHMS_fromSeconds(positionMS / 1000) # convert from milliseconds to Sonos H:MM:SS format
11773
+ _logsi.LogVerbose("Issuing command to Sonos device \"%s\": SEEK (position=%s)" % (scDevice.Name, sonosPosition))
11774
+ sonosPlayer.seek(position=sonosPosition)
11775
+
11776
+ # give Sonos Controller time to process the change.
11777
+ if delay > 0:
11778
+ _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE_SONOS % delay)
11779
+ time.sleep(delay)
11780
+
11781
+ else:
11782
+
11783
+ # trace.
11784
+ _logsi.LogVerbose("Context will be played on the Spotify Connect device via Spotify Web API")
11785
+
11786
+ # build spotify web api request parameters.
11787
+ reqData:dict = \
11788
+ {
11789
+ 'context_uri': contextUri,
11790
+ 'position_ms': positionMS
11791
+ }
11792
+ if offsetUri is not None:
11793
+ reqData['offset'] = { 'uri': offsetUri }
11794
+ else:
11795
+ reqData['offset'] = { 'position': offsetPosition }
11796
+
11797
+ # formulate url parms; will manually add them since we are adding json body as well.
11798
+ urlParms:str = ''
11799
+ if (scDevice is not None):
11800
+ urlParms = '?device_id=%s' % scDevice.Id
11801
+
11802
+ # execute spotify web api request.
11803
+ msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/player/play{url_parms}'.format(url_parms=urlParms))
11804
+ msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
11805
+ msg.RequestJson = reqData
11806
+ self.MakeRequest('PUT', msg)
11725
11807
 
11726
- # give spotify web api time to process the change.
11727
- if delay > 0:
11728
- _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % delay)
11729
- time.sleep(delay)
11808
+ # give spotify web api time to process the change.
11809
+ if delay > 0:
11810
+ _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % delay)
11811
+ time.sleep(delay)
11730
11812
 
11731
11813
  # process results.
11732
11814
  # no results to process - this is pass or fail.
@@ -11952,6 +12034,9 @@ class SpotifyClient:
11952
12034
 
11953
12035
  # validations.
11954
12036
  delay = validateDelay(delay, 0.50, 10)
12037
+ if (positionMS is None) or (positionMS < 0):
12038
+ positionMS = 0
12039
+ offsetPosition:int = 0
11955
12040
 
11956
12041
  # build a list of all item uri's.
11957
12042
  # remove any leading / trailing spaces in case user put a space between the items.
@@ -11964,50 +12049,84 @@ class SpotifyClient:
11964
12049
  arrUris[idx] = arrUris[idx].strip()
11965
12050
 
11966
12051
  # resolve / activate the device object if needed.
11967
- scDevice = self._ResolveDeviceObject(deviceId, False)
12052
+ scDevice = self._ResolveDeviceObject(deviceId, True)
11968
12053
 
11969
- # left this here in case we want to implement it in the future.
11970
-
11971
- # # are we backfilling the player queue? if so, we can only have 50 uris total.
11972
- # if (backfillUrisPageOffset > -1) and (len(arrUris) < 50):
12054
+ # is this a Sonos device?
12055
+ if (scDevice is not None) and (scDevice.IsSonos):
11973
12056
 
11974
- # # are we playing tracks?
11975
- # if (len(arrUris) > 0) and (SpotifyClient.GetTypeFromUri(arrUris[0]) == 'track'):
11976
-
11977
- # _logsi.LogVerbose("Backfilling player queue items from users top tracks")
12057
+ # trace.
12058
+ _logsi.LogVerbose("Track list will be played on Sonos local queue for device: %s" % (scDevice.Title))
12059
+
12060
+ # get the Sonos Controller player instance.
12061
+ sonosPlayer:SoCo = self.SpotifyConnectDirectory.GetSonosPlayer(scDevice)
12062
+
12063
+ # clear the Sonos local queue.
12064
+ _logsi.LogVerbose("Issuing command to Sonos device \"%s\": CLEAR_QUEUE" % (scDevice.Name))
12065
+ sonosPlayer.clear_queue()
12066
+
12067
+ # add all track items to the Sonos local queue.
12068
+ sharelink = ShareLinkPlugin(sonosPlayer)
12069
+ for idx in range(0, len(arrUris)):
12070
+
12071
+ # add track to the Sonos local queue.
12072
+ uri = arrUris[idx].strip()
12073
+ _logsi.LogVerbose("Issuing command to Sonos device \"%s\": ADD_SHARE_LINK_TO_QUEUE (uri=%s)" % (scDevice.Name, uri))
12074
+ sharelink.add_share_link_to_queue(uri)
12075
+
12076
+ # if this is the first item added, then start play of the queue as
12077
+ # it may take awhile to load the rest of the items.
12078
+ if (idx == 0):
12079
+
12080
+ # start playing the Sonos local queue.
12081
+ _logsi.LogVerbose("Issuing command to Sonos device \"%s\": PLAY_FROM_QUEUE (index=%s)" % (scDevice.Name, offsetPosition))
12082
+ sonosPlayer.play_from_queue(index=offsetPosition)
11978
12083
 
11979
- # # get list of users top tracks (50 max items).
11980
- # pageObj:TrackPage = self.GetUsersTopTracks(timeRange='medium_term', offset=backfillUrisPageOffset, limit=(50 - len(arrUris)), sortResult=False)
12084
+ # # give Sonos Controller time to process the change.
12085
+ # if delay > 0:
12086
+ # _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE_SONOS % delay)
12087
+ # time.sleep(delay)
12088
+
12089
+ # was a track seek position specified?
12090
+ if (positionMS > 0):
12091
+
12092
+ # seek to the position in the track.
12093
+ sonosPosition:str = mediaPositionHMS_fromSeconds(positionMS / 1000) # convert from milliseconds to Sonos H:MM:SS format
12094
+ _logsi.LogVerbose("Issuing command to Sonos device \"%s\": SEEK (position=%s)" % (scDevice.Name, sonosPosition))
12095
+ sonosPlayer.seek(position=sonosPosition)
11981
12096
 
11982
- # # add them to the player queue; no need to validate the device id, since we
11983
- # # know there is an active device id by this point.
11984
- # item:Track
11985
- # for item in pageObj.Items:
11986
- # arrUris.append(item.Uri)
12097
+ # give Sonos Controller time to process the change.
12098
+ if delay > 0:
12099
+ _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE_SONOS % delay)
12100
+ time.sleep(delay)
11987
12101
 
11988
- # build spotify web api request parameters.
11989
- reqData:dict = \
11990
- {
11991
- 'position_ms': positionMS
11992
- }
11993
- if uris is not None:
11994
- reqData['uris'] = arrUris
12102
+ else:
11995
12103
 
11996
- # formulate url parms; will manually add them since we are adding json body as well.
11997
- urlParms:str = ''
11998
- if (scDevice is not None):
11999
- urlParms = '?device_id=%s' % scDevice.Id
12104
+ # trace.
12105
+ _logsi.LogVerbose("Track list will be played on the Spotify Connect device via Spotify Web API")
12000
12106
 
12001
- # execute spotify web api request.
12002
- msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/player/play{url_parms}'.format(url_parms=urlParms))
12003
- msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
12004
- msg.RequestJson = reqData
12005
- self.MakeRequest('PUT', msg)
12107
+ # build spotify web api request parameters.
12108
+ reqData:dict = \
12109
+ {
12110
+ 'position_ms': positionMS
12111
+ }
12112
+ if uris is not None:
12113
+ reqData['uris'] = arrUris
12114
+
12115
+ # formulate url parms; will manually add them since we are adding json body as well.
12116
+ urlParms:str = ''
12117
+ if (scDevice is not None):
12118
+ urlParms = '?device_id=%s' % scDevice.Id
12119
+
12120
+ # execute spotify web api request.
12121
+ msg:SpotifyApiMessage = SpotifyApiMessage(apiMethodName, '/me/player/play{url_parms}'.format(url_parms=urlParms))
12122
+ msg.RequestHeaders[self.AuthToken.HeaderKey] = self.AuthToken.HeaderValue
12123
+ msg.RequestJson = reqData
12124
+ self.MakeRequest('PUT', msg)
12006
12125
 
12007
- # give spotify web api time to process the change.
12008
- if delay > 0:
12009
- _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % delay)
12010
- time.sleep(delay)
12126
+ # give spotify web api time to process the change.
12127
+ if delay > 0:
12128
+ _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE % delay)
12129
+ time.sleep(delay)
12011
12130
 
12012
12131
  # process results.
12013
12132
  # no results to process - this is pass or fail.
@@ -13023,7 +13142,7 @@ class SpotifyClient:
13023
13142
  sonosPlayer.play()
13024
13143
  wasCmdIssued = True
13025
13144
 
13026
- # give SoCo api time to process the change.
13145
+ # give Sonos Controller time to process the change.
13027
13146
  if (wasCmdIssued) and (delay > 0):
13028
13147
  _logsi.LogVerbose(TRACE_MSG_DELAY_DEVICE_SONOS % delay)
13029
13148
  time.sleep(delay)