From e74c504f91a982b36fc27229b13d3aac8d624278 Mon Sep 17 00:00:00 2001 From: Joe Frambach Date: Wed, 24 Apr 2013 21:59:10 +0000 Subject: [PATCH 1/5] Dont delete source file when source file and post-processed file are the same --- youtube_dl/PostProcessor.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/youtube_dl/PostProcessor.py b/youtube_dl/PostProcessor.py index 70dc01004..0c6885dda 100644 --- a/youtube_dl/PostProcessor.py +++ b/youtube_dl/PostProcessor.py @@ -188,6 +188,11 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): prefix, sep, ext = path.rpartition(u'.') # not os.path.splitext, since the latter does not work on unicode in all setups new_path = prefix + sep + extension + + # If we download foo.mp3 and convert it to... foo.mp3, then don't delete foo.mp3, silly. + if new_path == path: + self._nopostoverwrites = True + try: if self._nopostoverwrites and os.path.exists(encodeFilename(new_path)): self._downloader.to_screen(u'[youtube] Post-process file %s exists, skipping' % new_path) @@ -210,7 +215,7 @@ class FFmpegExtractAudioPP(FFmpegPostProcessor): self._downloader.to_stderr(u'WARNING: Cannot update utime of audio file') information['filepath'] = new_path - return False,information + return self._nopostoverwrites,information class FFmpegVideoConvertor(FFmpegPostProcessor): def __init__(self, downloader=None,preferedformat=None): From 0c021ad171231c91e554c76d62e7fc749caf87bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Sat, 4 May 2013 14:23:16 +0200 Subject: [PATCH 2/5] More callbacks changed to raise ExtractorError --- youtube_dl/InfoExtractors.py | 382 ++++++++++++----------------------- 1 file changed, 129 insertions(+), 253 deletions(-) diff --git a/youtube_dl/InfoExtractors.py b/youtube_dl/InfoExtractors.py index 36343882b..0c544d747 100755 --- a/youtube_dl/InfoExtractors.py +++ b/youtube_dl/InfoExtractors.py @@ -472,14 +472,12 @@ class YoutubeIE(InfoExtractor): self.report_age_confirmation() age_results = compat_urllib_request.urlopen(request).read().decode('utf-8') except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to confirm age: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to confirm age: %s' % compat_str(err)) def _extract_id(self, url): mobj = re.match(self._VALID_URL, url, re.VERBOSE) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(2) return video_id @@ -497,8 +495,7 @@ class YoutubeIE(InfoExtractor): try: video_webpage_bytes = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download video webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to download video webpage: %s' % compat_str(err)) video_webpage = video_webpage_bytes.decode('utf-8', 'ignore') @@ -522,23 +519,20 @@ class YoutubeIE(InfoExtractor): break if 'token' not in video_info: if 'reason' in video_info: - self._downloader.report_error(u'YouTube said: %s' % video_info['reason'][0]) + raise ExtractorError(u'YouTube said: %s' % video_info['reason'][0]) else: - self._downloader.report_error(u'"token" parameter not in video info for unknown reason') - return + raise ExtractorError(u'"token" parameter not in video info for unknown reason') # Check for "rental" videos if 'ypc_video_rental_bar_text' in video_info and 'author' not in video_info: - self._downloader.report_error(u'"rental" videos not supported') - return + raise ExtractorError(u'"rental" videos not supported') # Start extracting information self.report_information_extraction(video_id) # uploader if 'author' not in video_info: - self._downloader.report_error(u'unable to extract uploader name') - return + raise ExtractorError(u'Unable to extract uploader name') video_uploader = compat_urllib_parse.unquote_plus(video_info['author'][0]) # uploader_id @@ -551,8 +545,7 @@ class YoutubeIE(InfoExtractor): # title if 'title' not in video_info: - self._downloader.report_error(u'unable to extract video title') - return + raise ExtractorError(u'Unable to extract video title') video_title = compat_urllib_parse.unquote_plus(video_info['title'][0]) # thumbnail image @@ -699,8 +692,7 @@ class MetacafeIE(InfoExtractor): self.report_disclaimer() disclaimer = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to retrieve disclaimer: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to retrieve disclaimer: %s' % compat_str(err)) # Confirm age disclaimer_form = { @@ -712,15 +704,13 @@ class MetacafeIE(InfoExtractor): self.report_age_confirmation() disclaimer = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to confirm age: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to confirm age: %s' % compat_str(err)) def _real_extract(self, url): # Extract id and simplified title from URL mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(1) @@ -749,30 +739,25 @@ class MetacafeIE(InfoExtractor): else: mobj = re.search(r' name="flashvars" value="(.*?)"', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract media URL') - return + raise ExtractorError(u'Unable to extract media URL') vardict = compat_parse_qs(mobj.group(1)) if 'mediaData' not in vardict: - self._downloader.report_error(u'unable to extract media URL') - return + raise ExtractorError(u'Unable to extract media URL') mobj = re.search(r'"mediaURL":"(?Phttp.*?)",(.*?)"key":"(?P.*?)"', vardict['mediaData'][0]) if mobj is None: - self._downloader.report_error(u'unable to extract media URL') - return + raise ExtractorError(u'Unable to extract media URL') mediaURL = mobj.group('mediaURL').replace('\\/', '/') video_extension = mediaURL[-3:] video_url = '%s?__gda__=%s' % (mediaURL, mobj.group('key')) mobj = re.search(r'(?im)(.*) - Video', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract title') - return + raise ExtractorError(u'Unable to extract title') video_title = mobj.group(1).decode('utf-8') mobj = re.search(r'submitter=(.*?);', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract uploader nickname') - return + raise ExtractorError(u'Unable to extract uploader nickname') video_uploader = mobj.group(1) return [{ @@ -794,8 +779,7 @@ class DailymotionIE(InfoExtractor): # Extract id and simplified title from URL mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(1).split('_')[0].split('?')[0] @@ -810,8 +794,7 @@ class DailymotionIE(InfoExtractor): self.report_extraction(video_id) mobj = re.search(r'\s*var flashvars = (.*)', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract media URL') - return + raise ExtractorError(u'Unable to extract media URL') flashvars = compat_urllib_parse.unquote(mobj.group(1)) for key in ['hd1080URL', 'hd720URL', 'hqURL', 'sdURL', 'ldURL', 'video_url']: @@ -820,13 +803,11 @@ class DailymotionIE(InfoExtractor): self.to_screen(u'Using %s' % key) break else: - self._downloader.report_error(u'unable to extract video URL') - return + raise ExtractorError(u'Unable to extract video URL') mobj = re.search(r'"' + max_quality + r'":"(.+?)"', flashvars) if mobj is None: - self._downloader.report_error(u'unable to extract video URL') - return + raise ExtractorError(u'Unable to extract video URL') video_url = compat_urllib_parse.unquote(mobj.group(1)).replace('\\/', '/') @@ -834,8 +815,7 @@ class DailymotionIE(InfoExtractor): mobj = re.search(r'', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract title') - return + raise ExtractorError(u'Unable to extract title') video_title = unescapeHTML(mobj.group('title')) video_uploader = None @@ -875,8 +855,7 @@ class PhotobucketIE(InfoExtractor): # Extract id from URL mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'Invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(1) @@ -888,23 +867,20 @@ class PhotobucketIE(InfoExtractor): self.report_download_webpage(video_id) webpage = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'Unable to retrieve video webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to retrieve video webpage: %s' % compat_str(err)) # Extract URL, uploader, and title from webpage self.report_extraction(video_id) mobj = re.search(r'', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract media URL') - return + raise ExtractorError(u'Unable to extract media URL') mediaURL = compat_urllib_parse.unquote(mobj.group(1)) video_url = mediaURL mobj = re.search(r'(.*) video by (.*) - Photobucket', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract title') - return + raise ExtractorError(u'Unable to extract title') video_title = mobj.group(1).decode('utf-8') video_uploader = mobj.group(2).decode('utf-8') @@ -933,8 +909,7 @@ class YahooIE(InfoExtractor): # Extract ID from URL mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'Invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(2) video_extension = 'flv' @@ -946,19 +921,16 @@ class YahooIE(InfoExtractor): try: webpage = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'Unable to retrieve video webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to retrieve video webpage: %s' % compat_str(err)) mobj = re.search(r'\("id", "([0-9]+)"\);', webpage) if mobj is None: - self._downloader.report_error(u'Unable to extract id field') - return + raise ExtractorError(u'Unable to extract id field') yahoo_id = mobj.group(1) mobj = re.search(r'\("vid", "([0-9]+)"\);', webpage) if mobj is None: - self._downloader.report_error(u'Unable to extract vid field') - return + raise ExtractorError(u'Unable to extract vid field') yahoo_vid = mobj.group(1) url = 'http://video.yahoo.com/watch/%s/%s' % (yahoo_vid, yahoo_id) @@ -970,35 +942,30 @@ class YahooIE(InfoExtractor): self.report_download_webpage(video_id) webpage = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'Unable to retrieve video webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to retrieve video webpage: %s' % compat_str(err)) # Extract uploader and title from webpage self.report_extraction(video_id) mobj = re.search(r'', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video title') - return + raise ExtractorError(u'Unable to extract video title') video_title = mobj.group(1).decode('utf-8') mobj = re.search(r'

