diff options
Diffstat (limited to 'youtube_dl/FileDownloader.py')
| -rw-r--r-- | youtube_dl/FileDownloader.py | 123 | 
1 files changed, 81 insertions, 42 deletions
diff --git a/youtube_dl/FileDownloader.py b/youtube_dl/FileDownloader.py index 7c5a52be1..2237d355d 100644 --- a/youtube_dl/FileDownloader.py +++ b/youtube_dl/FileDownloader.py @@ -418,10 +418,85 @@ class FileDownloader(object):              if re.search(rejecttitle, title, re.IGNORECASE):                  return u'"' + title + '" title matched reject pattern "' + rejecttitle + '"'          return None +         +    def extract_info(self, url): +        ''' +        Returns a list with a dictionary for each video we find. +         ''' +        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.to_stderr(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 +            try: +                ie_results = ie.extract(url) +                results = self.process_ie_results(ie_results, ie) +                return results +            except ExtractorError as de: # An error we somewhat expected +                self.trouble(u'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())) +                    break +                else: +                    raise +        if not suitable_found: +                self.trouble(u'ERROR: no suitable InfoExtractor: %s' % url) +    def extract_info_iterable(self, urls): +        ''' +            Return the videos founded for the urls +        ''' +        results = [] +        for url in urls: +            results.extend(self.extract_info(url)) +        return results +         +    def process_ie_results(self, ie_results, ie): +        """ +        Take the results of the ie and return a list of videos. +        For url elements it will seartch the suitable ie and get the videos +        For playlist elements it will process each of the elements of the 'entries' key +        """ +        results = []  +        for result in ie_results or []: +            result_type = result.get('_type', 'video') #If not given we suppose it's a video, support the dafault old system +            if result_type == 'video': +                if not 'extractor' in result: +                    #The extractor has already been set somewhere else +                    result['extractor'] = ie.IE_NAME +                results.append(result) +            elif result_type == 'url': +                #We get the videos pointed by the url +                results.extend(self.extract_info(result['url'])) +            elif result_type == 'playlist': +                #We process each entry in the playlist +                entries_result = self.process_ie_results(result['entries'], ie) +                result['entries'] = entries_result +                results.extend([result]) +        return results      def process_info(self, info_dict):          """Process a single dictionary returned by an InfoExtractor.""" +        if info_dict.get('_type','video') == 'playlist': +            playlist = info_dict.get('title', None) or info_dict.get('id', None) +            self.to_screen(u'[download] Downloading playlist: %s'  % playlist) +            for video in info_dict['entries']: +                video['playlist'] = playlist +                self.process_info(video) +            return +                  # Keep for backwards compatibility          info_dict['stitle'] = info_dict['title'] @@ -556,53 +631,17 @@ class FileDownloader(object):              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 +            videos = self.extract_info(url) -                # Warn if the _WORKING attribute is False -                if not ie.working(): -                    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 -                suitable_found = True - -                # Extract information from URL and process it +            for video in videos or []:                  try: -                    videos = ie.extract(url) -                except ExtractorError as de: # An error we somewhat expected -                    self.trouble(u'ERROR: ' + compat_str(de), de.format_traceback()) -                    break +                    self.increment_downloads() +                    self.process_info(video) +                except UnavailableVideoError: +                    self.trouble(u'\nERROR: unable to download video')                  except MaxDownloadsReached:                      self.to_screen(u'[info] Maximum number of downloaded files reached.')                      raise -                except Exception as e: -                    if self.params.get('ignoreerrors', False): -                        self.report_error(u'' + compat_str(e), tb=compat_str(traceback.format_exc())) -                        break -                    else: -                        raise - -                if len(videos or []) > 1 and self.fixed_template(): -                    raise SameFileError(self.params['outtmpl']) - -                for video in videos or []: -                    video['extractor'] = ie.IE_NAME -                    try: -                        self.increment_downloads() -                        self.process_info(video) -                    except UnavailableVideoError: -                        self.to_stderr(u"\n") -                        self.report_error(u'unable to download video') - -                # Suitable InfoExtractor had been found; go to next URL -                break - -            if not suitable_found: -                self.report_error(u'no suitable InfoExtractor: %s' % url)          return self._download_retcode  | 
