- def increment_downloads(self):
- """Increment the ordinal that assigns a number to each file."""
- self._num_downloads += 1
-
- def prepare_filename(self, info_dict):
- """Generate the output filename."""
- try:
- template_dict = dict(info_dict)
-
- template_dict['epoch'] = int(time.time())
- template_dict['autonumber'] = u'%05d' % self._num_downloads
-
- sanitize = lambda k,v: sanitize_filename(
- u'NA' if v is None else compat_str(v),
- restricted=self.params.get('restrictfilenames'),
- is_id=(k==u'id'))
- template_dict = dict((k, sanitize(k, v)) for k,v in template_dict.items())
-
- filename = self.params['outtmpl'] % template_dict
- return filename
- except (ValueError, KeyError) as err:
- self.trouble(u'ERROR: invalid system charset or erroneous output template')
- return None
-
- def _match_entry(self, info_dict):
- """ Returns None iff the file should be downloaded """
-
- title = info_dict['title']
- matchtitle = self.params.get('matchtitle', False)
- if matchtitle:
- matchtitle = matchtitle.decode('utf8')
- if not re.search(matchtitle, title, re.IGNORECASE):
- return u'[download] "' + title + '" title did not match pattern "' + matchtitle + '"'
- rejecttitle = self.params.get('rejecttitle', False)
- if rejecttitle:
- rejecttitle = rejecttitle.decode('utf8')
- if re.search(rejecttitle, title, re.IGNORECASE):
- return u'"' + title + '" title matched reject pattern "' + rejecttitle + '"'
- return None
-
- def process_info(self, info_dict):
- """Process a single dictionary returned by an InfoExtractor."""
-
- # Keep for backwards compatibility
- info_dict['stitle'] = info_dict['title']
-
- if not 'format' in info_dict:
- info_dict['format'] = info_dict['ext']
-
- reason = self._match_entry(info_dict)
- if reason is not None:
- self.to_screen(u'[download] ' + reason)
- return
-
- max_downloads = self.params.get('max_downloads')
- if max_downloads is not None:
- if self._num_downloads > int(max_downloads):
- raise MaxDownloadsReached()
-
- filename = self.prepare_filename(info_dict)
-
- # Forced printings
- if self.params.get('forcetitle', False):
- compat_print(info_dict['title'])
- if self.params.get('forceurl', False):
- compat_print(info_dict['url'])
- if self.params.get('forcethumbnail', False) and 'thumbnail' in info_dict:
- compat_print(info_dict['thumbnail'])
- if self.params.get('forcedescription', False) and 'description' in info_dict:
- compat_print(info_dict['description'])
- if self.params.get('forcefilename', False) and filename is not None:
- compat_print(filename)
- if self.params.get('forceformat', False):
- compat_print(info_dict['format'])
-
- # Do nothing else if in simulate mode
- if self.params.get('simulate', False):
- return
-
- if filename is None:
- return
-
- try:
- dn = os.path.dirname(encodeFilename(filename))
- if dn != '' and not os.path.exists(dn): # dn is already encoded
- os.makedirs(dn)
- except (OSError, IOError) as err:
- self.trouble(u'ERROR: unable to create directory ' + compat_str(err))
- return
-
- if self.params.get('writedescription', False):
- try:
- descfn = filename + u'.description'
- self.report_writedescription(descfn)
- descfile = open(encodeFilename(descfn), 'wb')
- try:
- descfile.write(info_dict['description'].encode('utf-8'))
- finally:
- descfile.close()
- except (OSError, IOError):
- self.trouble(u'ERROR: Cannot write description file ' + descfn)
- return
-
- if self.params.get('writesubtitles', False) and 'subtitles' in info_dict and info_dict['subtitles']:
- # subtitles download errors are already managed as troubles in relevant IE
- # that way it will silently go on when used with unsupporting IE
- try:
- srtfn = filename.rsplit('.', 1)[0] + u'.srt'
- self.report_writesubtitles(srtfn)
- srtfile = open(encodeFilename(srtfn), 'wb')
- try:
- srtfile.write(info_dict['subtitles'].encode('utf-8'))
- finally:
- srtfile.close()
- except (OSError, IOError):
- self.trouble(u'ERROR: Cannot write subtitles file ' + descfn)
- return
-
- if self.params.get('writeinfojson', False):
- infofn = filename + u'.info.json'
- self.report_writeinfojson(infofn)
- try:
- json.dump
- except (NameError,AttributeError):
- self.trouble(u'ERROR: No JSON encoder found. Update to Python 2.6+, setup a json module, or leave out --write-info-json.')
- return
- try:
- infof = open(encodeFilename(infofn), 'w')
- try:
- json_info_dict = dict((k, info_dict[k]) for k in info_dict if not k in ['urlhandle'])
- json.dump(json_info_dict, infof)
- finally:
- infof.close()
- except (OSError, IOError):
- self.trouble(u'ERROR: Cannot write metadata to JSON file ' + infofn)
- return
-
- if not self.params.get('skip_download', False):
- if self.params.get('nooverwrites', False) and os.path.exists(encodeFilename(filename)):
- success = True
- else:
- try:
- success = self._do_download(filename, info_dict)
- except (OSError, IOError) as err:
- raise UnavailableVideoError()
- except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err:
- self.trouble(u'ERROR: unable to download video data: %s' % str(err))
- return
- except (ContentTooShortError, ) as err:
- self.trouble(u'ERROR: content too short (expected %s bytes and served %s)' % (err.expected, err.downloaded))
- return
-
- if success:
- try:
- self.post_process(filename, info_dict)
- except (PostProcessingError) as err:
- self.trouble(u'ERROR: postprocessing: %s' % str(err))
- return
-
- def download(self, url_list):
- """Download a given list of URLs."""
- 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
-
- # Warn if the _WORKING attribute is False
- if not ie.working():
- self.trouble(u'WARNING: 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
- suitable_found = True
-
- # Extract information from URL and process it
- videos = ie.extract(url)
- for video in videos or []:
- video['extractor'] = ie.IE_NAME
- try:
- self.increment_downloads()
- self.process_info(video)
- except UnavailableVideoError:
- self.trouble(u'\nERROR: unable to download video')
-
- # Suitable InfoExtractor had been found; go to next URL
- break
-
- if not suitable_found:
- self.trouble(u'ERROR: no suitable InfoExtractor: %s' % url)
-
- return self._download_retcode
-
- def post_process(self, filename, ie_info):
- """Run the postprocessing chain on the given file."""
- info = dict(ie_info)
- info['filepath'] = filename
- for pp in self._pps:
- info = pp.run(info)
- if info is None:
- break
-
- def _download_with_rtmpdump(self, filename, url, player_url):