@@ -280,6 +280,11 @@ def update(self, received_bytes: int, total_bytes: int = 0):
280280 def final (self ):
281281 return DownloadProgress (self ._initial + self ._received , self ._initial + self ._total , 0 , 1 )
282282
283+ def seconds_since_last_update (self ):
284+ if self ._time is None :
285+ return 0
286+ return (datetime .now () - self ._time ).total_seconds ()
287+
283288
284289async def _try_download (network : QNetworkAccessManager , url : str , path : Path ):
285290 out_file = QFile (str (path ) + ".part" )
@@ -326,8 +331,17 @@ def handle_finished():
326331 await asyncio .wait ([progress_future , finished_future ], return_when = asyncio .FIRST_COMPLETED )
327332 if progress_future .done ():
328333 progress = progress_future .result ()
329- progress_future = asyncio .get_running_loop ().create_future ()
330334 yield progress
335+ await asyncio .sleep (0.1 ) # don't starve UI
336+ progress_future = asyncio .get_running_loop ().create_future ()
337+
338+ if progress_helper .seconds_since_last_update () > 30 :
339+ reply .abort ()
340+ raise NetworkError (
341+ QNetworkReply .NetworkError .TimeoutError ,
342+ "Connection timed out, the server took too long to respond" ,
343+ url ,
344+ )
331345
332346 if e := finished_future .exception ():
333347 raise e
@@ -349,6 +363,7 @@ async def download(network: QNetworkAccessManager, url: str, path: Path):
349363 elif e .code in [
350364 QNetworkReply .NetworkError .RemoteHostClosedError ,
351365 QNetworkReply .NetworkError .TemporaryNetworkFailureError ,
366+ QNetworkReply .NetworkError .TimeoutError ,
352367 ]:
353368 log .warning (f"Download interrupted: { e } " )
354369 if retry == 1 :
0 commit comments