def get_cover(self, filename, cover_url, feed_url, title, username=None, password=None, download=False): # Detection of "all episodes" podcast if filename == self.ALL_EPISODES_ID: return self.get_cover_all_episodes() # Return already existing files for extension in self.EXTENSIONS: if os.path.exists(filename + extension): return filename + extension # If allowed to download files, do so here if download: # YouTube-specific cover art image resolver youtube_cover_url = youtube.get_cover(feed_url) if youtube_cover_url is not None: cover_url = youtube_cover_url if not cover_url: return self._fallback_filename(title) # We have to add username/password, because password-protected # feeds might keep their cover art also protected (bug 1521) if username is not None and password is not None: cover_url = util.url_add_authentication(cover_url, username, password) try: logger.info('Downloading cover art: %s', cover_url) data = util.urlopen(cover_url, timeout=self.TIMEOUT).read() except Exception as e: logger.warn('Cover art download failed: %s', e) return self._fallback_filename(title) try: extension = None for filetype, check in list(self.SUPPORTED_EXTENSIONS.items()): if check(data): extension = filetype break if extension is None: msg = 'Unknown file type: %s (%r)' % (cover_url, data[:6]) raise ValueError(msg) # Successfully downloaded the cover art - save it! fp = open(filename + extension, 'wb') fp.write(data) fp.close() return filename + extension except Exception as e: logger.warn('Cannot save cover art', exc_info=True) # Fallback to cover art based on the podcast title return self._fallback_filename(title)
def refresh(self, url, channel_url, max_episodes): """ Fetch a channel or playlist contents. Doesn't yet fetch video entry informations, so we only get the video id and title. """ # Duplicate a bit of the YoutubeDL machinery here because we only # want to parse the channel/playlist first, not to fetch video entries. # We call YoutubeDL.extract_info(process=False), so we # have to call extract_info again ourselves when we get a result of type 'url'. def extract_type(ie_result): result_type = ie_result.get('_type', 'video') if result_type not in ('url', 'playlist', 'multi_video'): raise Exception( 'Unsuported result_type: {}'.format(result_type)) has_playlist = result_type in ('playlist', 'multi_video') return result_type, has_playlist opts = { 'youtube_include_dash_manifest': False, # only interested in video title and id } opts.update(self._ydl_opts) with youtube_dl.YoutubeDL(opts) as ydl: ie_result = ydl.extract_info(url, download=False, process=False) result_type, has_playlist = extract_type(ie_result) while not has_playlist: if result_type in ('url', 'url_transparent'): ie_result['url'] = youtube_dl.utils.sanitize_url( ie_result['url']) if result_type == 'url': logger.debug("extract_info(%s) to get the video list", ie_result['url']) # We have to add extra_info to the results because it may be # contained in a playlist ie_result = ydl.extract_info( ie_result['url'], download=False, process=False, ie_key=ie_result.get('ie_key')) result_type, has_playlist = extract_type(ie_result) cover_url = youtube.get_cover( channel_url) # youtube-dl doesn't provide the cover url! description = youtube.get_channel_desc( channel_url) # youtube-dl doesn't provide the description! return feedcore.Result( feedcore.UPDATED_FEED, YoutubeFeed(url, cover_url, description, max_episodes, ie_result, self))
def get_cover(self, filename, cover_url, feed_url, title, username=None, password=None, download=False): # Detection of "all episodes" podcast if filename == self.ALL_EPISODES_ID: return self.get_cover_all_episodes() # Return already existing files for extension in self.EXTENSIONS: if os.path.exists(filename + extension): return filename + extension # If allowed to download files, do so here if download: # YouTube-specific cover art image resolver youtube_cover_url = youtube.get_cover(feed_url) if youtube_cover_url is not None: cover_url = youtube_cover_url if not cover_url: return self._fallback_filename(title) # We have to add username/password, because password-protected # feeds might keep their cover art also protected (bug 1521) if username is not None and password is not None: cover_url = util.url_add_authentication( cover_url, username, password) try: logger.info('Downloading cover art: %s', cover_url) data = util.urlopen(cover_url, timeout=self.TIMEOUT).read() except Exception as e: logger.warn('Cover art download failed: %s', e) return self._fallback_filename(title) try: extension = None for filetype, check in list(self.SUPPORTED_EXTENSIONS.items()): if check(data): extension = filetype break if extension is None: msg = 'Unknown file type: %s (%r)' % (cover_url, data[:6]) raise ValueError(msg) # Successfully downloaded the cover art - save it! fp = open(filename + extension, 'wb') fp.write(data) fp.close() return filename + extension except Exception as e: logger.warn('Cannot save cover art', exc_info=True) # Fallback to cover art based on the podcast title return self._fallback_filename(title)