[youtube] Add an extractor for Youtube recommended videos (":ytrec" keyword) (closes #476)

The new extractor and YoutubeSubscriptionsIE are subclasses of YoutubeFeedsInfoExtractor, which allows to fetch videos from http://www.youtube.com/feed_ajax
This commit is contained in:
Jaime Marquínez Ferrándiz 2013-07-20 19:33:40 +02:00
parent 0382435990
commit d7ae0639b4
2 changed files with 31 additions and 9 deletions

View File

@ -92,6 +92,7 @@
YoutubeChannelIE, YoutubeChannelIE,
YoutubeShowIE, YoutubeShowIE,
YoutubeSubscriptionsIE, YoutubeSubscriptionsIE,
YoutubeRecommendedIE,
) )
from .zdf import ZDFIE from .zdf import ZDFIE

View File

@ -898,12 +898,12 @@ def _real_extract(self, url):
return [self.url_result('https://www.youtube.com' + season.group(1), 'YoutubePlaylist') for season in m_seasons] return [self.url_result('https://www.youtube.com' + season.group(1), 'YoutubePlaylist') for season in m_seasons]
class YoutubeSubscriptionsIE(YoutubeIE): class YoutubeFeedsInfoExtractor(YoutubeIE):
"""It's a subclass of YoutubeIE because we need to login""" """
IE_DESC = u'YouTube.com subscriptions feed, "ytsubs" keyword(requires authentication)' Base class for extractors that fetch info from
_VALID_URL = r'https?://www\.youtube\.com/feed/subscriptions|:ytsubs(?:criptions)?' http://www.youtube.com/feed_ajax
IE_NAME = u'youtube:subscriptions' Subclasses must define the _FEED_NAME and _PLAYLIST_TITLE properties.
_FEED_TEMPLATE = 'http://www.youtube.com/feed_ajax?action_load_system_feed=1&feed_name=subscriptions&paging=%s' """
_PAGING_STEP = 30 _PAGING_STEP = 30
# Overwrite YoutubeIE properties we don't want # Overwrite YoutubeIE properties we don't want
@ -912,18 +912,27 @@ class YoutubeSubscriptionsIE(YoutubeIE):
def suitable(cls, url): def suitable(cls, url):
return re.match(cls._VALID_URL, url) is not None return re.match(cls._VALID_URL, url) is not None
@property
def _FEED_TEMPLATE(self):
return 'http://www.youtube.com/feed_ajax?action_load_system_feed=1&feed_name=%s&paging=%%s' % self._FEED_NAME
@property
def IE_NAME(self):
return u'youtube:%s' % self._FEED_NAME
def _real_initialize(self): def _real_initialize(self):
(username, password) = self._get_login_info() (username, password) = self._get_login_info()
if username is None: if username is None:
raise ExtractorError(u'No login info available, needed for downloading the Youtube subscriptions.', expected=True) raise ExtractorError(u'No login info available, needed for downloading the Youtube subscriptions.', expected=True)
super(YoutubeSubscriptionsIE, self)._real_initialize() super(YoutubeFeedsInfoExtractor, self)._real_initialize()
def _real_extract(self, url): def _real_extract(self, url):
feed_entries = [] feed_entries = []
# The step argument is available only in 2.7 or higher # The step argument is available only in 2.7 or higher
for i in itertools.count(0): for i in itertools.count(0):
paging = i*self._PAGING_STEP paging = i*self._PAGING_STEP
info = self._download_webpage(self._FEED_TEMPLATE % paging, 'feed', info = self._download_webpage(self._FEED_TEMPLATE % paging,
u'%s feed' % self._FEED_NAME,
u'Downloading page %s' % i) u'Downloading page %s' % i)
info = json.loads(info) info = json.loads(info)
feed_html = info['feed_html'] feed_html = info['feed_html']
@ -932,4 +941,16 @@ def _real_extract(self, url):
feed_entries.extend(self.url_result(id, 'Youtube') for id in ids) feed_entries.extend(self.url_result(id, 'Youtube') for id in ids)
if info['paging'] is None: if info['paging'] is None:
break break
return self.playlist_result(feed_entries, playlist_title='Youtube Subscriptions') return self.playlist_result(feed_entries, playlist_title=self._PLAYLIST_TITLE)
class YoutubeSubscriptionsIE(YoutubeFeedsInfoExtractor):
IE_DESC = u'YouTube.com subscriptions feed, "ytsubs" keyword(requires authentication)'
_VALID_URL = r'https?://www\.youtube\.com/feed/subscriptions|:ytsubs(?:criptions)?'
_FEED_NAME = 'subscriptions'
_PLAYLIST_TITLE = u'Youtube Subscriptions'
class YoutubeRecommendedIE(YoutubeFeedsInfoExtractor):
IE_DESC = u'YouTube.com recommended videos, "ytrec" keyword (requires authentication)'
_VALID_URL = r'https?://www\.youtube\.com/feed/recommended|:ytrec(?:ommended)?'
_FEED_NAME = 'recommended'
_PLAYLIST_TITLE = u'Youtube Recommended videos'