from __future__ import division, unicode_literals
+import copy
import os
import re
import sys
verbose: Print additional info to stdout.
quiet: Do not print messages to stdout.
ratelimit: Download speed limit, in bytes/sec.
+ throttledratelimit: Assume the download is being throttled below this speed (bytes/sec)
retries: Number of times to retry for HTTP error 5xx
buffersize: Size of download buffer in bytes.
noresizebuffer: Do not automatically resize the download buffer.
min_filesize: Skip files smaller than this size
max_filesize: Skip files larger than this size
xattr_set_filesize: Set ytdl.filesize user xattribute with expected size.
- external_downloader_args: A list of additional command-line arguments for the
- external downloader.
+ external_downloader_args: A dictionary of downloader keys (in lower case)
+ and a list of additional command-line arguments for the
+ executable. Use 'default' as the name for arguments to be
+ passed to all downloaders. For compatibility with youtube-dl,
+ a single list of args can also be used
hls_use_mpegts: Use the mpegts container for HLS videos.
http_chunk_size: Size of a chunk for chunk-based HTTP downloading. May be
useful for bypassing bandwidth throttling imposed by
def report_error(self, *args, **kargs):
self.ydl.report_error(*args, **kargs)
+ def write_debug(self, *args, **kargs):
+ self.ydl.write_debug(*args, **kargs)
+
def slow_down(self, start_time, now, byte_counter):
"""Sleep if the download speed is over the rate limit."""
rate_limit = self.params.get('ratelimit')
return filename + '.ytdl'
def try_rename(self, old_filename, new_filename):
+ if old_filename == new_filename:
+ return
try:
- if old_filename == new_filename:
- return
- os.rename(encodeFilename(old_filename), encodeFilename(new_filename))
+ os.replace(old_filename, new_filename)
except (IOError, OSError) as err:
- self.report_error('unable to rename file: %s' % error_to_compat_str(err))
+ self.report_error(f'unable to rename file: {err}')
def try_utime(self, filename, last_modified_hdr):
"""Try to set the last-modified time of the given file."""
'[download] Got server HTTP error: %s. Retrying (attempt %d of %s) ...'
% (error_to_compat_str(err), count, self.format_retries(retries)))
- def report_file_already_downloaded(self, file_name):
+ def report_file_already_downloaded(self, *args, **kwargs):
"""Report file has already been fully downloaded."""
- try:
- self.to_screen('[download] %s has already been downloaded' % file_name)
- except UnicodeEncodeError:
- self.to_screen('[download] The file has already been downloaded')
+ return self.ydl.report_file_already_downloaded(*args, **kwargs)
def report_unable_to_resume(self):
"""Report it was impossible to resume download."""
"""
nooverwrites_and_exists = (
- not self.params.get('overwrites', subtitle)
+ not self.params.get('overwrites', True)
and os.path.exists(encodeFilename(filename))
)
'filename': filename,
'status': 'finished',
'total_bytes': os.path.getsize(encodeFilename(filename)),
- })
+ }, info_dict)
return True, False
if subtitle is False:
"""Real download process. Redefine in subclasses."""
raise NotImplementedError('This method must be implemented by subclasses')
- def _hook_progress(self, status):
+ def _hook_progress(self, status, info_dict):
+ if not self._progress_hooks:
+ return
+ info_dict = dict(info_dict)
+ for key in ('__original_infodict', '__postprocessors'):
+ info_dict.pop(key, None)
+ # youtube-dl passes the same status object to all the hooks.
+ # Some third party scripts seems to be relying on this.
+ # So keep this behavior if possible
+ status['info_dict'] = copy.deepcopy(info_dict)
for ph in self._progress_hooks:
ph(status)