[downloader] Obey --file-access-retries
when deleting/renaming (#2224)
Authored by: ehoogeveen-medweb
This commit is contained in:
parent
747c0bd127
commit
45806d44a7
4 changed files with 36 additions and 23 deletions
|
@ -210,28 +210,41 @@ class FileDownloader(object):
|
||||||
def ytdl_filename(self, filename):
|
def ytdl_filename(self, filename):
|
||||||
return filename + '.ytdl'
|
return filename + '.ytdl'
|
||||||
|
|
||||||
def sanitize_open(self, filename, open_mode):
|
def wrap_file_access(action, *, fatal=False):
|
||||||
file_access_retries = self.params.get('file_access_retries', 10)
|
def outer(func):
|
||||||
retry = 0
|
def inner(self, *args, **kwargs):
|
||||||
while True:
|
file_access_retries = self.params.get('file_access_retries', 0)
|
||||||
try:
|
retry = 0
|
||||||
return sanitize_open(filename, open_mode)
|
while True:
|
||||||
except (IOError, OSError) as err:
|
try:
|
||||||
retry = retry + 1
|
return func(self, *args, **kwargs)
|
||||||
if retry > file_access_retries or err.errno not in (errno.EACCES,):
|
except (IOError, OSError) as err:
|
||||||
raise
|
retry = retry + 1
|
||||||
self.to_screen(
|
if retry > file_access_retries or err.errno not in (errno.EACCES, errno.EINVAL):
|
||||||
'[download] Got file access error. Retrying (attempt %d of %s) ...'
|
if not fatal:
|
||||||
% (retry, self.format_retries(file_access_retries)))
|
self.report_error(f'unable to {action} file: {err}')
|
||||||
time.sleep(0.01)
|
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):
|
||||||
|
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):
|
def try_rename(self, old_filename, new_filename):
|
||||||
if old_filename == new_filename:
|
if old_filename == new_filename:
|
||||||
return
|
return
|
||||||
try:
|
os.replace(old_filename, new_filename)
|
||||||
os.replace(old_filename, new_filename)
|
|
||||||
except (IOError, OSError) as err:
|
|
||||||
self.report_error(f'unable to rename file: {err}')
|
|
||||||
|
|
||||||
def try_utime(self, filename, last_modified_hdr):
|
def try_utime(self, filename, last_modified_hdr):
|
||||||
"""Try to set the last-modified time of the given file."""
|
"""Try to set the last-modified time of the given file."""
|
||||||
|
|
|
@ -159,9 +159,9 @@ class ExternalFD(FragmentFD):
|
||||||
dest.write(decrypt_fragment(fragment, src.read()))
|
dest.write(decrypt_fragment(fragment, src.read()))
|
||||||
src.close()
|
src.close()
|
||||||
if not self.params.get('keep_fragments', False):
|
if not self.params.get('keep_fragments', False):
|
||||||
os.remove(encodeFilename(fragment_filename))
|
self.try_remove(encodeFilename(fragment_filename))
|
||||||
dest.close()
|
dest.close()
|
||||||
os.remove(encodeFilename('%s.frag.urls' % tmpfilename))
|
self.try_remove(encodeFilename('%s.frag.urls' % tmpfilename))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ class FragmentFD(FileDownloader):
|
||||||
if self.__do_ytdl_file(ctx):
|
if self.__do_ytdl_file(ctx):
|
||||||
self._write_ytdl_file(ctx)
|
self._write_ytdl_file(ctx)
|
||||||
if not self.params.get('keep_fragments', False):
|
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']
|
del ctx['fragment_filename_sanitized']
|
||||||
|
|
||||||
def _prepare_frag_download(self, ctx):
|
def _prepare_frag_download(self, ctx):
|
||||||
|
@ -305,7 +305,7 @@ class FragmentFD(FileDownloader):
|
||||||
if self.__do_ytdl_file(ctx):
|
if self.__do_ytdl_file(ctx):
|
||||||
ytdl_filename = encodeFilename(self.ytdl_filename(ctx['filename']))
|
ytdl_filename = encodeFilename(self.ytdl_filename(ctx['filename']))
|
||||||
if os.path.isfile(ytdl_filename):
|
if os.path.isfile(ytdl_filename):
|
||||||
os.remove(ytdl_filename)
|
self.try_remove(ytdl_filename)
|
||||||
elapsed = time.time() - ctx['started']
|
elapsed = time.time() - ctx['started']
|
||||||
|
|
||||||
if ctx['tmpfilename'] == '-':
|
if ctx['tmpfilename'] == '-':
|
||||||
|
|
|
@ -727,7 +727,7 @@ def create_parser():
|
||||||
help='Number of retries (default is %default), or "infinite"')
|
help='Number of retries (default is %default), or "infinite"')
|
||||||
downloader.add_option(
|
downloader.add_option(
|
||||||
'--file-access-retries',
|
'--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"')
|
help='Number of times to retry on file access error (default is %default), or "infinite"')
|
||||||
downloader.add_option(
|
downloader.add_option(
|
||||||
'--fragment-retries',
|
'--fragment-retries',
|
||||||
|
|
Loading…
Reference in a new issue