mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-07-08 22:38:33 +00:00
Merge 52d0130a37
into 73bf102116
This commit is contained in:
commit
190893b335
@ -742,6 +742,7 @@ def test(tmpl, expected, *, info=None, **params):
|
|||||||
params['outtmpl'] = tmpl
|
params['outtmpl'] = tmpl
|
||||||
ydl = FakeYDL(params)
|
ydl = FakeYDL(params)
|
||||||
ydl._num_downloads = 1
|
ydl._num_downloads = 1
|
||||||
|
ydl.validate_destination_filename = lambda *args: None
|
||||||
self.assertEqual(ydl.validate_outtmpl(tmpl), None)
|
self.assertEqual(ydl.validate_outtmpl(tmpl), None)
|
||||||
|
|
||||||
out = ydl.evaluate_outtmpl(tmpl, info or self.outtmpl_info)
|
out = ydl.evaluate_outtmpl(tmpl, info or self.outtmpl_info)
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
import locale
|
import locale
|
||||||
import operator
|
import operator
|
||||||
import os
|
import os
|
||||||
|
import pathlib
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
@ -1486,12 +1487,53 @@ def _prepare_filename(self, info_dict, *, outtmpl=None, tmpl_type=None):
|
|||||||
self.report_error('Error in output template: ' + str(err) + ' (encoding: ' + repr(preferredencoding()) + ')')
|
self.report_error('Error in output template: ' + str(err) + ' (encoding: ' + repr(preferredencoding()) + ')')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def validate_destination_filename(self, filename):
|
||||||
|
"""Check if the destination filename is valid in the OS. In particular
|
||||||
|
it checks if the length does not exceed the OS limit. However currently
|
||||||
|
any error is simply raised, independent of the cause.
|
||||||
|
|
||||||
|
Without this, download would fail only after the entire file is downloaded."""
|
||||||
|
# An improvement idea:
|
||||||
|
# by default, retry (exec yt-dlp itself) by
|
||||||
|
# -o "%(id)s.%(ext)s" --write-info-json,
|
||||||
|
# but respect the directory from --output of the original call.
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
try:
|
||||||
|
# To make sure it's confined under tmpdir
|
||||||
|
tmpfn = '.' + os.sep + os.path.splitdrive(filename)[1]
|
||||||
|
|
||||||
|
parentDirStr = os.sep + '..' + os.sep
|
||||||
|
# This may contain '../' so remove them.
|
||||||
|
while parentDirStr in tmpfn:
|
||||||
|
tmpfn = tmpfn.replace(parentDirStr, os.sep)
|
||||||
|
tmpfn = os.path.join(d, tmpfn)
|
||||||
|
pathlib.Path(os.path.dirname(tmpfn)).mkdir(parents=True, exist_ok=True)
|
||||||
|
open(tmpfn, 'w').close()
|
||||||
|
except OSError as e:
|
||||||
|
if (os.name == 'nt' and e.errno == 206) or (os.name != 'nt' and e.errno == errno.ENAMETOOLONG):
|
||||||
|
# For Win, 206 means filename length exceeds MAX_PATH.
|
||||||
|
|
||||||
|
e.filename = filename
|
||||||
|
self.to_screen('''[Notice] The file name to be saved is too long, exceeding the OS limit.
|
||||||
|
[Notice] Consider options --trim-filenames or -o (--output).''')
|
||||||
|
|
||||||
|
elif os.name == 'nt' and e.errno == 22:
|
||||||
|
# Even when MAX_PATH is disabled, 255 chars is the limit, resulting in 22.
|
||||||
|
# https://github.com/python/cpython/issues/126929#issuecomment-2483684861
|
||||||
|
e.filename = filename
|
||||||
|
self.to_screen(f'''[Notice] Attempt to create file {filename} resulted in Errno 22.
|
||||||
|
This is often caused e.g. by too long filename or forbidden characters.''')
|
||||||
|
|
||||||
|
raise
|
||||||
|
|
||||||
def prepare_filename(self, info_dict, dir_type='', *, outtmpl=None, warn=False):
|
def prepare_filename(self, info_dict, dir_type='', *, outtmpl=None, warn=False):
|
||||||
"""Generate the output filename"""
|
"""Generate the output filename"""
|
||||||
if outtmpl:
|
if outtmpl:
|
||||||
assert not dir_type, 'outtmpl and dir_type are mutually exclusive'
|
assert not dir_type, 'outtmpl and dir_type are mutually exclusive'
|
||||||
dir_type = None
|
dir_type = None
|
||||||
filename = self._prepare_filename(info_dict, tmpl_type=dir_type, outtmpl=outtmpl)
|
filename = self._prepare_filename(info_dict, tmpl_type=dir_type, outtmpl=outtmpl)
|
||||||
|
self.validate_destination_filename(filename)
|
||||||
if not filename and dir_type not in ('', 'temp'):
|
if not filename and dir_type not in ('', 'temp'):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user