2828# Global stop event for handling Ctrl+C across all threads
2929_global_stop_event = threading .Event ()
3030
31+ class DownloadAbortedException (Exception ):
32+ """Raised when a download is aborted by user (Ctrl+C)"""
33+ pass
34+
3135def signal_handler (signum , frame ):
3236 """Handle Ctrl+C signal"""
3337 print ("\n [!] Ctrl+C detected - Aborting all downloads..." )
@@ -232,6 +236,10 @@ def list_dl(doc, args):
232236 if not line or line .startswith ('#' ):
233237 continue
234238 lines .append (line )
239+
240+ # If --numbering is used without --name, use "Episode" as default
241+ if args .numbering and not title :
242+ title = "Episode"
235243
236244 print (f"Downloading { len (lines )} files in parallel with { args .workers } threads..." )
237245 print ("[*] Press Ctrl+C to abort all downloads" )
@@ -249,7 +257,7 @@ def list_dl(doc, args):
249257
250258 episode = extract_episode_tag (link , i ) if args .numbering else None
251259 filename = generate_custom_filename (title , episode ) if title and episode else None
252- thread_args = copy .deepcopy (args )
260+ thread_args = copy .copy (args )
253261 thread_args .name = filename if filename else args .name
254262 future = executor .submit (download , link , thread_args , _global_stop_event )
255263 futures .append (future )
@@ -811,7 +819,7 @@ def shift_characters(s: str, offset: int) -> str:
811819 # Progress hook to check for abort
812820 def progress_hook (d ):
813821 if stop_event and stop_event .is_set ():
814- raise Exception ("Download aborted by user" )
822+ raise DownloadAbortedException ("Download aborted by user" )
815823
816824 ydl_opts = {
817825 'outtmpl' : name ,
@@ -823,6 +831,9 @@ def progress_hook(d):
823831 with YoutubeDL (ydl_opts ) as ydl :
824832 try :
825833 ydl .download ([link ])
834+ except DownloadAbortedException :
835+ # Re-raise abort exception to be handled by caller
836+ raise
826837 except Exception as e :
827838 # Check if it was aborted
828839 if stop_event and stop_event .is_set ():
@@ -860,7 +871,7 @@ def progress_hook(d):
860871 # Progress hook to check for abort
861872 def progress_hook (d ):
862873 if stop_event and stop_event .is_set ():
863- raise Exception ("Download aborted by user" )
874+ raise DownloadAbortedException ("Download aborted by user" )
864875
865876 ydl_opts = {
866877 'outtmpl' : name ,
@@ -872,6 +883,9 @@ def progress_hook(d):
872883 with YoutubeDL (ydl_opts ) as ydl :
873884 try :
874885 ydl .download ([link ])
886+ except DownloadAbortedException :
887+ # Re-raise abort exception to be handled by caller
888+ raise
875889 except Exception as e :
876890 # Check if it was aborted
877891 if stop_event and stop_event .is_set ():
0 commit comments