@@ -1889,6 +1889,14 @@ def _report_download_status(self, status: str, fraction: float = 0.0) -> None:
18891889 if self ._download_progress_callback :
18901890 self ._download_progress_callback (fraction , 0.0 , status )
18911891
1892+ def _raise_if_download_cancelled (self ) -> None :
1893+ """Abort the current download if the user has already hit Cancel."""
1894+ if self ._download_cancelled :
1895+ raise RuntimeError ("Download cancelled" )
1896+
1897+ def _download_was_cancelled (self ) -> bool :
1898+ return self ._download_cancelled
1899+
18921900 def _interruptible_pause (self , seconds : float ) -> None :
18931901 """Sleep in short slices so Cancel can abort between UI stages.
18941902
@@ -1897,8 +1905,7 @@ def _interruptible_pause(self, seconds: float) -> None:
18971905 """
18981906 deadline = time .time () + seconds
18991907 while True :
1900- if self ._download_cancelled :
1901- raise RuntimeError ("Download cancelled" )
1908+ self ._raise_if_download_cancelled ()
19021909 remaining = deadline - time .time ()
19031910 if remaining <= 0 :
19041911 return
@@ -1929,12 +1936,15 @@ def _verify_download_with_status(self, filepath: str, model_type: str, filename:
19291936 out. Unpinned models (non-strict mode) get an honest "skipping" status
19301937 so the UI never claims a verification that did not happen.
19311938 """
1939+ self ._raise_if_download_cancelled ()
19321940 watching = self ._download_progress_callback is not None
19331941 pinned = get_pinned_digest (model_type , filename )
1942+ abort = self ._download_was_cancelled
19341943
19351944 if pinned is None :
19361945 # verify_downloaded_model will warn (or raise in strict mode).
1937- verify_downloaded_model (filepath , model_type , filename )
1946+ verify_downloaded_model (filepath , model_type , filename , should_abort = abort )
1947+ self ._raise_if_download_cancelled ()
19381948 self ._report_download_status ("No pinned digest — skipping hash check" , 1.0 )
19391949 if watching :
19401950 self ._interruptible_pause (0.35 )
@@ -1945,7 +1955,8 @@ def _verify_download_with_status(self, filepath: str, model_type: str, filename:
19451955 # we burn CPU hashing; large models take long enough on their own.
19461956 if watching :
19471957 self ._interruptible_pause (0.3 )
1948- verify_downloaded_model (filepath , model_type , filename )
1958+ verify_downloaded_model (filepath , model_type , filename , should_abort = abort )
1959+ self ._raise_if_download_cancelled ()
19491960 self ._report_download_status ("Hash matches — integrity verified" , 1.0 )
19501961 if watching :
19511962 self ._interruptible_pause (0.5 )
@@ -2071,6 +2082,7 @@ def _download_whispercpp_model(self):
20712082 self ._announce_secured_download ("whispercpp" , os .path .basename (model_path ))
20722083 self ._stream_model_download (url , temp_file )
20732084 self ._verify_download_with_status (temp_file , "whispercpp" , os .path .basename (model_path ))
2085+ self ._raise_if_download_cancelled ()
20742086 os .rename (temp_file , model_path )
20752087 logger .info ("whisper.cpp model downloaded successfully" )
20762088
@@ -2249,6 +2261,7 @@ def _download_vosk_model(self):
22492261 logger .info (f"Download progress: { progress * 100 :.1f} % - { status } " )
22502262
22512263 self ._verify_download_with_status (zip_path , "vosk" , os .path .basename (zip_path ))
2264+ self ._raise_if_download_cancelled ()
22522265
22532266 # Update status for extraction phase
22542267 if self ._download_progress_callback :
@@ -2366,6 +2379,7 @@ def _download_whisper_model(self, cache_dir: str):
23662379 logger .info (f"Download progress: { progress * 100 :.1f} % - { status } " )
23672380
23682381 self ._verify_download_with_status (temp_file , "whisper" , f"{ self .model_size } .pt" )
2382+ self ._raise_if_download_cancelled ()
23692383
23702384 # Rename temp file to final
23712385 os .rename (temp_file , model_file )
0 commit comments