From 99315aa2527cedebbe55210f6ce20e7c3b5c273a Mon Sep 17 00:00:00 2001 From: John Hawkinson Date: Sat, 8 Oct 2016 09:51:00 -0400 Subject: [PATCH] ExternalFD:real_download(): Skip getsize/rename when writing to stdout In the real_download() method of the ExternalFD class: Special-case output to stdout, when filename=='-', because otherwise the call to os.path.getsize() raises OSError: [Errno 2] No such file or directory: '-' which in turn gets masked by a try block and re-raised as UnavailableVideoError(). And even if getsize had succeeded, we would fail on renaming, and then we would also fail on reporting progress as report_progress() expects to have file size information. So report download completion with self.to_screen() just as report_progress() would in the noprogress==True case. You might ask whether it's an abstraction violation for external.py to have to know and think about '-' as a filename, but unfortunately we're there already. _call_downloader() thinks about it, and also real_download() calls common.py's temp_name() which special-cases the '-' filename to preserve it instead of returnign a temp file. So we already worry about this case at this abstraction level, as well as both below and above. Perhaps that should change, but that's for another day. --- youtube_dl/downloader/external.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/youtube_dl/downloader/external.py b/youtube_dl/downloader/external.py index 0aeae3b8f..fab137199 100644 --- a/youtube_dl/downloader/external.py +++ b/youtube_dl/downloader/external.py @@ -27,15 +27,20 @@ class ExternalFD(FileDownloader): retval = self._call_downloader(tmpfilename, info_dict) if retval == 0: - fsize = os.path.getsize(encodeFilename(tmpfilename)) - self.to_screen('\r[%s] Downloaded %s bytes' % (self.get_basename(), fsize)) - self.try_rename(tmpfilename, filename) - self._hook_progress({ - 'downloaded_bytes': fsize, - 'total_bytes': fsize, - 'filename': filename, - 'status': 'finished', - }) + if filename == '-': + # xxx report_progress() expects total_bytes to be set or it throws a KeyError, so + # we can't just call: self._hook_progress({'status': 'finished'}) + self.to_screen('[download] Download completed') + else: + fsize = os.path.getsize(encodeFilename(tmpfilename)) + self.to_screen('\r[%s] Downloaded %s bytes' % (self.get_basename(), fsize)) + self.try_rename(tmpfilename, filename) + self._hook_progress({ + 'downloaded_bytes': fsize, + 'total_bytes': fsize, + 'filename': filename, + 'status': 'finished', + }) return True else: self.to_stderr('\n')