[youtube:user:playlists] Add extractor (Closes #3817)
authorSergey M․ <dstftw@gmail.com>
Sat, 21 Nov 2015 22:17:07 +0000 (04:17 +0600)
committerSergey M․ <dstftw@gmail.com>
Sat, 21 Nov 2015 22:17:07 +0000 (04:17 +0600)
youtube_dl/extractor/__init__.py
youtube_dl/extractor/youtube.py

index 232bcd89ad3700d5cbb84a37f22ed98f5391e390..947b836832b5551a6abfc7df34631a4180af394f 100644 (file)
@@ -834,6 +834,7 @@ from .youtube import (
     YoutubeTruncatedIDIE,
     YoutubeTruncatedURLIE,
     YoutubeUserIE,
+    YoutubeUserPlaylistsIE,
     YoutubeWatchLaterIE,
 )
 from .zapiks import ZapiksIE
index 364ca102a6d6033dad6e7c7b45a0cf3ccc15668d..abc67f07fa95b0773dcf98ee1d0f1d354b270a0b 100644 (file)
@@ -224,6 +224,17 @@ class YoutubePlaylistBaseInfoExtractor(InfoExtractor):
         return zip(ids_in_page, titles_in_page)
 
 
+class YoutubePlaylistsBaseInfoExtractor(InfoExtractor):
+    def _real_extract(self, url):
+        playlist_id = self._match_id(url)
+        webpage = self._download_webpage(url, playlist_id)
+        entries = [
+            self.url_result(compat_urlparse.urljoin(url, playlist), 'YoutubePlaylist')
+            for playlist in re.findall(r'href="(/playlist\?list=.+?)"', webpage)]
+        title = self._og_search_title(webpage, fatal=False)
+        return self.playlist_result(entries, playlist_id, title)
+
+
 class YoutubeIE(YoutubeBaseInfoExtractor):
     IE_DESC = 'YouTube.com'
     _VALID_URL = r"""(?x)^
@@ -1742,6 +1753,21 @@ class YoutubeUserIE(YoutubeChannelIE):
             return super(YoutubeUserIE, cls).suitable(url)
 
 
+class YoutubeUserPlaylistsIE(YoutubePlaylistsBaseInfoExtractor):
+    IE_DESC = 'YouTube.com user playlists'
+    _VALID_URL = r'https?://(?:\w+\.)?youtube\.com/user/(?P<id>[^/]+)/playlists'
+    IE_NAME = 'youtube:user:playlists'
+
+    _TEST = {
+        'url': 'http://www.youtube.com/user/ThirstForScience/playlists',
+        'playlist_mincount': 4,
+        'info_dict': {
+            'id': 'ThirstForScience',
+            'title': 'Thirst for Science',
+        },
+    }
+
+
 class YoutubeSearchIE(SearchInfoExtractor, YoutubePlaylistIE):
     IE_DESC = 'YouTube.com searches'
     # there doesn't appear to be a real limit, for example if you search for