From a3c736def2058547e2c9e9fa4013f7c547c72c55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Mon, 29 Jul 2013 12:07:38 +0200 Subject: [PATCH 01/35] [dailymotion] Add an extractor for Dailymotion playlists --- test/test_playlists.py | 30 ++++++++++++++++++++++++++++ youtube_dl/extractor/__init__.py | 2 +- youtube_dl/extractor/dailymotion.py | 31 +++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 test/test_playlists.py diff --git a/test/test_playlists.py b/test/test_playlists.py new file mode 100644 index 000000000..f8cc75afb --- /dev/null +++ b/test/test_playlists.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +import sys +import unittest +import json + +# Allow direct execution +import os +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from youtube_dl.extractor import DailymotionPlaylistIE +from youtube_dl.utils import * + +from helper import FakeYDL + +class TestPlaylists(unittest.TestCase): + def assertIsPlaylist(self, info): + """Make sure the info has '_type' set to 'playlist'""" + self.assertEqual(info['_type'], 'playlist') + + def test_dailymotion_playlist(self): + dl = FakeYDL() + ie = DailymotionPlaylistIE(dl) + result = ie.extract('http://www.dailymotion.com/playlist/xv4bw_nqtv_sport/1#video=xl8v3q') + self.assertIsPlaylist(result) + self.assertEqual(result['title'], u'SPORT') + self.assertTrue(len(result['entries']) > 20) + +if __name__ == '__main__': + unittest.main() diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 7cfb292d9..063a3d065 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -12,7 +12,7 @@ from .comedycentral import ComedyCentralIE from .condenast import CondeNastIE from .criterion import CriterionIE from .cspan import CSpanIE -from .dailymotion import DailymotionIE +from .dailymotion import DailymotionIE, DailymotionPlaylistIE from .depositfiles import DepositFilesIE from .dotsub import DotsubIE from .dreisat import DreiSatIE diff --git a/youtube_dl/extractor/dailymotion.py b/youtube_dl/extractor/dailymotion.py index 9bf7a28ca..fa8c630d0 100644 --- a/youtube_dl/extractor/dailymotion.py +++ b/youtube_dl/extractor/dailymotion.py @@ -1,9 +1,12 @@ import re import json +import itertools from .common import InfoExtractor from ..utils import ( compat_urllib_request, + get_element_by_attribute, + get_element_by_id, ExtractorError, ) @@ -77,3 +80,31 @@ class DailymotionIE(InfoExtractor): 'ext': video_extension, 'thumbnail': info['thumbnail_url'] }] + + +class DailymotionPlaylistIE(InfoExtractor): + _VALID_URL = r'(?:https?://)?(?:www\.)?dailymotion\.[a-z]{2,3}/playlist/(?P.+?)/' + _MORE_PAGES_INDICATOR = r'' + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + playlist_id = mobj.group('id') + video_ids = [] + + for pagenum in itertools.count(1): + webpage = self._download_webpage('https://www.dailymotion.com/playlist/%s/%s' % (playlist_id, pagenum), + playlist_id, u'Downloading page %s' % pagenum) + + playlist_el = get_element_by_attribute(u'class', u'video_list', webpage) + video_ids.extend(re.findall(r'data-id="(.+?)" data-ext-id', playlist_el)) + + if re.search(self._MORE_PAGES_INDICATOR, webpage, re.DOTALL) is None: + break + + entries = [self.url_result('http://www.dailymotion.com/video/%s' % video_id, 'Dailymotion') + for video_id in video_ids] + return {'_type': 'playlist', + 'id': playlist_id, + 'title': get_element_by_id(u'playlist_name', webpage), + 'entries': entries, + } From caeefc29ebce8dbfb0c25a79887719055276c9eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Mon, 29 Jul 2013 13:12:09 +0200 Subject: [PATCH 02/35] [vimeo] add an extractor for channels --- test/test_playlists.py | 10 +++++++++- youtube_dl/extractor/__init__.py | 2 +- youtube_dl/extractor/vimeo.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/test/test_playlists.py b/test/test_playlists.py index f8cc75afb..65de3a55c 100644 --- a/test/test_playlists.py +++ b/test/test_playlists.py @@ -8,7 +8,7 @@ import json import os sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -from youtube_dl.extractor import DailymotionPlaylistIE +from youtube_dl.extractor import DailymotionPlaylistIE, VimeoChannelIE from youtube_dl.utils import * from helper import FakeYDL @@ -26,5 +26,13 @@ class TestPlaylists(unittest.TestCase): self.assertEqual(result['title'], u'SPORT') self.assertTrue(len(result['entries']) > 20) + def test_vimeo_channel(self): + dl = FakeYDL() + ie = VimeoChannelIE(dl) + result = ie.extract('http://vimeo.com/channels/tributes') + self.assertIsPlaylist(result) + self.assertEqual(result['title'], u'Vimeo Tributes') + self.assertTrue(len(result['entries']) > 24) + if __name__ == '__main__': unittest.main() diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 063a3d065..9f4dd3c24 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -71,7 +71,7 @@ from .ustream import UstreamIE from .vbox7 import Vbox7IE from .veoh import VeohIE from .vevo import VevoIE -from .vimeo import VimeoIE +from .vimeo import VimeoIE, VimeoChannelIE from .vine import VineIE from .c56 import C56IE from .wat import WatIE diff --git a/youtube_dl/extractor/vimeo.py b/youtube_dl/extractor/vimeo.py index ac32043c1..cc9c8d018 100644 --- a/youtube_dl/extractor/vimeo.py +++ b/youtube_dl/extractor/vimeo.py @@ -1,5 +1,6 @@ import json import re +import itertools from .common import InfoExtractor from ..utils import ( @@ -171,3 +172,31 @@ class VimeoIE(InfoExtractor): 'thumbnail': video_thumbnail, 'description': video_description, }] + + +class VimeoChannelIE(InfoExtractor): + IE_NAME = u'vimeo:channel' + _VALID_URL = r'(?:https?://)?vimeo.\com/channels/(?P[^/]+)' + _MORE_PAGES_INDICATOR = r'(.*?)' % channel_id, + webpage, u'channel title') + return {'_type': 'playlist', + 'id': channel_id, + 'title': channel_title, + 'entries': entries, + } From 63f05de10bac9250f58b2f15539f109ec75b3af7 Mon Sep 17 00:00:00 2001 From: Johny Mo Swag Date: Mon, 29 Jul 2013 12:11:57 -0700 Subject: [PATCH 03/35] detect vevo embed --- youtube_dl/extractor/worldstarhiphop.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/youtube_dl/extractor/worldstarhiphop.py b/youtube_dl/extractor/worldstarhiphop.py index 5b9779c05..8715848ee 100644 --- a/youtube_dl/extractor/worldstarhiphop.py +++ b/youtube_dl/extractor/worldstarhiphop.py @@ -21,6 +21,14 @@ class WorldStarHipHopIE(InfoExtractor): webpage_src = self._download_webpage(url, video_id) + video_url = self._search_regex('videoId=(.*?)&?', + webpage_src, u'video URL', fatal=False) + + if video_url: + self.to_screen(u'Vevo video detected:') + vevo_id = 'vevo:%s' video_url + self.url_result(vevo_id) + video_url = self._search_regex(r'so\.addVariable\("file","(.*?)"\)', webpage_src, u'video URL') From 579e2691feca6173c5a84c1fb4fe7a213386c223 Mon Sep 17 00:00:00 2001 From: Johny Mo Swag Date: Mon, 29 Jul 2013 12:24:26 -0700 Subject: [PATCH 04/35] detect vevo embed fix --- youtube_dl/extractor/worldstarhiphop.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/youtube_dl/extractor/worldstarhiphop.py b/youtube_dl/extractor/worldstarhiphop.py index 8715848ee..a93928f3c 100644 --- a/youtube_dl/extractor/worldstarhiphop.py +++ b/youtube_dl/extractor/worldstarhiphop.py @@ -21,17 +21,23 @@ class WorldStarHipHopIE(InfoExtractor): webpage_src = self._download_webpage(url, video_id) - video_url = self._search_regex('videoId=(.*?)&?', + video_url = self._search_regex(r'videoId=(.*?)&?', webpage_src, u'video URL', fatal=False) - + if video_url: self.to_screen(u'Vevo video detected:') - vevo_id = 'vevo:%s' video_url - self.url_result(vevo_id) + return self.url_result('vevo:%s' % video_url, ie='Vevo') video_url = self._search_regex(r'so\.addVariable\("file","(.*?)"\)', webpage_src, u'video URL') + if video_url == None: + video_url = self._search_regex(r'videoId=(.*?)&?', + webpage_src, u'video URL') + self.to_screen(u'Vevo video detected:') + vevo_id = 'vevo:%s' % video_url + return self.url_result(vevo_id, ie='Vevo') + if 'youtube' in video_url: self.to_screen(u'Youtube video detected:') return self.url_result(video_url, ie='Youtube') From a3124ba49fa7e089e761216ea4eb739aae6b07e5 Mon Sep 17 00:00:00 2001 From: pishposhmcgee Date: Mon, 29 Jul 2013 15:45:20 -0500 Subject: [PATCH 05/35] Modified m_urls regex and video_url Some videos have a leading slash, some do not --- youtube_dl/extractor/vevo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/vevo.py b/youtube_dl/extractor/vevo.py index 3b16dcfbc..67537eae5 100644 --- a/youtube_dl/extractor/vevo.py +++ b/youtube_dl/extractor/vevo.py @@ -35,12 +35,12 @@ class VevoIE(InfoExtractor): self.report_extraction(video_id) video_info = json.loads(info_json) - m_urls = list(re.finditer(r'