diff --git a/librespot/audio/cdn/CdnManager.py b/librespot/audio/cdn/CdnManager.py index f25b4c8..080bdde 100644 --- a/librespot/audio/cdn/CdnManager.py +++ b/librespot/audio/cdn/CdnManager.py @@ -37,9 +37,9 @@ class CdnManager: def get_head(self, file_id: bytes): resp = self._session.client().get( self._session.get_user_attribute( - "head-files-url", "https://heads-fa.spotify.com/head/{file_id}" - ).replace("{file_id}", Utils.bytes_to_hex(file_id)) - ) + "head-files-url", + "https://heads-fa.spotify.com/head/{file_id}").replace( + "{file_id}", Utils.bytes_to_hex(file_id))) if resp.status_code != 200: raise IOError("{}".format(resp.status_code)) @@ -50,9 +50,9 @@ class CdnManager: return body - def stream_external_episode( - self, episode: Metadata.Episode, external_url: str, halt_listener: HaltListener - ): + def stream_external_episode(self, episode: Metadata.Episode, + external_url: str, + halt_listener: HaltListener): return CdnManager.Streamer( self._session, StreamId(episode), @@ -84,8 +84,7 @@ class CdnManager: resp = self._session.api().send( "GET", "/storage-resolve/files/audio/interactive/{}".format( - Utils.bytes_to_hex(file_id) - ), + Utils.bytes_to_hex(file_id)), None, None, ) @@ -101,13 +100,11 @@ class CdnManager: proto.ParseFromString(body) if proto.result == StorageResolve.StorageResolveResponse.Result.CDN: url = random.choice(proto.cdnurl) - self._LOGGER.debug( - "Fetched CDN url for {}: {}".format(Utils.bytes_to_hex(file_id), url) - ) + self._LOGGER.debug("Fetched CDN url for {}: {}".format( + Utils.bytes_to_hex(file_id), url)) return url raise CdnManager.CdnException( - "Could not retrieve CDN url! result: {}".format(proto.result) - ) + "Could not retrieve CDN url! result: {}".format(proto.result)) class CdnException(Exception): pass @@ -161,14 +158,13 @@ class CdnManager: continue if s[0][:i] == "exp": - expire_at = int(s[0][i + 1 :]) + expire_at = int(s[0][i + 1:]) break if expire_at is None: self._expiration = -1 self._cdnManager._LOGGER.warning( - "Invalid __token__ in CDN url: {}".format(url) - ) + "Invalid __token__ in CDN url: {}".format(url)) return self._expiration = expire_at * 1000 @@ -178,10 +174,8 @@ class CdnManager: except ValueError: self._expiration = -1 self._cdnManager._LOGGER.warning( - "Couldn't extract expiration, invalid parameter in CDN url: ".format( - url - ) - ) + "Couldn't extract expiration, invalid parameter in CDN url: " + .format(url)) return self._expiration = int(token_url.query[:i]) * 1000 @@ -190,8 +184,8 @@ class CdnManager: self._expiration = -1 class Streamer( - GeneralAudioStream.GeneralAudioStream, - GeneralWritableStream.GeneralWritableStream, + GeneralAudioStream.GeneralAudioStream, + GeneralWritableStream.GeneralWritableStream, ): _session: Session = None _streamId: StreamId = None @@ -224,38 +218,39 @@ class CdnManager: self._cdnUrl = cdn_url self._haltListener = halt_listener - resp = self.request(range_start=0, range_end=ChannelManager.CHUNK_SIZE - 1) + resp = self.request(range_start=0, + range_end=ChannelManager.CHUNK_SIZE - 1) content_range = resp._headers.get("Content-Range") if content_range is None: raise IOError("Missing Content-Range header!") split = Utils.split(content_range, "/") self._size = int(split[1]) - self._chunks = int(math.ceil(self._size / ChannelManager.CHUNK_SIZE)) + self._chunks = int( + math.ceil(self._size / ChannelManager.CHUNK_SIZE)) first_chunk = resp._buffer self._available = [False for _ in range(self._chunks)] self._requested = [False for _ in range(self._chunks)] self._buffer = [bytearray() for _ in range(self._chunks)] - self._internalStream = CdnManager.Streamer.InternalStream(self, False) + self._internalStream = CdnManager.Streamer.InternalStream( + self, False) self._requested[0] = True self.write_chunk(first_chunk, 0, False) - def write_chunk(self, chunk: bytes, chunk_index: int, cached: bool) -> None: + def write_chunk(self, chunk: bytes, chunk_index: int, + cached: bool) -> None: if self._internalStream.is_closed(): return self._session._LOGGER.debug( "Chunk {}/{} completed, cached: {}, stream: {}".format( - chunk_index + 1, self._chunks, cached, self.describe() - ) - ) + chunk_index + 1, self._chunks, cached, self.describe())) self._buffer[chunk_index] = self._audioDecrypt.decrypt_chunk( - chunk_index, chunk - ) + chunk_index, chunk) self._internalStream.notify_chunk_available(chunk_index) def stream(self) -> AbsChunkedInputStream: @@ -266,7 +261,8 @@ class CdnManager: def describe(self) -> str: if self._streamId.is_episode(): - return "episode_gid: {}".format(self._streamId.get_episode_gid()) + return "episode_gid: {}".format( + self._streamId.get_episode_gid()) return "file_id: {}".format(self._streamId.get_file_id()) def decrypt_time_ms(self) -> int: @@ -276,9 +272,10 @@ class CdnManager: resp = self.request(index) self.write_chunk(resp._buffer, index, False) - def request( - self, chunk: int = None, range_start: int = None, range_end: int = None - ) -> CdnManager.InternalResponse: + def request(self, + chunk: int = None, + range_start: int = None, + range_end: int = None) -> CdnManager.InternalResponse: if chunk is None and range_start is None and range_end is None: raise TypeError() @@ -288,7 +285,9 @@ class CdnManager: resp = self._session.client().get( self._cdnUrl._url, - headers={"Range": "bytes={}-{}".format(range_start, range_end)}, + headers={ + "Range": "bytes={}-{}".format(range_start, range_end) + }, ) if resp.status_code != 206: @@ -324,21 +323,16 @@ class CdnManager: def request_chunk_from_stream(self, index: int) -> None: self.streamer._executorService.submit( - lambda: self.streamer.request_chunk(index) - ) + lambda: self.streamer.request_chunk(index)) def stream_read_halted(self, chunk: int, _time: int) -> None: if self.streamer._haltListener is not None: self.streamer._executorService.submit( lambda: self.streamer._haltListener.stream_read_halted( - chunk, _time - ) - ) + chunk, _time)) def stream_read_resumed(self, chunk: int, _time: int) -> None: if self.streamer._haltListener is not None: self.streamer._executorService.submit( - lambda: self.streamer._haltListener.stream_read_resumed( - chunk, _time - ) - ) + lambda: self.streamer._haltListener. + stream_read_resumed(chunk, _time))