mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2025-03-09 12:50:23 -05:00
YoutubeDL.py: Defines a new function validate_destination_filename(), which checks the filename length limit before downloading.
This closes issue #8908 """yt-dlp should abort on first "File name too long" error""". Currenty the test fails at test/test_YoutubeDL.py:819. The message is: ------------------------------------------------------------------------- TestYoutubeDL::test_prepare_outtmpl_and_filename - OSError: [Errno 36] File name too long: '{"id ": "1234", "ext": "mp4", "width": null,... ------------------------------------------------------------------------- And the tried filename is: ------------------------------------------------------------------------ '{"id": "1234", "ext": "mp4", "width": null, "height": 1080, "filesize": 1024, "title1": "$PATH", "title2": "%PATH%", "title3": "foo⧸bar⧹⧹test", "title4": "foo ⧹"ba⧹" test", "title5": "⧹u00e1⧹u00e9⧹u00ed ⧹ud835⧹udc00", "timestamp": 1618488000, "duration: 100000, "playlist_index": 1, "playlist_autonumber": 2, "__last_playlist_index": 100, "n_entries": 10, "formats": [{"id": "id 1", "height": 1080, "width": 1920}, {"id": "id2", "height": 720}, {"id": "id 3"}], "epoch": 1740284668, "duration_string": "27-46-40", "autonumber": 1, "video_autonumber": 0, "resolution": "1080p"}' ------------------------------------------------------------------------
This commit is contained in:
parent
7f3006eb0c
commit
4f46e5a323
1 changed files with 29 additions and 0 deletions
|
@ -1475,12 +1475,41 @@ def _prepare_filename(self, info_dict, *, outtmpl=None, tmpl_type=None):
|
|||
self.report_error('Error in output template: ' + str(err) + ' (encoding: ' + repr(preferredencoding()) + ')')
|
||||
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."""
|
||||
cwd = os.getcwd()
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
os.chdir(d)
|
||||
try:
|
||||
with open(filename, 'w') as f:
|
||||
f.close()
|
||||
except OSError as e:
|
||||
if (os.name == 'nt' and e.errno == 206) or (e.errno == errno.ENAMETOOLONG):
|
||||
# The first condition is for windows,
|
||||
# and the second for unix-ish systems.
|
||||
|
||||
# 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.
|
||||
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).''')
|
||||
|
||||
raise
|
||||
finally:
|
||||
os.chdir(cwd)
|
||||
|
||||
def prepare_filename(self, info_dict, dir_type='', *, outtmpl=None, warn=False):
|
||||
"""Generate the output filename"""
|
||||
if outtmpl:
|
||||
assert not dir_type, 'outtmpl and dir_type are mutually exclusive'
|
||||
dir_type = None
|
||||
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'):
|
||||
return ''
|
||||
|
||||
|
|
Loading…
Reference in a new issue