1
0
Fork 0
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:
Teika Kazura 2025-02-23 13:59:55 +09:00
parent 7f3006eb0c
commit 4f46e5a323

View file

@ -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 ''