Format code with yapf

This commit fixes the style issues introduced in 2790f48 according to the output
from yapf.

Details: https://deepsource.io/gh/kokarare1212/librespot-python/transform/04a80a03-ea85-44b3-9159-2580bda68c1c/
This commit is contained in:
deepsource-autofix[bot]
2021-09-12 04:58:42 +00:00
committed by GitHub
parent 2790f484c8
commit 0741dbdd43
15 changed files with 396 additions and 237 deletions

View File

@@ -41,36 +41,51 @@ class ApiClient(Closeable):
self.__session = session
self.__base_url = "https://{}".format(ApResolver.get_random_spclient())
def build_request(self, method: str, suffix: str, headers: typing.Union[None, typing.Dict[str, str]],
body: typing.Union[None, bytes]) -> requests.PreparedRequest:
def build_request(
self, method: str, suffix: str,
headers: typing.Union[None, typing.Dict[str, str]],
body: typing.Union[None, bytes]) -> requests.PreparedRequest:
request = requests.PreparedRequest()
request.method = method
request.data = body
request.headers = {}
if headers is not None:
request.headers = headers
request.headers["Authorization"] = "Bearer {}".format(self.__session.tokens().get("playlist-read"))
request.headers["Authorization"] = "Bearer {}".format(
self.__session.tokens().get("playlist-read"))
request.url = self.__base_url + suffix
return request
def send(self, method: str, suffix: str, headers: typing.Union[None, typing.Dict[str, str]],
body: typing.Union[None, bytes]) -> requests.Response:
response = self.__session.client().send(self.build_request(method, suffix, headers, body))
def send(self, method: str, suffix: str,
headers: typing.Union[None, typing.Dict[str, str]],
body: typing.Union[None, bytes]) -> requests.Response:
response = self.__session.client().send(
self.build_request(method, suffix, headers, body))
return response
def put_connect_state(self, connection_id: str, proto: Connect.PutStateRequest) -> None:
def put_connect_state(self, connection_id: str,
proto: Connect.PutStateRequest) -> None:
response = self.send(
"PUT", "/connect-state/v1/devices/{}".format(self.__session.device_id()),
{"Content-Type": "application/protobuf", "X-Spotify-Connection-Id": connection_id},
"PUT",
"/connect-state/v1/devices/{}".format(self.__session.device_id()),
{
"Content-Type": "application/protobuf",
"X-Spotify-Connection-Id": connection_id
},
proto.SerializeToString(),
)
if response.status_code == 413:
self.logger.warning("PUT state payload is too large: {} bytes uncompressed.".format(len(proto.SerializeToString())))
self.logger.warning(
"PUT state payload is too large: {} bytes uncompressed.".
format(len(proto.SerializeToString())))
elif response.status_code != 200:
self.logger.warning("PUT state returned {}. headers: {}".format(response.status_code, response.headers))
self.logger.warning("PUT state returned {}. headers: {}".format(
response.status_code, response.headers))
def get_metadata_4_track(self, track: TrackId) -> Metadata.Track:
response = self.send("GET", "/metadata/4/track/{}".format(track.hex_id()), None, None)
response = self.send("GET",
"/metadata/4/track/{}".format(track.hex_id()),
None, None)
ApiClient.StatusCodeException.check_status(response)
body = response.content
if body is None:
@@ -80,7 +95,9 @@ class ApiClient(Closeable):
return proto
def get_metadata_4_episode(self, episode: EpisodeId) -> Metadata.Episode:
response = self.send("GET", "/metadata/4/episode/{}".format(episode.hex_id()), None, None)
response = self.send("GET",
"/metadata/4/episode/{}".format(episode.hex_id()),
None, None)
ApiClient.StatusCodeException.check_status(response)
body = response.content
if body is None:
@@ -90,7 +107,9 @@ class ApiClient(Closeable):
return proto
def get_metadata_4_album(self, album: AlbumId) -> Metadata.Album:
response = self.send("GET", "/metadata/4/album/{}".format(album.hex_id()), None, None)
response = self.send("GET",
"/metadata/4/album/{}".format(album.hex_id()),
None, None)
ApiClient.StatusCodeException.check_status(response)
body = response.content
@@ -101,7 +120,9 @@ class ApiClient(Closeable):
return proto
def get_metadata_4_artist(self, artist: ArtistId) -> Metadata.Artist:
response = self.send("GET", "/metadata/4/artist/{}".format(artist.hex_id()), None, None)
response = self.send("GET",
"/metadata/4/artist/{}".format(artist.hex_id()),
None, None)
ApiClient.StatusCodeException.check_status(response)
body = response.content
if body is None:
@@ -111,7 +132,9 @@ class ApiClient(Closeable):
return proto
def get_metadata_4_show(self, show: ShowId) -> Metadata.Show:
response = self.send("GET", "/metadata/4/show/{}".format(show.hex_id()), None, None)
response = self.send("GET",
"/metadata/4/show/{}".format(show.hex_id()), None,
None)
ApiClient.StatusCodeException.check_status(response)
body = response.content
if body is None:
@@ -145,7 +168,8 @@ class ApResolver:
Returns:
The resulting object will be returned
"""
response = requests.get("{}?type={}".format(ApResolver.base_url, service_type))
response = requests.get("{}?type={}".format(ApResolver.base_url,
service_type))
return response.json()
@staticmethod
@@ -203,14 +227,19 @@ class EventService(Closeable):
try:
body = event_builder.to_array()
resp = self.__session.mercury().send_sync(
RawMercuryRequest.Builder().set_uri("hm://event-service/v1/events")
.set_method("POST").add_user_field("Accept-Language", "en")
.add_user_field("X-ClientTimeStamp", int(time.time() * 1000)).add_payload_part(body).build())
self.logger.debug("Event sent. body: {}, result: {}".format(body, resp.status_code))
RawMercuryRequest.Builder().set_uri(
"hm://event-service/v1/events").set_method("POST").
add_user_field("Accept-Language", "en").add_user_field(
"X-ClientTimeStamp",
int(time.time() * 1000)).add_payload_part(body).build())
self.logger.debug("Event sent. body: {}, result: {}".format(
body, resp.status_code))
except IOError as ex:
self.logger.error("Failed sending event: {} {}".format(event_builder, ex))
self.logger.error("Failed sending event: {} {}".format(
event_builder, ex))
def send_event(self, event_or_builder: typing.Union[GenericEvent, EventBuilder]):
def send_event(self, event_or_builder: typing.Union[GenericEvent,
EventBuilder]):
if type(event_or_builder) is EventService.GenericEvent:
builder = event_or_builder.build()
elif type(event_or_builder) is EventService.EventBuilder:
@@ -258,7 +287,9 @@ class EventService(Closeable):
s = ""
self.body.write(s.encode())
def append(self, c: int = None, s: str = None) -> EventService.EventBuilder:
def append(self,
c: int = None,
s: str = None) -> EventService.EventBuilder:
if c is None and s is None or c is not None and s is not None:
raise TypeError()
if c is not None:
@@ -326,7 +357,8 @@ class Session(Closeable, SubListener):
self.connection = Session.ConnectionHolder.create(address, None)
self.__inner = inner
self.__keys = DiffieHellman()
self.logger.info("Created new session! device_id: {}, ap: {}".format(inner.device_id, address))
self.logger.info("Created new session! device_id: {}, ap: {}".format(
inner.device_id, address))
def api(self) -> ApiClient:
self.__wait_auth_lock()
@@ -346,7 +378,8 @@ class Session(Closeable, SubListener):
raise RuntimeError("Session isn't authenticated!")
return self.__audio_key_manager
def authenticate(self, credential: Authentication.LoginCredentials) -> None:
def authenticate(self,
credential: Authentication.LoginCredentials) -> None:
"""
Log in to Spotify
Args:
@@ -365,7 +398,8 @@ class Session(Closeable, SubListener):
self.__event_service = EventService(self)
self.__auth_lock_bool = False
self.__auth_lock.notify_all()
self.logger.info("Authenticated as {}!".format(self.__ap_welcome.canonical_username))
self.logger.info("Authenticated as {}!".format(
self.__ap_welcome.canonical_username))
self.mercury().interested_in("spotify:user:attributes:update", self)
def cache(self) -> CacheManager:
@@ -393,7 +427,8 @@ class Session(Closeable, SubListener):
"""
Close instance
"""
self.logger.info("Closing session. device_id: {}".format(self.__inner.device_id))
self.logger.info("Closing session. device_id: {}".format(
self.__inner.device_id))
self.__closing = True
if self.__audio_key_manager is not None:
self.__audio_key_manager = None
@@ -416,7 +451,8 @@ class Session(Closeable, SubListener):
self.__ap_welcome = None
self.cipher_pair = None
self.__closed = True
self.logger.info("Closed session. device_id: {}".format(self.__inner.device_id))
self.logger.info("Closed session. device_id: {}".format(
self.__inner.device_id))
def connect(self) -> None:
"""
@@ -433,10 +469,7 @@ class Session(Closeable, SubListener):
],
login_crypto_hello=Keyexchange.LoginCryptoHelloUnion(
diffie_hellman=Keyexchange.LoginCryptoDiffieHellmanHello(
gc=self.__keys.public_key_bytes(),
server_keys_known=1
),
),
gc=self.__keys.public_key_bytes(), server_keys_known=1), ),
padding=b"\x1e",
)
client_hello_bytes = client_hello_proto.SerializeToString()
@@ -450,22 +483,24 @@ class Session(Closeable, SubListener):
# Read APResponseMessage
ap_response_message_length = self.connection.read_int()
acc.write_int(ap_response_message_length)
ap_response_message_bytes = self.connection.read(ap_response_message_length - 4)
ap_response_message_bytes = self.connection.read(
ap_response_message_length - 4)
acc.write(ap_response_message_bytes)
ap_response_message_proto = Keyexchange.APResponseMessage()
ap_response_message_proto.ParseFromString(ap_response_message_bytes)
shared_key = util.int_to_bytes(
self.__keys.compute_shared_key(
ap_response_message_proto.challenge.login_crypto_challenge.diffie_hellman.gs
)
)
ap_response_message_proto.challenge.login_crypto_challenge.
diffie_hellman.gs))
# Check gs_signature
rsa = RSA.construct((int.from_bytes(self.__server_key, "big"), 65537))
pkcs1_v1_5 = PKCS1_v1_5.new(rsa)
sha1 = SHA1.new()
sha1.update(ap_response_message_proto.challenge.login_crypto_challenge.diffie_hellman.gs)
sha1.update(ap_response_message_proto.challenge.login_crypto_challenge.
diffie_hellman.gs)
if not pkcs1_v1_5.verify(
sha1, ap_response_message_proto.challenge.login_crypto_challenge.diffie_hellman.gs_signature):
sha1, ap_response_message_proto.challenge.
login_crypto_challenge.diffie_hellman.gs_signature):
raise RuntimeError("Failed signature check!")
# Solve challenge
buffer = io.BytesIO()
@@ -481,11 +516,12 @@ class Session(Closeable, SubListener):
client_response_plaintext_proto = Keyexchange.ClientResponsePlaintext(
crypto_response=Keyexchange.CryptoResponseUnion(),
login_crypto_response=Keyexchange.LoginCryptoResponseUnion(
diffie_hellman=Keyexchange.LoginCryptoDiffieHellmanResponse(hmac=challenge)
),
diffie_hellman=Keyexchange.LoginCryptoDiffieHellmanResponse(
hmac=challenge)),
pow_response=Keyexchange.PoWResponseUnion(),
)
client_response_plaintext_bytes = client_response_plaintext_proto.SerializeToString()
client_response_plaintext_bytes = client_response_plaintext_proto.SerializeToString(
)
self.connection.write_int(4 + len(client_response_plaintext_bytes))
self.connection.write(client_response_plaintext_bytes)
self.connection.flush()
@@ -493,7 +529,8 @@ class Session(Closeable, SubListener):
self.connection.set_timeout(1)
scrap = self.connection.read(4)
if len(scrap) == 4:
payload = self.connection.read(struct.unpack(">i", scrap)[0] - 4)
payload = self.connection.read(
struct.unpack(">i", scrap)[0] - 4)
failed = Keyexchange.APResponseMessage()
failed.ParseFromString(payload)
raise RuntimeError(failed)
@@ -522,7 +559,8 @@ class Session(Closeable, SubListener):
return self.__inner.device_id
def get_user_attribute(self, key: str, fallback: str = None) -> str:
return self.__user_attributes.get(key) if self.__user_attributes.get(key) is not None else fallback
return self.__user_attributes.get(key) if self.__user_attributes.get(
key) is not None else fallback
def is_valid(self) -> bool:
if self.__closed:
@@ -550,7 +588,8 @@ class Session(Closeable, SubListener):
return
for i in range(len(product)):
self.__user_attributes[product[i].tag] = product[i].text
self.logger.debug("Parsed product info: {}".format(self.__user_attributes))
self.logger.debug("Parsed product info: {}".format(
self.__user_attributes))
def reconnect(self) -> None:
"""
@@ -559,7 +598,8 @@ class Session(Closeable, SubListener):
if self.connection is not None:
self.connection.close()
self.__receiver.stop()
self.connection = Session.ConnectionHolder.create(ApResolver.get_random_accesspoint(), self.__inner.conf)
self.connection = Session.ConnectionHolder.create(
ApResolver.get_random_accesspoint(), self.__inner.conf)
self.connect()
self.__authenticate_partial(
Authentication.LoginCredentials(
@@ -569,7 +609,8 @@ class Session(Closeable, SubListener):
),
True,
)
self.logger.info("Re-authenticated as {}!".format(self.__ap_welcome.canonical_username))
self.logger.info("Re-authenticated as {}!".format(
self.__ap_welcome.canonical_username))
def reconnecting(self) -> bool:
return not self.__closing and not self.__closed and self.connection is None
@@ -597,7 +638,9 @@ class Session(Closeable, SubListener):
raise RuntimeError("Session isn't authenticated!")
return self.__token_provider
def __authenticate_partial(self, credential: Authentication.LoginCredentials, remove_lock: bool) -> None:
def __authenticate_partial(self,
credential: Authentication.LoginCredentials,
remove_lock: bool) -> None:
"""
Login to Spotify
Args:
@@ -615,7 +658,9 @@ class Session(Closeable, SubListener):
),
version_string=Version.version_string(),
)
self.__send_unchecked(Packet.Type.login, client_response_encrypted_proto.SerializeToString())
self.__send_unchecked(
Packet.Type.login,
client_response_encrypted_proto.SerializeToString())
packet = self.cipher_pair.receive_encoded(self.connection)
if packet.is_cmd(Packet.Type.ap_welcome):
self.__ap_welcome = Authentication.APWelcome()
@@ -624,9 +669,11 @@ class Session(Closeable, SubListener):
bytes0x0f = Random.get_random_bytes(0x14)
self.__send_unchecked(Packet.Type.unknown_0x0f, bytes0x0f)
preferred_locale = io.BytesIO()
preferred_locale.write(b"\x00\x00\x10\x00\x02preferred-locale" + self.__inner.preferred_locale.encode())
preferred_locale.write(b"\x00\x00\x10\x00\x02preferred-locale" +
self.__inner.preferred_locale.encode())
preferred_locale.seek(0)
self.__send_unchecked(Packet.Type.preferred_locale, preferred_locale.read())
self.__send_unchecked(Packet.Type.preferred_locale,
preferred_locale.read())
if remove_lock:
with self.__auth_lock:
self.__auth_lock_bool = False
@@ -636,13 +683,15 @@ class Session(Closeable, SubListener):
reusable_type = Authentication.AuthenticationType.Name(
self.__ap_welcome.reusable_auth_credentials_type)
if self.__inner.conf.stored_credentials_file is None:
raise TypeError("The file path to be saved is not specified")
raise TypeError(
"The file path to be saved is not specified")
with open(self.__inner.conf.stored_credentials_file, "w") as f:
json.dump({
"username": self.__ap_welcome.canonical_username,
"credentials": base64.b64encode(reusable).decode(),
"type": reusable_type,
}, f)
json.dump(
{
"username": self.__ap_welcome.canonical_username,
"credentials": base64.b64encode(reusable).decode(),
"type": reusable_type,
}, f)
elif packet.is_cmd(Packet.Type.auth_failure):
ap_login_failed = Keyexchange.APLoginFailed()
@@ -746,7 +795,8 @@ class Session(Closeable, SubListener):
"""
pass
def stored_file(self, stored_credentials: str = None) -> Session.Builder:
def stored_file(self,
stored_credentials: str = None) -> Session.Builder:
"""
Create credential from stored file
Args:
@@ -765,7 +815,8 @@ class Session(Closeable, SubListener):
else:
try:
self.login_credentials = Authentication.LoginCredentials(
typ=Authentication.AuthenticationType.Value(obj["type"]),
typ=Authentication.AuthenticationType.Value(
obj["type"]),
username=obj["username"],
auth_data=base64.b64decode(obj["credentials"]),
)
@@ -834,20 +885,20 @@ class Session(Closeable, SubListener):
retry_on_chunk_error: bool
def __init__(
self,
# proxy_enabled: bool,
# proxy_type: Proxy.Type,
# proxy_address: str,
# proxy_port: int,
# proxy_auth: bool,
# proxy_username: str,
# proxy_password: str,
cache_enabled: bool,
cache_dir: str,
do_cache_clean_up: bool,
store_credentials: bool,
stored_credentials_file: str,
retry_on_chunk_error: bool,
self,
# proxy_enabled: bool,
# proxy_type: Proxy.Type,
# proxy_address: str,
# proxy_port: int,
# proxy_auth: bool,
# proxy_username: str,
# proxy_password: str,
cache_enabled: bool,
cache_dir: str,
do_cache_clean_up: bool,
store_credentials: bool,
stored_credentials_file: str,
retry_on_chunk_error: bool,
):
# self.proxyEnabled = proxy_enabled
# self.proxyType = proxy_type
@@ -880,7 +931,8 @@ class Session(Closeable, SubListener):
# Stored credentials
store_credentials: bool = True
stored_credentials_file: str = os.path.join(os.getcwd(), "credentials.json")
stored_credentials_file: str = os.path.join(
os.getcwd(), "credentials.json")
# Fetching
retry_on_chunk_error: bool = True
@@ -919,7 +971,9 @@ class Session(Closeable, SubListener):
# self.proxyPassword = proxy_password
# return self
def set_cache_enabled(self, cache_enabled: bool) -> Session.Configuration.Builder:
def set_cache_enabled(
self,
cache_enabled: bool) -> Session.Configuration.Builder:
"""
Set cache_enabled
Args:
@@ -930,7 +984,8 @@ class Session(Closeable, SubListener):
self.cache_enabled = cache_enabled
return self
def set_cache_dir(self, cache_dir: str) -> Session.Configuration.Builder:
def set_cache_dir(self,
cache_dir: str) -> Session.Configuration.Builder:
"""
Set cache_dir
Args:
@@ -941,7 +996,9 @@ class Session(Closeable, SubListener):
self.cache_dir = cache_dir
return self
def set_do_cache_clean_up(self, do_cache_clean_up: bool) -> Session.Configuration.Builder:
def set_do_cache_clean_up(
self,
do_cache_clean_up: bool) -> Session.Configuration.Builder:
"""
Set do_cache_clean_up
Args:
@@ -952,7 +1009,9 @@ class Session(Closeable, SubListener):
self.do_cache_clean_up = do_cache_clean_up
return self
def set_store_credentials(self, store_credentials: bool) -> Session.Configuration.Builder:
def set_store_credentials(
self,
store_credentials: bool) -> Session.Configuration.Builder:
"""
Set store_credentials
Args:
@@ -963,7 +1022,9 @@ class Session(Closeable, SubListener):
self.store_credentials = store_credentials
return self
def set_stored_credential_file(self, stored_credential_file: str) -> Session.Configuration.Builder:
def set_stored_credential_file(
self, stored_credential_file: str
) -> Session.Configuration.Builder:
"""
Set stored_credential_file
Args:
@@ -974,7 +1035,9 @@ class Session(Closeable, SubListener):
self.stored_credentials_file = stored_credential_file
return self
def set_retry_on_chunk_error(self, retry_on_chunk_error: bool) -> Session.Configuration.Builder:
def set_retry_on_chunk_error(
self, retry_on_chunk_error: bool
) -> Session.Configuration.Builder:
"""
Set retry_on_chunk_error
Args:
@@ -1111,18 +1174,19 @@ class Session(Closeable, SubListener):
preferred_locale: str
def __init__(
self,
device_type: Connect.DeviceType,
device_name: str,
preferred_locale: str,
conf: Session.Configuration,
device_id: str = None,
self,
device_type: Connect.DeviceType,
device_name: str,
preferred_locale: str,
conf: Session.Configuration,
device_id: str = None,
):
self.preferred_locale = preferred_locale
self.conf = conf
self.device_type = device_type
self.device_name = device_name
self.device_id = (device_id if device_id is not None else util.random_hex_string(40))
self.device_id = (device_id if device_id is not None else
util.random_hex_string(40))
class Receiver:
__session: Session
@@ -1148,65 +1212,79 @@ class Session(Closeable, SubListener):
packet: Packet
cmd: bytes
try:
packet = self.__session.cipher_pair.receive_encoded(self.__session.connection)
packet = self.__session.cipher_pair.receive_encoded(
self.__session.connection)
cmd = Packet.Type.parse(packet.cmd)
if cmd is None:
self.__session.logger.info(
"Skipping unknown command cmd: 0x{}, payload: {}".
format(util.bytes_to_hex(packet.cmd), packet.payload))
format(util.bytes_to_hex(packet.cmd),
packet.payload))
continue
except RuntimeError as ex:
if self.__running:
self.__session.logger.fatal("Failed reading packet! {}".format(ex))
self.__session.logger.fatal(
"Failed reading packet! {}".format(ex))
self.__session.reconnect()
break
if not self.__running:
break
if cmd == Packet.Type.ping:
if self.__session.scheduled_reconnect is not None:
self.__session.scheduler.cancel(self.__session.scheduled_reconnect)
self.__session.scheduler.cancel(
self.__session.scheduled_reconnect)
def anonymous():
self.__session.logger.warning("Socket timed out. Reconnecting...")
self.__session.logger.warning(
"Socket timed out. Reconnecting...")
self.__session.reconnect()
self.__session.scheduled_reconnect = self.__session.scheduler.enter(2 * 60 + 5, 1, anonymous)
self.__session.scheduled_reconnect = self.__session.scheduler.enter(
2 * 60 + 5, 1, anonymous)
self.__session.send(Packet.Type.pong, packet.payload)
elif cmd == Packet.Type.pong_ack:
continue
elif cmd == Packet.Type.country_code:
self.__session.country_code = packet.payload.decode()
self.__session.logger.info("Received country_code: {}".format(self.__session.country_code))
self.__session.logger.info(
"Received country_code: {}".format(
self.__session.country_code))
elif cmd == Packet.Type.license_version:
license_version = io.BytesIO(packet.payload)
license_id = struct.unpack(">h", license_version.read(2))[0]
license_id = struct.unpack(">h",
license_version.read(2))[0]
if license_id != 0:
buffer = license_version.read()
self.__session.logger.info(
"Received license_version: {}, {}".format(license_id, buffer.decode()))
"Received license_version: {}, {}".format(
license_id, buffer.decode()))
else:
self.__session.logger.info("Received license_version: {}".format(license_id))
self.__session.logger.info(
"Received license_version: {}".format(license_id))
elif cmd == Packet.Type.unknown_0x10:
self.__session.logger.debug("Received 0x10: {}".format(util.bytes_to_hex(packet.payload)))
self.__session.logger.debug("Received 0x10: {}".format(
util.bytes_to_hex(packet.payload)))
elif cmd in [
Packet.Type.mercury_sub, Packet.Type.mercury_unsub,
Packet.Type.mercury_event, Packet.Type.mercury_req
Packet.Type.mercury_sub, Packet.Type.mercury_unsub,
Packet.Type.mercury_event, Packet.Type.mercury_req
]:
self.__session.mercury().dispatch(packet)
elif cmd in [Packet.Type.aes_key, Packet.Type.aes_key_error]:
self.__session.audio_key().dispatch(packet)
elif cmd in [
Packet.Type.channel_error, Packet.Type.stream_chunk_res
Packet.Type.channel_error, Packet.Type.stream_chunk_res
]:
self.__session.channel().dispatch(packet)
elif cmd == Packet.Type.product_info:
self.__session.parse_product_info(packet.payload)
else:
self.__session.logger.info("Skipping {}".format(util.bytes_to_hex(cmd)))
self.__session.logger.info("Skipping {}".format(
util.bytes_to_hex(cmd)))
class SpotifyAuthenticationException(Exception):
def __init__(self, login_failed: Keyexchange.APLoginFailed):
super().__init__(Keyexchange.ErrorCode.Name(login_failed.error_code))
super().__init__(
Keyexchange.ErrorCode.Name(login_failed.error_code))
class TokenProvider:
@@ -1218,7 +1296,8 @@ class TokenProvider:
def __init__(self, session: Session):
self._session = session
def find_token_with_all_scopes(self, scopes: typing.List[str]) -> typing.Union[StoredToken, None]:
def find_token_with_all_scopes(
self, scopes: typing.List[str]) -> typing.Union[StoredToken, None]:
for token in self.__tokens:
if token.has_scopes(scopes):
return token
@@ -1238,11 +1317,15 @@ class TokenProvider:
else:
return token
self.logger.debug(
"Token expired or not suitable, requesting again. scopes: {}, old_token: {}".format(scopes, token))
"Token expired or not suitable, requesting again. scopes: {}, old_token: {}"
.format(scopes, token))
response = self._session.mercury().send_sync_json(
MercuryRequests.request_token(self._session.device_id(), ",".join(scopes)))
MercuryRequests.request_token(self._session.device_id(),
",".join(scopes)))
token = TokenProvider.StoredToken(response)
self.logger.debug("Updated token successfully! scopes: {}, new_token: {}".format(scopes, token))
self.logger.debug(
"Updated token successfully! scopes: {}, new_token: {}".format(
scopes, token))
self.__tokens.append(token)
return token
@@ -1259,8 +1342,10 @@ class TokenProvider:
self.scopes = obj["scope"]
def expired(self) -> bool:
return (self.timestamp +
(self.expires_in - TokenProvider.token_expire_threshold) * 1000 < int(time.time_ns() / 1000))
return (
self.timestamp +
(self.expires_in - TokenProvider.token_expire_threshold) * 1000
< int(time.time_ns() / 1000))
def has_scope(self, scope: str) -> bool:
for s in self.scopes: