@@ -33,6 +33,7 @@ async def cleared(self, id):
3333class DownloadInfo :
3434 def __init__ (self , id , title , url , quality , format , folder , custom_name_prefix , error ):
3535 self .id = id if len (custom_name_prefix ) == 0 else f'{ custom_name_prefix } .{ id } '
36+ self .id = f'{ self .id } .{ format } '
3637 self .title = title if len (custom_name_prefix ) == 0 else f'{ custom_name_prefix } .{ title } '
3738 self .url = url
3839 self .quality = quality
@@ -51,8 +52,8 @@ class Download:
5152 def __init__ (self , download_dir , temp_dir , output_template , output_template_chapter , quality , format , ytdl_opts , info ):
5253 self .download_dir = download_dir
5354 self .temp_dir = temp_dir
54- self .output_template = output_template
55- self .output_template_chapter = output_template_chapter
55+ self .output_template = self . _add_format_identifier ( format , output_template )
56+ self .output_template_chapter = self . _add_format_identifier ( format , output_template_chapter )
5657 self .format = get_format (format , quality )
5758 self .ytdl_opts = get_opts (format , quality , ytdl_opts )
5859 if "impersonate" in self .ytdl_opts :
@@ -139,6 +140,8 @@ def close(self):
139140 if self .status_queue is not None :
140141 self .status_queue .put (None )
141142
143+ self ._delete_format_identifier ()
144+
142145 def running (self ):
143146 try :
144147 return self .proc is not None and self .proc .is_alive ()
@@ -174,6 +177,49 @@ async def update_status(self):
174177 self .info .eta = status .get ('eta' )
175178 log .info (f"Updating status for { self .info .title } : { status } " )
176179 await self .notifier .updated (self .info )
180+
181+ def _add_format_identifier (self , identifier , template ):
182+ # Preventing the post-processing of YT-DLP from deleting the intermediate file which was download before.
183+ return f'{ identifier } _{ template } '
184+
185+ def _delete_format_identifier (self ):
186+ # Delete the identifier in the file name after the post-processing is complete.
187+ if self .canceled or self .info .status != 'finished' or not hasattr (self .info ,'filename' ):
188+ return
189+
190+ try :
191+ filename = re .sub (r'^\w+_' , '' , self .info .filename )
192+ filepath_idt = os .path .join (self .download_dir , self .info .filename )
193+ filepath = os .path .join (self .download_dir , filename )
194+ if os .path .exists (filepath ):
195+ os .remove (filepath )
196+ os .rename (filepath_idt , filepath )
197+ log .info (f"Renamed file '{ filepath_idt } ' to '{ filepath } '" )
198+ except PermissionError as e :
199+ log .warning (f"Error deleting old file '{ filepath } ': { e } " )
200+ return
201+ except Exception as e :
202+ log .warning (f"Error renaming file '{ filepath_idt } ': { e } " )
203+ return
204+
205+ self .info .filename = filename
206+
207+ def delete_tmpfile (self ):
208+ if not self .tmpfilename or not self .download_dir :
209+ return
210+ if not os .path .isdir (self .download_dir ):
211+ return
212+
213+ tmpfilename = os .path .basename (self .tmpfilename )
214+ def is_tmpfile (filename ):
215+ return filename .startswith (tmpfilename )
216+
217+ try :
218+ tmpfiles = filter (is_tmpfile , os .listdir (self .download_dir ))
219+ for tmpfile in tmpfiles :
220+ os .remove (os .path .join (self .download_dir , tmpfile ))
221+ except Exception as e :
222+ log .warning (f"Error deleting temporary files: { e } " )
177223
178224class PersistentQueue :
179225 def __init__ (self , path ):
@@ -203,7 +249,7 @@ def saved_items(self):
203249 return sorted (shelf .items (), key = lambda item : item [1 ].timestamp )
204250
205251 def put (self , value ):
206- key = value .info .url
252+ key = value .info .id
207253 self .dict [key ] = value
208254 with shelve .open (self .path , 'w' ) as shelf :
209255 shelf [key ] = value .info
@@ -278,17 +324,13 @@ async def _run_download(self, download):
278324
279325 def _post_download_cleanup (self , download ):
280326 if download .info .status != 'finished' :
281- if download .tmpfilename and os .path .isfile (download .tmpfilename ):
282- try :
283- os .remove (download .tmpfilename )
284- except :
285- pass
327+ download .delete_tmpfile ()
286328 download .info .status = 'error'
287329 download .close ()
288- if self .queue .exists (download .info .url ):
289- self .queue .delete (download .info .url )
330+ if self .queue .exists (download .info .id ):
331+ self .queue .delete (download .info .id )
290332 if download .canceled :
291- asyncio .create_task (self .notifier .canceled (download .info .url ))
333+ asyncio .create_task (self .notifier .canceled (download .info .id ))
292334 else :
293335 self .done .put (download )
294336 asyncio .create_task (self .notifier .completed (download .info ))
@@ -361,9 +403,9 @@ async def __add_entry(self, entry, quality, format, folder, custom_name_prefix,
361403 return {'status' : 'ok' }
362404 elif etype == 'video' or (etype .startswith ('url' ) and 'id' in entry and 'title' in entry ):
363405 log .debug ('Processing as a video' )
364- key = entry .get ('webpage_url' ) or entry ['url' ]
365- if not self . queue . exists ( key ):
366- dl = DownloadInfo ( entry [ 'id' ], entry . get ( 'title' ) or entry [ 'id' ], key , quality , format , folder , custom_name_prefix , error )
406+ url = entry .get ('webpage_url' ) or entry ['url' ]
407+ dl = DownloadInfo ( entry [ 'id' ], entry . get ( 'title' ) or entry [ 'id' ], url , quality , format , folder , custom_name_prefix , error )
408+ if not self . queue . exists ( dl . id ):
367409 dldirectory , error_message = self .__calc_download_path (quality , format , folder )
368410 if error_message is not None :
369411 return error_message
0 commit comments