]> jfr.im git - yt-dlp.git/commitdiff
[downloader] Obey `--file-access-retries` when deleting/renaming (#2224)
authorEmanuel Hoogeveen <redacted>
Thu, 3 Mar 2022 14:33:32 +0000 (15:33 +0100)
committerGitHub <redacted>
Thu, 3 Mar 2022 14:33:32 +0000 (06:33 -0800)
Authored by: ehoogeveen-medweb

yt_dlp/downloader/common.py
yt_dlp/downloader/external.py
yt_dlp/downloader/fragment.py
yt_dlp/options.py

index 37321e34b1919f0918c90fd004f6bcf3aa409106..3a949d38adb6064fd9c32b187f28046a04a77bea 100644 (file)
@@ -210,28 +210,41 @@ def undo_temp_name(self, filename):
     def ytdl_filename(self, filename):
         return filename + '.ytdl'
 
+    def wrap_file_access(action, *, fatal=False):
+        def outer(func):
+            def inner(self, *args, **kwargs):
+                file_access_retries = self.params.get('file_access_retries', 0)
+                retry = 0
+                while True:
+                    try:
+                        return func(self, *args, **kwargs)
+                    except (IOError, OSError) as err:
+                        retry = retry + 1
+                        if retry > file_access_retries or err.errno not in (errno.EACCES, errno.EINVAL):
+                            if not fatal:
+                                self.report_error(f'unable to {action} file: {err}')
+                                return
+                            raise
+                        self.to_screen(
+                            f'[download] Unable to {action} file due to file access error. '
+                            f'Retrying (attempt {retry} of {self.format_retries(file_access_retries)}) ...')
+                        time.sleep(0.01)
+            return inner
+        return outer
+
+    @wrap_file_access('open', fatal=True)
     def sanitize_open(self, filename, open_mode):
-        file_access_retries = self.params.get('file_access_retries', 10)
-        retry = 0
-        while True:
-            try:
-                return sanitize_open(filename, open_mode)
-            except (IOError, OSError) as err:
-                retry = retry + 1
-                if retry > file_access_retries or err.errno not in (errno.EACCES,):
-                    raise
-                self.to_screen(
-                    '[download] Got file access error. Retrying (attempt %d of %s) ...'
-                    % (retry, self.format_retries(file_access_retries)))
-                time.sleep(0.01)
+        return sanitize_open(filename, open_mode)
+
+    @wrap_file_access('remove')
+    def try_remove(self, filename):
+        os.remove(filename)
 
+    @wrap_file_access('rename')
     def try_rename(self, old_filename, new_filename):
         if old_filename == new_filename:
             return
-        try:
-            os.replace(old_filename, new_filename)
-        except (IOError, OSError) as err:
-            self.report_error(f'unable to rename file: {err}')
+        os.replace(old_filename, new_filename)
 
     def try_utime(self, filename, last_modified_hdr):
         """Try to set the last-modified time of the given file."""
index 03ae3a00e689e940a37544aa89bf7279420d4313..be6202eef293ec610d060fef12c9d0571cdce6d9 100644 (file)
@@ -159,9 +159,9 @@ def _call_downloader(self, tmpfilename, info_dict):
             dest.write(decrypt_fragment(fragment, src.read()))
             src.close()
             if not self.params.get('keep_fragments', False):
-                os.remove(encodeFilename(fragment_filename))
+                self.try_remove(encodeFilename(fragment_filename))
         dest.close()
-        os.remove(encodeFilename('%s.frag.urls' % tmpfilename))
+        self.try_remove(encodeFilename('%s.frag.urls' % tmpfilename))
         return 0
 
 
index 83a9f81b6788279d967bfff55b67a96494682b38..95fb2f9e792d4b763c29dd4bc21f33eab40f6383 100644 (file)
@@ -159,7 +159,7 @@ def _append_fragment(self, ctx, frag_content):
             if self.__do_ytdl_file(ctx):
                 self._write_ytdl_file(ctx)
             if not self.params.get('keep_fragments', False):
-                os.remove(encodeFilename(ctx['fragment_filename_sanitized']))
+                self.try_remove(encodeFilename(ctx['fragment_filename_sanitized']))
             del ctx['fragment_filename_sanitized']
 
     def _prepare_frag_download(self, ctx):
@@ -305,7 +305,7 @@ def _finish_frag_download(self, ctx, info_dict):
         if self.__do_ytdl_file(ctx):
             ytdl_filename = encodeFilename(self.ytdl_filename(ctx['filename']))
             if os.path.isfile(ytdl_filename):
-                os.remove(ytdl_filename)
+                self.try_remove(ytdl_filename)
         elapsed = time.time() - ctx['started']
 
         if ctx['tmpfilename'] == '-':
index 6fcef98cd99aed420356373d46bcfd81b3a81b9d..9908f397527920c687da4d7e185d6eb17e351af5 100644 (file)
@@ -727,7 +727,7 @@ def _dict_from_options_callback(
         help='Number of retries (default is %default), or "infinite"')
     downloader.add_option(
         '--file-access-retries',
-        dest='file_access_retries', metavar='RETRIES', default=10,
+        dest='file_access_retries', metavar='RETRIES', default=3,
         help='Number of times to retry on file access error (default is %default), or "infinite"')
     downloader.add_option(
         '--fragment-retries',