This commit is contained in:
Xoconoch
2025-08-07 12:26:40 -06:00
parent bd75f2f5cc
commit 28bfcbf826

View File

@@ -80,33 +80,27 @@ class ApiClient(Closeable):
headers: typing.Union[None, typing.Dict[str, str]], headers: typing.Union[None, typing.Dict[str, str]],
body: typing.Union[None, bytes], body: typing.Union[None, bytes],
) -> requests.PreparedRequest: ) -> requests.PreparedRequest:
"""
:param method: str:
:param suffix: str:
:param headers: typing.Union[None:
:param typing.Dict[str:
:param str]]:
:param body: typing.Union[None:
:param bytes]:
"""
if self.__client_token_str is None: if self.__client_token_str is None:
resp = self.__client_token() resp = self.__client_token()
self.__client_token_str = resp.granted_token.token self.__client_token_str = resp.granted_token.token
self.logger.debug("Updated client token: {}".format( self.logger.debug("Updated client token: {}".format(self.__client_token_str))
self.__client_token_str))
request = requests.PreparedRequest() request = requests.PreparedRequest()
request.method = method request.method = method
request.data = body request.data = body
request.headers = {} request.headers = headers.copy() if headers else {}
if headers is not None:
request.headers = headers
request.headers["Authorization"] = "Bearer {}".format( request.headers["Authorization"] = "Bearer {}".format(
self.__session.tokens().get("playlist-read")) self.__session.tokens().get("playlist-read")
)
request.headers["client-token"] = self.__client_token_str request.headers["client-token"] = self.__client_token_str
request.url = self.__base_url + suffix
# Force metadata requests to use a specific host
if suffix.startswith("/metadata/4/"):
base_url = "https://spclient.wg.spotify.com"
else:
base_url = self.__base_url
request.url = base_url + suffix
return request return request
def send( def send(
@@ -116,29 +110,12 @@ class ApiClient(Closeable):
headers: typing.Union[None, typing.Dict[str, str]], headers: typing.Union[None, typing.Dict[str, str]],
body: typing.Union[None, bytes], body: typing.Union[None, bytes],
) -> requests.Response: ) -> requests.Response:
"""
:param method: str:
:param suffix: str:
:param headers: typing.Union[None:
:param typing.Dict[str:
:param str]]:
:param body: typing.Union[None:
:param bytes]:
"""
response = self.__session.client().send( response = self.__session.client().send(
self.build_request(method, suffix, headers, body)) self.build_request(method, suffix, headers, body)
)
return response return response
def put_connect_state(self, connection_id: str, def put_connect_state(self, connection_id: str, proto: Connect.PutStateRequest) -> None:
proto: Connect.PutStateRequest) -> None:
"""
:param connection_id: str:
:param proto: Connect.PutStateRequest:
"""
response = self.send( response = self.send(
"PUT", "PUT",
"/connect-state/v1/devices/{}".format(self.__session.device_id()), "/connect-state/v1/devices/{}".format(self.__session.device_id()),
@@ -150,21 +127,17 @@ class ApiClient(Closeable):
) )
if response.status_code == 413: if response.status_code == 413:
self.logger.warning( self.logger.warning(
"PUT state payload is too large: {} bytes uncompressed.". "PUT state payload is too large: {} bytes uncompressed.".format(
format(len(proto.SerializeToString()))) len(proto.SerializeToString())
)
)
elif response.status_code != 200: elif response.status_code != 200:
self.logger.warning("PUT state returned {}. headers: {}".format( self.logger.warning(
response.status_code, response.headers)) "PUT state returned {}. headers: {}".format(response.status_code, response.headers)
)
def get_metadata_4_track(self, track: TrackId) -> Metadata.Track: def get_metadata_4_track(self, track: TrackId) -> Metadata.Track:
""" response = self.send("GET", "/metadata/4/track/{}".format(track.hex_id()), None, None)
:param track: TrackId:
"""
response = self.send("GET",
"/metadata/4/track/{}".format(track.hex_id()),
None, None)
ApiClient.StatusCodeException.check_status(response) ApiClient.StatusCodeException.check_status(response)
body = response.content body = response.content
if body is None: if body is None:
@@ -174,14 +147,7 @@ class ApiClient(Closeable):
return proto return proto
def get_metadata_4_episode(self, episode: EpisodeId) -> Metadata.Episode: def get_metadata_4_episode(self, episode: EpisodeId) -> Metadata.Episode:
""" response = self.send("GET", "/metadata/4/episode/{}".format(episode.hex_id()), None, None)
:param episode: EpisodeId:
"""
response = self.send("GET",
"/metadata/4/episode/{}".format(episode.hex_id()),
None, None)
ApiClient.StatusCodeException.check_status(response) ApiClient.StatusCodeException.check_status(response)
body = response.content body = response.content
if body is None: if body is None:
@@ -191,16 +157,8 @@ class ApiClient(Closeable):
return proto return proto
def get_metadata_4_album(self, album: AlbumId) -> Metadata.Album: def get_metadata_4_album(self, album: AlbumId) -> Metadata.Album:
""" response = self.send("GET", "/metadata/4/album/{}".format(album.hex_id()), None, None)
:param album: AlbumId:
"""
response = self.send("GET",
"/metadata/4/album/{}".format(album.hex_id()),
None, None)
ApiClient.StatusCodeException.check_status(response) ApiClient.StatusCodeException.check_status(response)
body = response.content body = response.content
if body is None: if body is None:
raise IOError() raise IOError()
@@ -209,14 +167,7 @@ class ApiClient(Closeable):
return proto return proto
def get_metadata_4_artist(self, artist: ArtistId) -> Metadata.Artist: def get_metadata_4_artist(self, artist: ArtistId) -> Metadata.Artist:
""" response = self.send("GET", "/metadata/4/artist/{}".format(artist.hex_id()), None, None)
:param artist: ArtistId:
"""
response = self.send("GET",
"/metadata/4/artist/{}".format(artist.hex_id()),
None, None)
ApiClient.StatusCodeException.check_status(response) ApiClient.StatusCodeException.check_status(response)
body = response.content body = response.content
if body is None: if body is None:
@@ -226,14 +177,7 @@ class ApiClient(Closeable):
return proto return proto
def get_metadata_4_show(self, show: ShowId) -> Metadata.Show: def get_metadata_4_show(self, show: ShowId) -> Metadata.Show:
""" response = self.send("GET", "/metadata/4/show/{}".format(show.hex_id()), None, None)
:param show: ShowId:
"""
response = self.send("GET",
"/metadata/4/show/{}".format(show.hex_id()), None,
None)
ApiClient.StatusCodeException.check_status(response) ApiClient.StatusCodeException.check_status(response)
body = response.content body = response.content
if body is None: if body is None:
@@ -242,16 +186,8 @@ class ApiClient(Closeable):
proto.ParseFromString(body) proto.ParseFromString(body)
return proto return proto
def get_playlist(self, def get_playlist(self, _id: PlaylistId) -> Playlist4External.SelectedListContent:
_id: PlaylistId) -> Playlist4External.SelectedListContent: response = self.send("GET", "/playlist/v2/playlist/{}".format(_id.id()), None, None)
"""
:param _id: PlaylistId:
"""
response = self.send("GET",
"/playlist/v2/playlist/{}".format(_id.id()), None,
None)
ApiClient.StatusCodeException.check_status(response) ApiClient.StatusCodeException.check_status(response)
body = response.content body = response.content
if body is None: if body is None:
@@ -261,17 +197,11 @@ class ApiClient(Closeable):
return proto return proto
def set_client_token(self, client_token): def set_client_token(self, client_token):
"""
:param client_token:
"""
self.__client_token_str = client_token self.__client_token_str = client_token
def __client_token(self): def __client_token(self):
proto_req = ClientToken.ClientTokenRequest( proto_req = ClientToken.ClientTokenRequest(
request_type=ClientToken.ClientTokenRequestType. request_type=ClientToken.ClientTokenRequestType.REQUEST_CLIENT_DATA_REQUEST,
REQUEST_CLIENT_DATA_REQUEST,
client_data=ClientToken.ClientDataRequest( client_data=ClientToken.ClientDataRequest(
client_id=MercuryRequests.keymaster_client_id, client_id=MercuryRequests.keymaster_client_id,
client_version=Version.version_name, client_version=Version.version_name,
@@ -286,7 +216,8 @@ class ApiClient(Closeable):
something7=332, something7=332,
something8=33404, something8=33404,
something10=True, something10=True,
), ), ),
),
), ),
), ),
) )
@@ -307,7 +238,6 @@ class ApiClient(Closeable):
return proto_resp return proto_resp
class StatusCodeException(IOError): class StatusCodeException(IOError):
""" """
code: int code: int
def __init__(self, response: requests.Response): def __init__(self, response: requests.Response):
@@ -316,11 +246,6 @@ class ApiClient(Closeable):
@staticmethod @staticmethod
def check_status(response: requests.Response) -> None: def check_status(response: requests.Response) -> None:
"""
:param response: requests.Response:
"""
if response.status_code != 200: if response.status_code != 200:
raise ApiClient.StatusCodeException(response) raise ApiClient.StatusCodeException(response)