X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=youtube_dl%2FFileDownloader.py;h=574863e7c9da066b1fc29741a83a58f2a2baaed4;hb=815dd2ffa8564d6b709f2f12e4a528bfd166a50a;hp=19766153c477dd7a90bb3282ec51c9ea1001274e;hpb=b0936ef42365ce7f2bd5b49e39d0ed42c4c3684e;p=youtube-dl diff --git a/youtube_dl/FileDownloader.py b/youtube_dl/FileDownloader.py index 19766153c..574863e7c 100644 --- a/youtube_dl/FileDownloader.py +++ b/youtube_dl/FileDownloader.py @@ -7,6 +7,7 @@ import math import io import os import re +import shutil import socket import subprocess import sys @@ -79,6 +80,7 @@ class FileDownloader(object): updatetime: Use the Last-modified header to set output file timestamps. writedescription: Write the video description to a .description file writeinfojson: Write the video description to a .info.json file + writethumbnail: Write the thumbnail image to a file writesubtitles: Write the video subtitles to a file onlysubtitles: Downloads only the subtitles of the video allsubtitles: Downloads all the subtitles of the video @@ -89,6 +91,7 @@ class FileDownloader(object): keepvideo: Keep the video file after post-processing min_filesize: Skip files smaller than this size max_filesize: Skip files larger than this size + daterange: A DateRange object, download only if the upload_date is in the range. """ params = None @@ -254,7 +257,7 @@ class FileDownloader(object): Print the message to stderr, it will be prefixed with 'WARNING:' If stderr is a tty file the 'WARNING:' will be colored ''' - if sys.stderr.isatty(): + if sys.stderr.isatty() and os.name != 'nt': _msg_header=u'\033[0;33mWARNING:\033[0m' else: _msg_header=u'WARNING:' @@ -266,7 +269,7 @@ class FileDownloader(object): Do the same as trouble, but prefixes the message with 'ERROR:', colored in red if stderr is a tty file. ''' - if sys.stderr.isatty(): + if sys.stderr.isatty() and os.name != 'nt': _msg_header = u'\033[0;31mERROR:\033[0m' else: _msg_header = u'ERROR:' @@ -344,12 +347,13 @@ class FileDownloader(object): """Report download progress.""" if self.params.get('noprogress', False): return + clear_line = (u'\x1b[K' if sys.stderr.isatty() and os.name != 'nt' else u'') if self.params.get('progress_with_newline', False): self.to_screen(u'[download] %s of %s at %s ETA %s' % (percent_str, data_len_str, speed_str, eta_str)) else: - self.to_screen(u'\r[download] %s of %s at %s ETA %s' % - (percent_str, data_len_str, speed_str, eta_str), skip_eol=True) + self.to_screen(u'\r%s[download] %s of %s at %s ETA %s' % + (clear_line, percent_str, data_len_str, speed_str, eta_str), skip_eol=True) self.to_cons_title(u'youtube-dl - %s of %s at %s ETA %s' % (percent_str.strip(), data_len_str.strip(), speed_str.strip(), eta_str.strip())) @@ -406,10 +410,10 @@ class FileDownloader(object): filename = self.params['outtmpl'] % template_dict return filename except KeyError as err: - self.trouble(u'ERROR: Erroneous output template') + self.report_error(u'Erroneous output template') return None except ValueError as err: - self.trouble(u'ERROR: Insufficient system charset ' + repr(preferredencoding())) + self.report_error(u'Insufficient system charset ' + repr(preferredencoding())) return None def _match_entry(self, info_dict): @@ -424,6 +428,11 @@ class FileDownloader(object): if rejecttitle: if re.search(rejecttitle, title, re.IGNORECASE): return u'"' + title + '" title matched reject pattern "' + rejecttitle + '"' + date = info_dict.get('upload_date', None) + if date is not None: + dateRange = self.params.get('daterange', DateRange()) + if date not in dateRange: + return u'[download] %s upload date is not in range %s' % (date_from_str(date).isoformat(), dateRange) return None def extract_info(self, url, download = True, ie_name = None): @@ -449,7 +458,7 @@ class FileDownloader(object): # Warn if the _WORKING attribute is False if not ie.working(): - self.to_stderr(u'WARNING: the program functionality for this site has been marked as broken, ' + self.report_warning(u'the program functionality for this site has been marked as broken, ' u'and will probably not work. If you want to go on, use the -i option.') # Suitable InfoExtractor found @@ -458,6 +467,8 @@ class FileDownloader(object): # Extract information from URL and process it try: ie_results = ie.extract(url) + if ie_results is None: # Finished already (backwards compatibility; listformats and friends should be moved here) + break results = [] for ie_result in ie_results: if not 'extractor' in ie_result: @@ -466,16 +477,16 @@ class FileDownloader(object): results.append(self.process_ie_result(ie_result, download)) return results except ExtractorError as de: # An error we somewhat expected - self.trouble(u'ERROR: ' + compat_str(de), de.format_traceback()) + self.report_error(compat_str(de), de.format_traceback()) break except Exception as e: if self.params.get('ignoreerrors', False): - self.trouble(u'ERROR: ' + compat_str(e), tb=compat_str(traceback.format_exc())) + self.report_error(compat_str(e), tb=compat_str(traceback.format_exc())) break else: raise if not suitable_found: - self.trouble(u'ERROR: no suitable InfoExtractor: %s' % url) + self.report_error(u'no suitable InfoExtractor: %s' % url) def process_ie_result(self, ie_result, download = True): """ @@ -634,7 +645,7 @@ class FileDownloader(object): with io.open(encodeFilename(sub_filename), 'w', encoding='utf-8') as subfile: subfile.write(sub) except (OSError, IOError): - self.trouble(u'ERROR: Cannot write subtitles file ' + descfn) + self.report_error(u'Cannot write subtitles file ' + descfn) return if self.params.get('onlysubtitles', False): return @@ -649,6 +660,20 @@ class FileDownloader(object): self.report_error(u'Cannot write metadata to JSON file ' + infofn) return + if self.params.get('writethumbnail', False): + if 'thumbnail' in info_dict: + thumb_format = info_dict['thumbnail'].rpartition(u'/')[2].rpartition(u'.')[2] + if not thumb_format: + thumb_format = 'jpg' + thumb_filename = filename.rpartition('.')[0] + u'.' + thumb_format + self.to_screen(u'[%s] %s: Downloading thumbnail ...' % + (info_dict['extractor'], info_dict['id'])) + uf = compat_urllib_request.urlopen(info_dict['thumbnail']) + with open(thumb_filename, 'wb') as thumbf: + shutil.copyfileobj(uf, thumbf) + self.to_screen(u'[%s] %s: Writing thumbnail to: %s' % + (info_dict['extractor'], info_dict['id'], thumb_filename)) + if not self.params.get('skip_download', False): if self.params.get('nooverwrites', False) and os.path.exists(encodeFilename(filename)): success = True @@ -681,7 +706,7 @@ class FileDownloader(object): #It also downloads the videos videos = self.extract_info(url) except UnavailableVideoError: - self.trouble(u'\nERROR: unable to download video') + self.report_error(u'unable to download video') except MaxDownloadsReached: self.to_screen(u'[info] Maximum number of downloaded files reached.') raise