(.*)

', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video uploader') - return + raise ExtractorError(u'Unable to extract video uploader') video_uploader = mobj.group(1).decode('utf-8') # Extract video thumbnail mobj = re.search(r'', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video thumbnail') - return + raise ExtractorError(u'Unable to extract video thumbnail') video_thumbnail = mobj.group(1).decode('utf-8') # Extract video description mobj = re.search(r'', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video description') - return + raise ExtractorError(u'Unable to extract video description') video_description = mobj.group(1).decode('utf-8') if not video_description: video_description = 'No description available.' @@ -1006,14 +973,12 @@ class YahooIE(InfoExtractor): # Extract video height and width mobj = re.search(r'', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video height') - return + raise ExtractorError(u'Unable to extract video height') yv_video_height = mobj.group(1) mobj = re.search(r'', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video width') - return + raise ExtractorError(u'Unable to extract video width') yv_video_width = mobj.group(1) # Retrieve video playlist to extract media URL @@ -1028,14 +993,12 @@ class YahooIE(InfoExtractor): self.report_download_webpage(video_id) webpage = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'Unable to retrieve video webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to retrieve video webpage: %s' % compat_str(err)) # Extract media URL from playlist XML mobj = re.search(r'(.*)', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract title') - return + raise ExtractorError(u'Unable to extract title') video_title = mobj.group(1) # video uploader is domain name mobj = re.match(r'(?:https?://)?([^/]*)/.*', url) if mobj is None: - self._downloader.report_error(u'unable to extract title') - return + raise ExtractorError(u'Unable to extract title') video_uploader = mobj.group(1) return [{ @@ -1435,8 +1386,7 @@ class YoutubeSearchIE(InfoExtractor): def _real_extract(self, query): mobj = re.match(self._VALID_URL, query) if mobj is None: - self._downloader.report_error(u'invalid search query "%s"' % query) - return + raise ExtractorError(u'Invalid search query "%s"' % query) prefix, query = query.split(':') prefix = prefix[8:] @@ -1449,8 +1399,7 @@ class YoutubeSearchIE(InfoExtractor): try: n = int(prefix) if n <= 0: - self._downloader.report_error(u'invalid download number %s for query "%s"' % (n, query)) - return + raise ExtractorError(u'Invalid download number %s for query "%s"' % (n, query)) elif n > self._max_youtube_results: self._downloader.report_warning(u'ytsearch returns max %i results (you requested %i)' % (self._max_youtube_results, n)) n = self._max_youtube_results @@ -1472,13 +1421,11 @@ class YoutubeSearchIE(InfoExtractor): try: data = compat_urllib_request.urlopen(request).read().decode('utf-8') except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download API page: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to download API page: %s' % compat_str(err)) api_response = json.loads(data)['data'] if not 'items' in api_response: - self._downloader.report_error(u'[youtube] No video results') - return + raise ExtractorError(u'[youtube] No video results') new_ids = list(video['id'] for video in api_response['items']) video_ids += new_ids @@ -1509,8 +1456,7 @@ class GoogleSearchIE(InfoExtractor): def _real_extract(self, query): mobj = re.match(self._VALID_URL, query) if mobj is None: - self._downloader.report_error(u'invalid search query "%s"' % query) - return + raise ExtractorError(u'Invalid search query "%s"' % query) prefix, query = query.split(':') prefix = prefix[8:] @@ -1525,8 +1471,7 @@ class GoogleSearchIE(InfoExtractor): try: n = int(prefix) if n <= 0: - self._downloader.report_error(u'invalid download number %s for query "%s"' % (n, query)) - return + raise ExtractorError(u'Invalid download number %s for query "%s"' % (n, query)) elif n > self._max_google_results: self._downloader.report_warning(u'gvsearch returns max %i results (you requested %i)' % (self._max_google_results, n)) n = self._max_google_results @@ -1549,8 +1494,7 @@ class GoogleSearchIE(InfoExtractor): try: page = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to download webpage: %s' % compat_str(err)) # Extract video identifiers for mobj in re.finditer(self._VIDEO_INDICATOR, page): @@ -1590,8 +1534,7 @@ class YahooSearchIE(InfoExtractor): def _real_extract(self, query): mobj = re.match(self._VALID_URL, query) if mobj is None: - self._downloader.report_error(u'invalid search query "%s"' % query) - return + raise ExtractorError(u'Invalid search query "%s"' % query) prefix, query = query.split(':') prefix = prefix[8:] @@ -1606,8 +1549,7 @@ class YahooSearchIE(InfoExtractor): try: n = int(prefix) if n <= 0: - self._downloader.report_error(u'invalid download number %s for query "%s"' % (n, query)) - return + raise ExtractorError(u'Invalid download number %s for query "%s"' % (n, query)) elif n > self._max_yahoo_results: self._downloader.report_warning(u'yvsearch returns max %i results (you requested %i)' % (self._max_yahoo_results, n)) n = self._max_yahoo_results @@ -1631,8 +1573,7 @@ class YahooSearchIE(InfoExtractor): try: page = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to download webpage: %s' % compat_str(err)) # Extract video identifiers for mobj in re.finditer(self._VIDEO_INDICATOR, page): @@ -1684,8 +1625,7 @@ class YoutubePlaylistIE(InfoExtractor): # Extract playlist id mobj = re.match(self._VALID_URL, url, re.VERBOSE) if mobj is None: - self._downloader.report_error(u'invalid url: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) # Download playlist videos from API playlist_id = mobj.group(1) or mobj.group(2) @@ -1699,12 +1639,10 @@ class YoutubePlaylistIE(InfoExtractor): try: response = json.loads(page) except ValueError as err: - self._downloader.report_error(u'Invalid JSON in API response: ' + compat_str(err)) - return + raise ExtractorError(u'Invalid JSON in API response: ' + compat_str(err)) if 'feed' not in response: - self._downloader.report_error(u'Got a malformed response from YouTube API') - return + raise ExtractorError(u'Got a malformed response from YouTube API') playlist_title = response['feed']['title']['$t'] if 'entry' not in response['feed']: # Number of videos is a multiple of self._MAX_RESULTS @@ -1744,8 +1682,7 @@ class YoutubeChannelIE(InfoExtractor): # Extract channel id mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid url: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) # Download channel page channel_id = mobj.group(1) @@ -1798,8 +1735,7 @@ class YoutubeUserIE(InfoExtractor): # Extract username mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid url: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) username = mobj.group(1) @@ -1854,8 +1790,7 @@ class BlipTVUserIE(InfoExtractor): # Extract username mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid url: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) username = mobj.group(1) @@ -1921,8 +1856,7 @@ class DepositFilesIE(InfoExtractor): self.report_download_webpage(file_id) webpage = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'Unable to retrieve file webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to retrieve file webpage: %s' % compat_str(err)) # Search for the real file URL mobj = re.search(r'
(Attention.*?)', webpage, re.DOTALL) if (mobj is not None) and (mobj.group(1) is not None): restriction_message = re.sub('\s+', ' ', mobj.group(1)).strip() - self._downloader.report_error(u'%s' % restriction_message) + raise ExtractorError(u'%s' % restriction_message) else: - self._downloader.report_error(u'unable to extract download URL from: %s' % url) - return + raise ExtractorError(u'Unable to extract download URL from: %s' % url) file_url = mobj.group(1) file_extension = os.path.splitext(file_url)[1][1:] @@ -1942,8 +1875,7 @@ class DepositFilesIE(InfoExtractor): # Search for file title mobj = re.search(r'', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract title') - return + raise ExtractorError(u'Unable to extract title') file_title = mobj.group(1).decode('utf-8') return [{ @@ -2015,8 +1947,7 @@ class FacebookIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group('ID') url = 'https://www.facebook.com/video/video.php?v=%s' % video_id @@ -2069,8 +2000,7 @@ class BlipTVIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) urlp = compat_urllib_parse_urlparse(url) if urlp.path.startswith('/play/'): @@ -2116,8 +2046,7 @@ class BlipTVIE(InfoExtractor): json_code_bytes = urlh.read() json_code = json_code_bytes.decode('utf-8') except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to read video info webpage: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to read video info webpage: %s' % compat_str(err)) try: json_data = json.loads(json_code) @@ -2147,8 +2076,7 @@ class BlipTVIE(InfoExtractor): 'user_agent': 'iTunes/10.6.1', } except (ValueError,KeyError) as err: - self._downloader.report_error(u'unable to parse video information: %s' % repr(err)) - return + raise ExtractorError(u'Unable to parse video information: %s' % repr(err)) return [info] @@ -2162,8 +2090,7 @@ class MyVideoIE(InfoExtractor): def _real_extract(self,url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._download.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(1) @@ -2175,14 +2102,12 @@ class MyVideoIE(InfoExtractor): mobj = re.search(r'([^<]+)', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract title') - return + raise ExtractorError(u'Unable to extract title') video_title = mobj.group(1) @@ -2245,8 +2170,7 @@ class ComedyCentralIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url, re.VERBOSE) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) if mobj.group('shortname'): if mobj.group('shortname') in ('tds', 'thedailyshow'): @@ -2373,8 +2297,7 @@ class EscapistIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) showName = mobj.group('showname') videoId = mobj.group('episode') @@ -2400,8 +2323,7 @@ class EscapistIE(InfoExtractor): try: config = json.loads(configJSON) except (ValueError,) as err: - self._downloader.report_error(u'Invalid JSON in configuration file: ' + compat_str(err)) - return + raise ExtractorError(u'Invalid JSON in configuration file: ' + compat_str(err)) playlist = config['playlist'] videoUrl = playlist[1]['url'] @@ -2434,8 +2356,7 @@ class CollegeHumorIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group('videoid') info = { @@ -2449,8 +2370,7 @@ class CollegeHumorIE(InfoExtractor): try: metaXml = compat_urllib_request.urlopen(xmlUrl).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download video info XML: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to download video info XML: %s' % compat_str(err)) mdoc = xml.etree.ElementTree.fromstring(metaXml) try: @@ -2460,16 +2380,14 @@ class CollegeHumorIE(InfoExtractor): info['thumbnail'] = videoNode.findall('./thumbnail')[0].text manifest_url = videoNode.findall('./file')[0].text except IndexError: - self._downloader.report_error(u'Invalid metadata XML file') - return + raise ExtractorError(u'Invalid metadata XML file') manifest_url += '?hdcore=2.10.3' self.report_manifest(video_id) try: manifestXml = compat_urllib_request.urlopen(manifest_url).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download video info XML: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to download video info XML: %s' % compat_str(err)) adoc = xml.etree.ElementTree.fromstring(manifestXml) try: @@ -2477,8 +2395,7 @@ class CollegeHumorIE(InfoExtractor): node_id = media_node.attrib['url'] video_id = adoc.findall('./{http://ns.adobe.com/f4m/1.0}id')[0].text except IndexError as err: - self._downloader.report_error(u'Invalid manifest file') - return + raise ExtractorError(u'Invalid manifest file') url_pr = compat_urllib_parse_urlparse(manifest_url) url = url_pr.scheme + '://' + url_pr.netloc + '/z' + video_id[:-2] + '/' + node_id + 'Seg1-Frag1' @@ -2497,8 +2414,7 @@ class XVideosIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(1) webpage = self._download_webpage(url, video_id) @@ -2509,24 +2425,21 @@ class XVideosIE(InfoExtractor): # Extract video URL mobj = re.search(r'flv_url=(.+?)&', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video url') - return + raise ExtractorError(u'Unable to extract video url') video_url = compat_urllib_parse.unquote(mobj.group(1)) # Extract title mobj = re.search(r'(.*?)\s+-\s+XVID', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video title') - return + raise ExtractorError(u'Unable to extract video title') video_title = mobj.group(1) # Extract video thumbnail mobj = re.search(r'http://(?:img.*?\.)xvideos.com/videos/thumbs/[a-fA-F0-9]+/[a-fA-F0-9]+/[a-fA-F0-9]+/[a-fA-F0-9]+/([a-fA-F0-9.]+jpg)', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video thumbnail') - return + raise ExtractorError(u'Unable to extract video thumbnail') video_thumbnail = mobj.group(0) info = { @@ -2562,8 +2475,7 @@ class SoundcloudIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) # extract uploader (which is in the url) uploader = mobj.group(1) @@ -2620,8 +2532,7 @@ class SoundcloudSetIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) # extract uploader (which is in the url) uploader = mobj.group(1) @@ -2673,8 +2584,7 @@ class InfoQIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) webpage = self._download_webpage(url, video_id=url) self.report_extraction(url) @@ -2682,16 +2592,14 @@ class InfoQIE(InfoExtractor): # Extract video URL mobj = re.search(r"jsclassref ?= ?'([^']*)'", webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video url') - return + raise ExtractorError(u'Unable to extract video url') real_id = compat_urllib_parse.unquote(base64.b64decode(mobj.group(1).encode('ascii')).decode('utf-8')) video_url = 'rtmpe://video.infoq.com/cfx/st/' + real_id # Extract title mobj = re.search(r'contentTitle = "(.*?)";', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video title') - return + raise ExtractorError(u'Unable to extract video title') video_title = mobj.group(1) # Extract description @@ -2766,8 +2674,7 @@ class MixcloudIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) # extract uploader & filename from url uploader = mobj.group(1).decode('utf-8') file_id = uploader + "-" + mobj.group(2).decode('utf-8') @@ -2780,8 +2687,7 @@ class MixcloudIE(InfoExtractor): self.report_download_json(file_url) jsonData = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'Unable to retrieve file: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to retrieve file: %s' % compat_str(err)) # parse JSON json_data = json.loads(jsonData) @@ -2804,8 +2710,7 @@ class MixcloudIE(InfoExtractor): break # got it! else: if req_format not in formats: - self._downloader.report_error(u'format is not available') - return + raise ExtractorError(u'Format is not available') url_list = self.get_urls(formats, req_format) file_url = self.check_urls(url_list) @@ -2850,15 +2755,13 @@ class StanfordOpenClassroomIE(InfoExtractor): try: metaXml = compat_urllib_request.urlopen(xmlUrl).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download video info XML: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to download video info XML: %s' % compat_str(err)) mdoc = xml.etree.ElementTree.fromstring(metaXml) try: info['title'] = mdoc.findall('./title')[0].text info['url'] = baseUrl + mdoc.findall('./videoFile')[0].text except IndexError: - self._downloader.report_error(u'Invalid metadata XML file') - return + raise ExtractorError(u'Invalid metadata XML file') info['ext'] = info['url'].rpartition('.')[2] return [info] elif mobj.group('course'): # A course page @@ -2909,8 +2812,7 @@ class StanfordOpenClassroomIE(InfoExtractor): try: rootpage = compat_urllib_request.urlopen(rootURL).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download course info page: ' + compat_str(err)) - return + raise ExtractorError(u'Unable to download course info page: ' + compat_str(err)) info['title'] = info['id'] @@ -2937,8 +2839,7 @@ class MTVIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) if not mobj.group('proto'): url = 'http://' + url video_id = mobj.group('videoid') @@ -2947,26 +2848,22 @@ class MTVIE(InfoExtractor): mobj = re.search(r'<meta name="mtv_vt" content="([^"]+)"/>', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract song name') - return + raise ExtractorError(u'Unable to extract song name') song_name = unescapeHTML(mobj.group(1).decode('iso-8859-1')) mobj = re.search(r'<meta name="mtv_an" content="([^"]+)"/>', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract performer') - return + raise ExtractorError(u'Unable to extract performer') performer = unescapeHTML(mobj.group(1).decode('iso-8859-1')) video_title = performer + ' - ' + song_name mobj = re.search(r'<meta name="mtvn_uri" content="([^"]+)"/>', webpage) if mobj is None: - self._downloader.report_error(u'unable to mtvn_uri') - return + raise ExtractorError(u'Unable to mtvn_uri') mtvn_uri = mobj.group(1) mobj = re.search(r'MTVN.Player.defaultPlaylistId = ([0-9]+);', webpage) if mobj is None: - self._downloader.report_error(u'unable to extract content id') - return + raise ExtractorError(u'Unable to extract content id') content_id = mobj.group(1) videogen_url = 'http://www.mtv.com/player/includes/mediaGen.jhtml?uri=' + mtvn_uri + '&id=' + content_id + '&vid=' + video_id + '&ref=www.mtvn.com&viewUri=' + mtvn_uri @@ -2975,8 +2872,7 @@ class MTVIE(InfoExtractor): try: metadataXml = compat_urllib_request.urlopen(request).read() except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - self._downloader.report_error(u'unable to download video metadata: %s' % compat_str(err)) - return + raise ExtractorError(u'Unable to download video metadata: %s' % compat_str(err)) mdoc = xml.etree.ElementTree.fromstring(metadataXml) renditions = mdoc.findall('.//rendition') @@ -2989,8 +2885,7 @@ class MTVIE(InfoExtractor): format = ext + '-' + rendition.attrib['width'] + 'x' + rendition.attrib['height'] + '_' + rendition.attrib['bitrate'] video_url = rendition.find('./src').text except KeyError: - self._downloader.report_error('Invalid rendition field.') - return + raise ExtractorError('Invalid rendition field.') info = { 'id': video_id, @@ -3039,8 +2934,7 @@ class YoukuIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group('ID') info_url = 'http://v.youku.com/player/getPlayList/VideoIDS/' + video_id @@ -3074,8 +2968,7 @@ class YoukuIE(InfoExtractor): fileid = config['data'][0]['streamfileids'][format] keys = [s['k'] for s in config['data'][0]['segs'][format]] except (UnicodeDecodeError, ValueError, KeyError): - self._downloader.report_error(u'unable to extract info section') - return + raise ExtractorError(u'Unable to extract info section') files_info=[] sid = self._gen_sid() @@ -3113,8 +3006,7 @@ class XNXXIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(1) # Get webpage content @@ -3122,20 +3014,17 @@ class XNXXIE(InfoExtractor): result = re.search(self.VIDEO_URL_RE, webpage) if result is None: - self._downloader.report_error(u'unable to extract video url') - return + raise ExtractorError(u'Unable to extract video url') video_url = compat_urllib_parse.unquote(result.group(1)) result = re.search(self.VIDEO_TITLE_RE, webpage) if result is None: - self._downloader.report_error(u'unable to extract video title') - return + raise ExtractorError(u'Unable to extract video title') video_title = result.group(1) result = re.search(self.VIDEO_THUMB_RE, webpage) if result is None: - self._downloader.report_error(u'unable to extract video thumbnail') - return + raise ExtractorError(u'Unable to extract video thumbnail') video_thumbnail = result.group(1) return [{ @@ -3180,8 +3069,7 @@ class GooglePlusIE(InfoExtractor): # Extract id from URL mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'Invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) post_url = mobj.group(0) video_id = mobj.group(1) @@ -3268,8 +3156,7 @@ class NBAIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group(1) if video_id.endswith('/index.html'): @@ -3641,8 +3528,7 @@ class YouPornIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group('videoid') @@ -3733,8 +3619,7 @@ class YouPornIE(InfoExtractor): else: format = self._specific( req_format, formats ) if result is None: - self._downloader.report_error(u'requested format not available') - return + raise ExtractorError(u'Requested format not available') return [format] @@ -3746,8 +3631,7 @@ class PornotubeIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group('videoid') video_title = mobj.group('title') @@ -3759,16 +3643,14 @@ class PornotubeIE(InfoExtractor): VIDEO_URL_RE = r'url: "(?P<url>http://video[0-9].pornotube.com/.+\.flv)",' result = re.search(VIDEO_URL_RE, webpage) if result is None: - self._downloader.report_error(u'unable to extract video url') - return + raise ExtractorError(u'Unable to extract video url') video_url = compat_urllib_parse.unquote(result.group('url')) #Get the uploaded date VIDEO_UPLOADED_RE = r'<div class="video_added_by">Added (?P<date>[0-9\/]+) by' result = re.search(VIDEO_UPLOADED_RE, webpage) if result is None: - self._downloader.report_error(u'unable to extract video title') - return + raise ExtractorError(u'Unable to extract video title') upload_date = unified_strdate(result.group('date')) info = {'id': video_id, @@ -3788,8 +3670,7 @@ class YouJizzIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group('videoid') @@ -3995,14 +3876,12 @@ class MySpassIE(InfoExtractor): # extract values from metadata url_flv_el = metadata.find('url_flv') if url_flv_el is None: - self._downloader.report_error(u'unable to extract download url') - return + raise ExtractorError(u'Unable to extract download url') video_url = url_flv_el.text extension = os.path.splitext(video_url)[1][1:] title_el = metadata.find('title') if title_el is None: - self._downloader.report_error(u'unable to extract title') - return + raise ExtractorError(u'Unable to extract title') title = title_el.text format_id_el = metadata.find('format_id') if format_id_el is None: @@ -4071,8 +3950,7 @@ class LiveLeakIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) if mobj is None: - self._downloader.report_error(u'invalid URL: %s' % url) - return + raise ExtractorError(u'Invalid URL: %s' % url) video_id = mobj.group('video_id') @@ -4080,8 +3958,7 @@ class LiveLeakIE(InfoExtractor): m = re.search(r'file: "(.*?)",', webpage) if not m: - self._downloader.report_error(u'unable to find video url') - return + raise ExtractorError(u'Unable to find video url') video_url = m.group(1) m = re.search(r'<meta property="og:title" content="(?P<title>.*?)"', webpage) @@ -4133,8 +4010,7 @@ class ARDIE(InfoExtractor): streams = [m.groupdict() for m in re.finditer(self._MEDIA_STREAM, html)] if not streams: assert '"fsk"' in html - self._downloader.report_error(u'this video is only available after 8:00 pm') - return + raise ExtractorError(u'This video is only available after 8:00 pm') # choose default media type and highest quality for now stream = max([s for s in streams if int(s["media_type"]) == 0], @@ -4196,8 +4072,8 @@ class BandcampIE(InfoExtractor): # We get the link to the free download page m_download = re.search(r'freeDownloadPage: "(.*?)"', webpage) if m_download is None: - self._downloader.report_error('No free songs founded') - return + raise ExtractorError(u'No free songs founded') + download_link = m_download.group(1) id = re.search(r'var TralbumData = {(.*?)id: (?P<id>\d*?)$', webpage, re.MULTILINE|re.DOTALL).group('id') From f8602d32429bf8a7dace35bcab91ba6be092cfde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Sun, 5 May 2013 11:48:47 +0200 Subject: [PATCH 3/5] ArteTvIE: Fix format of upload date --- youtube_dl/InfoExtractors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/InfoExtractors.py b/youtube_dl/InfoExtractors.py index 0c544d747..8c3751d0a 100755 --- a/youtube_dl/InfoExtractors.py +++ b/youtube_dl/InfoExtractors.py @@ -1218,7 +1218,7 @@ class ArteTvIE(InfoExtractor): 'id': info.get('id'), 'url': compat_urllib_parse.unquote(info.get('url')), 'uploader': u'arte.tv', - 'upload_date': info.get('date'), + 'upload_date': unified_strdate(info.get('date')), 'title': info.get('title').decode('utf-8'), 'ext': u'mp4', 'format': u'NA', From d96680f58d918c99baab952338f547c42266bdf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Sun, 5 May 2013 13:07:00 +0200 Subject: [PATCH 4/5] PhotobucketIE: accept new format of urls and add a test --- test/tests.json | 9 +++++++++ youtube_dl/InfoExtractors.py | 31 ++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/test/tests.json b/test/tests.json index b4d511dd8..66e93a33a 100644 --- a/test/tests.json +++ b/test/tests.json @@ -411,5 +411,14 @@ "info_dict":{ "title":"Sucked on a toilet" } + }, + { + "name": "Photobucket", + "url": "http://media.photobucket.com/user/rachaneronas/media/TiredofLinkBuildingTryBacklinkMyDomaincom_zpsc0c3b9fa.mp4.html?filters[term]=search&filters[primary]=videos&filters[secondary]=images&sort=1&o=0", + "file": "zpsc0c3b9fa.mp4", + "md5": "7dabfb92b0a31f6c16cebc0f8e60ff99", + "info_dict":{ + "title":"Tired of Link Building? Try BacklinkMyDomain.com!" + } } ] diff --git a/youtube_dl/InfoExtractors.py b/youtube_dl/InfoExtractors.py index 8c3751d0a..a98d403b3 100755 --- a/youtube_dl/InfoExtractors.py +++ b/youtube_dl/InfoExtractors.py @@ -848,7 +848,10 @@ class DailymotionIE(InfoExtractor): class PhotobucketIE(InfoExtractor): """Information extractor for photobucket.com.""" - _VALID_URL = r'(?:http://)?(?:[a-z0-9]+\.)?photobucket\.com/.*[\?\&]current=(.*\.flv)' + # TODO: the original _VALID_URL was: + # r'(?:http://)?(?:[a-z0-9]+\.)?photobucket\.com/.*[\?\&]current=(.*\.flv)' + # Check if it's necessary to keep the old extracion process + _VALID_URL = r'(?:http://)?(?:[a-z0-9]+\.)?photobucket\.com/.*(([\?\&]current=)|_)(?P<id>.*)\.(?P<ext>(flv)|(mp4))' IE_NAME = u'photobucket' def _real_extract(self, url): @@ -857,20 +860,30 @@ class PhotobucketIE(InfoExtractor): if mobj is None: raise ExtractorError(u'Invalid URL: %s' % url) - video_id = mobj.group(1) + video_id = mobj.group('id') - video_extension = 'flv' + video_extension = mobj.group('ext') # Retrieve video webpage to extract further information - request = compat_urllib_request.Request(url) - try: - self.report_download_webpage(video_id) - webpage = compat_urllib_request.urlopen(request).read() - except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err: - raise ExtractorError(u'Unable to retrieve video webpage: %s' % compat_str(err)) + webpage = self._download_webpage(url, video_id) # Extract URL, uploader, and title from webpage self.report_extraction(video_id) + # We try first by looking the javascript code: + mobj = re.search(r'Pb\.Data\.Shared\.put\(Pb\.Data\.Shared\.MEDIA, (?P<json>.*?)\);', webpage) + if mobj is not None: + info = json.loads(mobj.group('json')) + return [{ + 'id': video_id, + 'url': info[u'downloadUrl'], + 'uploader': info[u'username'], + 'upload_date': datetime.date.fromtimestamp(info[u'creationDate']).strftime('%Y%m%d'), + 'title': info[u'title'], + 'ext': video_extension, + 'thumbnail': info[u'thumbUrl'], + }] + + # We try looking in other parts of the webpage mobj = re.search(r'<link rel="video_src" href=".*\?file=([^"]+)" />', webpage) if mobj is None: raise ExtractorError(u'Unable to extract media URL') From 486f0c947675eebb129414f8f46010206c9245b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Sun, 5 May 2013 13:59:25 +0200 Subject: [PATCH 5/5] More callbacks changed to raise ExtractorError --- youtube_dl/InfoExtractors.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/youtube_dl/InfoExtractors.py b/youtube_dl/InfoExtractors.py index a98d403b3..0f1252113 100755 --- a/youtube_dl/InfoExtractors.py +++ b/youtube_dl/InfoExtractors.py @@ -3125,7 +3125,7 @@ class GooglePlusIE(InfoExtractor): pattern = '"(https\://plus\.google\.com/photos/.*?)",,"image/jpeg","video"\]' mobj = re.search(pattern, webpage) if mobj is None: - self._downloader.report_error(u'unable to extract video page URL') + raise ExtractorError(u'Unable to extract video page URL') video_page = mobj.group(1) webpage = self._download_webpage(video_page, video_id, u'Downloading video page') @@ -3137,7 +3137,7 @@ class GooglePlusIE(InfoExtractor): pattern = '\d+,\d+,(\d+),"(http\://redirector\.googlevideo\.com.*?)"' mobj = re.findall(pattern, webpage) if len(mobj) == 0: - self._downloader.report_error(u'unable to extract video links') + raise ExtractorError(u'Unable to extract video links') # Sort in resolution links = sorted(mobj) @@ -3343,14 +3343,14 @@ class FunnyOrDieIE(InfoExtractor): m = re.search(r'<video[^>]*>\s*<source[^>]*>\s*<source src="(?P<url>[^"]+)"', webpage, re.DOTALL) if not m: - self._downloader.report_error(u'unable to find video information') + raise ExtractorError(u'Unable to find video information') video_url = unescapeHTML(m.group('url')) m = re.search(r"<h1 class='player_page_h1'.*?>(?P<title>.*?)</h1>", webpage, flags=re.DOTALL) if not m: m = re.search(r'<title>(?P<title>[^<]+?)', webpage) if not m: - self._downloader.report_error(u'Cannot find video title') + raise ExtractorError(u'Cannot find video title') title = clean_html(m.group('title')) m = re.search(r'