|
|
@ -239,73 +239,87 @@ class FileDownloader(object):
|
|
|
|
"""Report download finished."""
|
|
|
|
"""Report download finished."""
|
|
|
|
self.to_stdout(u'')
|
|
|
|
self.to_stdout(u'')
|
|
|
|
|
|
|
|
|
|
|
|
def download(self, url_list):
|
|
|
|
def process_info(self, info_dict):
|
|
|
|
"""Download a given list of URLs."""
|
|
|
|
"""Process a single dictionary returned by an InfoExtractor."""
|
|
|
|
retcode = 0
|
|
|
|
|
|
|
|
if len(url_list) > 1 and self.fixed_template():
|
|
|
|
|
|
|
|
raise SameFileError(self.params['outtmpl'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for url in url_list:
|
|
|
|
|
|
|
|
suitable_found = False
|
|
|
|
|
|
|
|
for ie in self._ies:
|
|
|
|
|
|
|
|
if not ie.suitable(url):
|
|
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
# Suitable InfoExtractor found
|
|
|
|
|
|
|
|
suitable_found = True
|
|
|
|
|
|
|
|
all_results = ie.extract(url)
|
|
|
|
|
|
|
|
results = [x for x in all_results if x is not None]
|
|
|
|
|
|
|
|
if len(results) != len(all_results):
|
|
|
|
|
|
|
|
retcode = self.trouble()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if len(results) > 1 and self.fixed_template():
|
|
|
|
|
|
|
|
raise SameFileError(self.params['outtmpl'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for result in results:
|
|
|
|
|
|
|
|
# Forced printings
|
|
|
|
# Forced printings
|
|
|
|
if self.params.get('forcetitle', False):
|
|
|
|
if self.params.get('forcetitle', False):
|
|
|
|
print result['title']
|
|
|
|
print info_dict['title']
|
|
|
|
if self.params.get('forceurl', False):
|
|
|
|
if self.params.get('forceurl', False):
|
|
|
|
print result['url']
|
|
|
|
print info_dict['url']
|
|
|
|
|
|
|
|
|
|
|
|
# Do nothing else if in simulate mode
|
|
|
|
# Do nothing else if in simulate mode
|
|
|
|
if self.params.get('simulate', False):
|
|
|
|
if self.params.get('simulate', False):
|
|
|
|
continue
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
filename = self.params['outtmpl'] % result
|
|
|
|
filename = self.params['outtmpl'] % info_dict
|
|
|
|
self.report_destination(filename)
|
|
|
|
self.report_destination(filename)
|
|
|
|
except (ValueError, KeyError), err:
|
|
|
|
except (ValueError, KeyError), err:
|
|
|
|
retcode = self.trouble('ERROR: invalid output template or system charset: %s' % str(err))
|
|
|
|
return self.trouble('ERROR: invalid output template or system charset: %s' % str(err))
|
|
|
|
continue
|
|
|
|
|
|
|
|
if self.params['nooverwrites'] and os.path.exists(filename):
|
|
|
|
if self.params['nooverwrites'] and os.path.exists(filename):
|
|
|
|
self.to_stderr('WARNING: file exists: %s; skipping' % filename)
|
|
|
|
self.to_stderr('WARNING: file exists: %s; skipping' % filename)
|
|
|
|
continue
|
|
|
|
return 0
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.pmkdir(filename)
|
|
|
|
self.pmkdir(filename)
|
|
|
|
except (OSError, IOError), err:
|
|
|
|
except (OSError, IOError), err:
|
|
|
|
retcode = self.trouble('ERROR: unable to create directories: %s' % str(err))
|
|
|
|
return self.trouble('ERROR: unable to create directories: %s' % str(err))
|
|
|
|
continue
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
outstream = open(filename, 'wb')
|
|
|
|
outstream = open(filename, 'wb')
|
|
|
|
except (OSError, IOError), err:
|
|
|
|
except (OSError, IOError), err:
|
|
|
|
retcode = self.trouble('ERROR: unable to open for writing: %s' % str(err))
|
|
|
|
return self.trouble('ERROR: unable to open for writing: %s' % str(err))
|
|
|
|
continue
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self._do_download(outstream, result['url'])
|
|
|
|
self._do_download(outstream, info_dict['url'])
|
|
|
|
outstream.close()
|
|
|
|
outstream.close()
|
|
|
|
except (OSError, IOError), err:
|
|
|
|
except (OSError, IOError), err:
|
|
|
|
retcode = self.trouble('ERROR: unable to write video data: %s' % str(err))
|
|
|
|
return self.trouble('ERROR: unable to write video data: %s' % str(err))
|
|
|
|
continue
|
|
|
|
|
|
|
|
except (urllib2.URLError, httplib.HTTPException, socket.error), err:
|
|
|
|
except (urllib2.URLError, httplib.HTTPException, socket.error), err:
|
|
|
|
retcode = self.trouble('ERROR: unable to download video data: %s' % str(err))
|
|
|
|
return self.trouble('ERROR: unable to download video data: %s' % str(err))
|
|
|
|
continue
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
self.post_process(filename, result)
|
|
|
|
self.post_process(filename, info_dict)
|
|
|
|
except (PostProcessingError), err:
|
|
|
|
except (PostProcessingError), err:
|
|
|
|
retcode = self.trouble('ERROR: postprocessing: %s' % str(err))
|
|
|
|
return self.trouble('ERROR: postprocessing: %s' % str(err))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def download(self, url_list):
|
|
|
|
|
|
|
|
"""Download a given list of URLs."""
|
|
|
|
|
|
|
|
retcode = 0
|
|
|
|
|
|
|
|
if len(url_list) > 1 and self.fixed_template():
|
|
|
|
|
|
|
|
raise SameFileError(self.params['outtmpl'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for url in url_list:
|
|
|
|
|
|
|
|
suitable_found = False
|
|
|
|
|
|
|
|
for ie in self._ies:
|
|
|
|
|
|
|
|
# Go to next InfoExtractor if not suitable
|
|
|
|
|
|
|
|
if not ie.suitable(url):
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Suitable InfoExtractor found
|
|
|
|
|
|
|
|
suitable_found = True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Extract information from URL
|
|
|
|
|
|
|
|
all_results = ie.extract(url)
|
|
|
|
|
|
|
|
results = [x for x in all_results if x is not None]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# See if there were problems extracting any information
|
|
|
|
|
|
|
|
if len(results) != len(all_results):
|
|
|
|
|
|
|
|
retcode = self.trouble()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Two results could go to the same file
|
|
|
|
|
|
|
|
if len(results) > 1 and self.fixed_template():
|
|
|
|
|
|
|
|
raise SameFileError(self.params['outtmpl'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Process each result
|
|
|
|
|
|
|
|
for result in results:
|
|
|
|
|
|
|
|
result = self.process_info(result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Do not overwrite an error code with a success code
|
|
|
|
|
|
|
|
if result != 0:
|
|
|
|
|
|
|
|
retcode = result
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Suitable InfoExtractor had been found; go to next URL
|
|
|
|
break
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
if not suitable_found:
|
|
|
|
if not suitable_found:
|
|
|
|
retcode = self.trouble('ERROR: no suitable InfoExtractor: %s' % url)
|
|
|
|
retcode = self.trouble('ERROR: no suitable InfoExtractor: %s' % url)
|
|
|
|
|
|
|
|
|
|
|
|