TumblrIE
[youtube-dl] / youtube_dl / InfoExtractors.py
index 86a8ca511460a2c7b8ef806d4b37211e75b87947..6a6545c9b578fba948962542d602bc5352b86840 100755 (executable)
@@ -116,7 +116,7 @@ class InfoExtractor(object):
         if note is None:
             note = u'Downloading video webpage'
         if note is not False:
-            self._downloader.to_screen(u'[%s] %s: %s' % (self.IE_NAME, video_id, note))
+            self.to_screen(u'%s: %s' % (video_id, note))
         try:
             return compat_urllib_request.urlopen(url_or_request)
         except (compat_urllib_error.URLError, compat_http_client.HTTPException, socket.error) as err:
@@ -139,11 +139,23 @@ class InfoExtractor(object):
                 url = url_or_request.get_full_url()
             except AttributeError:
                 url = url_or_request
-            self._downloader.to_screen(u'Dumping request to ' + url)
+            self.to_screen(u'Dumping request to ' + url)
             dump = base64.b64encode(webpage_bytes).decode('ascii')
             self._downloader.to_screen(dump)
         return webpage_bytes.decode(encoding, 'replace')
-        
+
+    def to_screen(self, msg):
+        """Print msg to screen, prefixing it with '[ie_name]'"""
+        self._downloader.to_screen(u'[%s] %s' % (self.IE_NAME, msg))
+
+    def report_extraction(self, id_or_name):
+        """Report information extraction."""
+        self.to_screen(u'%s: Extracting information' % id_or_name)
+
+    def report_age_confirmation(self):
+        """Report attempt to confirm age."""
+        self.to_screen(u'Confirming age')
+
     #Methods for following #608
     #They set the correct value of the '_type' key
     def video_result(self, video_info):
@@ -236,48 +248,44 @@ class YoutubeIE(InfoExtractor):
 
     def report_lang(self):
         """Report attempt to set language."""
-        self._downloader.to_screen(u'[youtube] Setting language')
+        self.to_screen(u'Setting language')
 
     def report_login(self):
         """Report attempt to log in."""
-        self._downloader.to_screen(u'[youtube] Logging in')
-
-    def report_age_confirmation(self):
-        """Report attempt to confirm age."""
-        self._downloader.to_screen(u'[youtube] Confirming age')
+        self.to_screen(u'Logging in')
 
     def report_video_webpage_download(self, video_id):
         """Report attempt to download video webpage."""
-        self._downloader.to_screen(u'[youtube] %s: Downloading video webpage' % video_id)
+        self.to_screen(u'%s: Downloading video webpage' % video_id)
 
     def report_video_info_webpage_download(self, video_id):
         """Report attempt to download video info webpage."""
-        self._downloader.to_screen(u'[youtube] %s: Downloading video info webpage' % video_id)
+        self.to_screen(u'%s: Downloading video info webpage' % video_id)
 
     def report_video_subtitles_download(self, video_id):
         """Report attempt to download video info webpage."""
-        self._downloader.to_screen(u'[youtube] %s: Checking available subtitles' % video_id)
+        self.to_screen(u'%s: Checking available subtitles' % video_id)
 
     def report_video_subtitles_request(self, video_id, sub_lang, format):
         """Report attempt to download video info webpage."""
-        self._downloader.to_screen(u'[youtube] %s: Downloading video subtitles for %s.%s' % (video_id, sub_lang, format))
+        self.to_screen(u'%s: Downloading video subtitles for %s.%s' % (video_id, sub_lang, format))
 
     def report_video_subtitles_available(self, video_id, sub_lang_list):
         """Report available subtitles."""
         sub_lang = ",".join(list(sub_lang_list.keys()))
-        self._downloader.to_screen(u'[youtube] %s: Available subtitles for video: %s' % (video_id, sub_lang))
+        self.to_screen(u'%s: Available subtitles for video: %s' % (video_id, sub_lang))
 
     def report_information_extraction(self, video_id):
         """Report attempt to extract video information."""
-        self._downloader.to_screen(u'[youtube] %s: Extracting video information' % video_id)
+        self.to_screen(u'%s: Extracting video information' % video_id)
 
     def report_unavailable_format(self, video_id, format):
         """Report extracted video URL."""
-        self._downloader.to_screen(u'[youtube] %s: Format %s not available' % (video_id, format))
+        self.to_screen(u'%s: Format %s not available' % (video_id, format))
 
     def report_rtmp_download(self):
         """Indicate the download will use the RTMP protocol."""
-        self._downloader.to_screen(u'[youtube] RTMP download detected')
+        self.to_screen(u'RTMP download detected')
 
     def _get_available_subtitles(self, video_id):
         self.report_video_subtitles_download(video_id)
@@ -614,8 +622,7 @@ class YoutubeIE(InfoExtractor):
                 format_list = available_formats
             existing_formats = [x for x in format_list if x in url_map]
             if len(existing_formats) == 0:
-                self._downloader.report_error(u'no known formats available for video')
-                return
+                raise ExtractorError(u'no known formats available for video')
             if self._downloader.params.get('listformats', None):
                 self._print_formats(existing_formats)
                 return
@@ -635,11 +642,9 @@ class YoutubeIE(InfoExtractor):
                         video_url_list = [(rf, url_map[rf])]
                         break
                 if video_url_list is None:
-                    self._downloader.report_error(u'requested format not available')
-                    return
+                    raise ExtractorError(u'requested format not available')
         else:
-            self._downloader.report_error(u'no conn or url_encoded_fmt_stream_map information found in video info')
-            return
+            raise ExtractorError(u'no conn or url_encoded_fmt_stream_map information found in video info')
 
         results = []
         for format_param, video_real_url in video_url_list:
@@ -680,19 +685,11 @@ class MetacafeIE(InfoExtractor):
 
     def report_disclaimer(self):
         """Report disclaimer retrieval."""
-        self._downloader.to_screen(u'[metacafe] Retrieving disclaimer')
-
-    def report_age_confirmation(self):
-        """Report attempt to confirm age."""
-        self._downloader.to_screen(u'[metacafe] Confirming age')
+        self.to_screen(u'Retrieving disclaimer')
 
     def report_download_webpage(self, video_id):
         """Report webpage download."""
-        self._downloader.to_screen(u'[metacafe] %s: Downloading webpage' % video_id)
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[metacafe] %s: Extracting information' % video_id)
+        self.to_screen(u'%s: Downloading webpage' % video_id)
 
     def _real_initialize(self):
         # Retrieve disclaimer
@@ -797,10 +794,6 @@ class DailymotionIE(InfoExtractor):
     def __init__(self, downloader=None):
         InfoExtractor.__init__(self, downloader)
 
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[dailymotion] %s: Extracting information' % video_id)
-
     def _real_extract(self, url):
         # Extract id and simplified title from URL
         mobj = re.match(self._VALID_URL, url)
@@ -828,7 +821,7 @@ class DailymotionIE(InfoExtractor):
         for key in ['hd1080URL', 'hd720URL', 'hqURL', 'sdURL', 'ldURL', 'video_url']:
             if key in flashvars:
                 max_quality = key
-                self._downloader.to_screen(u'[dailymotion] Using %s' % key)
+                self.to_screen(u'Using %s' % key)
                 break
         else:
             self._downloader.report_error(u'unable to extract video URL')
@@ -887,11 +880,7 @@ class PhotobucketIE(InfoExtractor):
 
     def report_download_webpage(self, video_id):
         """Report webpage download."""
-        self._downloader.to_screen(u'[photobucket] %s: Downloading webpage' % video_id)
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[photobucket] %s: Extracting information' % video_id)
+        self.to_screen(u'%s: Downloading webpage' % video_id)
 
     def _real_extract(self, url):
         # Extract id from URL
@@ -956,11 +945,7 @@ class YahooIE(InfoExtractor):
 
     def report_download_webpage(self, video_id):
         """Report webpage download."""
-        self._downloader.to_screen(u'[video.yahoo] %s: Downloading webpage' % video_id)
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[video.yahoo] %s: Extracting information' % video_id)
+        self.to_screen(u'%s: Downloading webpage' % video_id)
 
     def _real_extract(self, url, new_video=True):
         # Extract ID from URL
@@ -1096,11 +1081,7 @@ class VimeoIE(InfoExtractor):
 
     def report_download_webpage(self, video_id):
         """Report webpage download."""
-        self._downloader.to_screen(u'[vimeo] %s: Downloading webpage' % video_id)
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[vimeo] %s: Extracting information' % video_id)
+        self.to_screen(u'%s: Downloading webpage' % video_id)
 
     def _real_extract(self, url, new_video=True):
         # Extract ID from URL
@@ -1182,7 +1163,7 @@ class VimeoIE(InfoExtractor):
                 video_quality = files[quality][0][2]
                 video_codec = files[quality][0][0]
                 video_extension = files[quality][0][1]
-                self._downloader.to_screen(u'[vimeo] %s: Downloading %s file at %s quality' % (video_id, video_codec.upper(), video_quality))
+                self.to_screen(u'%s: Downloading %s file at %s quality' % (video_id, video_codec.upper(), video_quality))
                 break
         else:
             self._downloader.report_error(u'no known codec found')
@@ -1217,11 +1198,7 @@ class ArteTvIE(InfoExtractor):
 
     def report_download_webpage(self, video_id):
         """Report webpage download."""
-        self._downloader.to_screen(u'[arte.tv] %s: Downloading webpage' % video_id)
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[arte.tv] %s: Extracting information' % video_id)
+        self.to_screen(u'%s: Downloading webpage' % video_id)
 
     def fetch_webpage(self, url):
         request = compat_urllib_request.Request(url)
@@ -1352,12 +1329,8 @@ class GenericIE(InfoExtractor):
     def report_download_webpage(self, video_id):
         """Report webpage download."""
         if not self._downloader.params.get('test', False):
-            self._downloader.to_screen(u'WARNING: Falling back on generic information extractor.')
-        self._downloader.to_screen(u'[generic] %s: Downloading webpage' % video_id)
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[generic] %s: Extracting information' % video_id)
+            self._downloader.report_warning(u'Falling back on generic information extractor.')
+        self.to_screen(u'%s: Downloading webpage' % video_id)
 
     def report_following_redirect(self, new_url):
         """Report information extraction."""
@@ -1575,7 +1548,7 @@ class GoogleSearchIE(InfoExtractor):
     def report_download_page(self, query, pagenum):
         """Report attempt to download playlist page with given number."""
         query = query.decode(preferredencoding())
-        self._downloader.to_screen(u'[video.google] query "%s": Downloading page %s' % (query, pagenum))
+        self.to_screen(u'query "%s": Downloading page %s' % (query, pagenum))
 
     def _real_extract(self, query):
         mobj = re.match(self._VALID_URL, query)
@@ -1659,7 +1632,7 @@ class YahooSearchIE(InfoExtractor):
     def report_download_page(self, query, pagenum):
         """Report attempt to download playlist page with given number."""
         query = query.decode(preferredencoding())
-        self._downloader.to_screen(u'[video.yahoo] query "%s": Downloading page %s' % (query, pagenum))
+        self.to_screen(u'query "%s": Downloading page %s' % (query, pagenum))
 
     def _real_extract(self, query):
         mobj = re.match(self._VALID_URL, query)
@@ -1970,8 +1943,8 @@ class BlipTVUserIE(InfoExtractor):
 
     def report_download_page(self, username, pagenum):
         """Report attempt to download user page."""
-        self._downloader.to_screen(u'[%s] user %s: Downloading video ids from page %d' %
-                (self.IE_NAME, username, pagenum))
+        self.to_screen(u'user %s: Downloading video ids from page %d' %
+                (username, pagenum))
 
     def _real_extract(self, url):
         # Extract username
@@ -2045,11 +2018,7 @@ class DepositFilesIE(InfoExtractor):
 
     def report_download_webpage(self, file_id):
         """Report webpage download."""
-        self._downloader.to_screen(u'[DepositFiles] %s: Downloading webpage' % file_id)
-
-    def report_extraction(self, file_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[DepositFiles] %s: Extracting information' % file_id)
+        self.to_screen(u'%s: Downloading webpage' % file_id)
 
     def _real_extract(self, url):
         file_id = url.split('/')[-1]
@@ -2108,7 +2077,7 @@ class FacebookIE(InfoExtractor):
 
     def report_login(self):
         """Report attempt to log in."""
-        self._downloader.to_screen(u'[%s] Logging in' % self.IE_NAME)
+        self.to_screen(u'Logging in')
 
     def _real_initialize(self):
         if self._downloader is None:
@@ -2204,13 +2173,9 @@ class BlipTVIE(InfoExtractor):
     _URL_EXT = r'^.*\.([a-z0-9]+)$'
     IE_NAME = u'blip.tv'
 
-    def report_extraction(self, file_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, file_id))
-
     def report_direct_download(self, title):
         """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Direct download detected' % (self.IE_NAME, title))
+        self.to_screen(u'%s: Direct download detected' % title)
 
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
@@ -2308,10 +2273,6 @@ class MyVideoIE(InfoExtractor):
     def __init__(self, downloader=None):
         InfoExtractor.__init__(self, downloader)
 
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[myvideo] %s: Extracting information' % video_id)
-
     def _real_extract(self,url):
         mobj = re.match(self._VALID_URL, url)
         if mobj is None:
@@ -2389,14 +2350,11 @@ class ComedyCentralIE(InfoExtractor):
         """Receives a URL and returns True if suitable for this IE."""
         return re.match(cls._VALID_URL, url, re.VERBOSE) is not None
 
-    def report_extraction(self, episode_id):
-        self._downloader.to_screen(u'[comedycentral] %s: Extracting information' % episode_id)
-
     def report_config_download(self, episode_id, media_id):
-        self._downloader.to_screen(u'[comedycentral] %s: Downloading configuration for %s' % (episode_id, media_id))
+        self.to_screen(u'%s: Downloading configuration for %s' % (episode_id, media_id))
 
     def report_index_download(self, episode_id):
-        self._downloader.to_screen(u'[comedycentral] %s: Downloading show index' % episode_id)
+        self.to_screen(u'%s: Downloading show index' % episode_id)
 
     def _print_formats(self, formats):
         print('Available formats:')
@@ -2550,11 +2508,8 @@ class EscapistIE(InfoExtractor):
     _VALID_URL = r'^(https?://)?(www\.)?escapistmagazine\.com/videos/view/(?P<showname>[^/]+)/(?P<episode>[^/?]+)[/?]?.*$'
     IE_NAME = u'escapist'
 
-    def report_extraction(self, showName):
-        self._downloader.to_screen(u'[escapist] %s: Extracting information' % showName)
-
     def report_config_download(self, showName):
-        self._downloader.to_screen(u'[escapist] %s: Downloading configuration' % showName)
+        self.to_screen(u'%s: Downloading configuration' % showName)
 
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
@@ -2627,11 +2582,7 @@ class CollegeHumorIE(InfoExtractor):
 
     def report_manifest(self, video_id):
         """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Downloading XML manifest' % (self.IE_NAME, video_id))
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, video_id))
+        self.to_screen(u'%s: Downloading XML manifest' % video_id)
 
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
@@ -2696,10 +2647,6 @@ class XVideosIE(InfoExtractor):
     _VALID_URL = r'^(?:https?://)?(?:www\.)?xvideos\.com/video([0-9]+)(?:.*)'
     IE_NAME = u'xvideos'
 
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, video_id))
-
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
         if mobj is None:
@@ -2766,11 +2713,7 @@ class SoundcloudIE(InfoExtractor):
 
     def report_resolve(self, video_id):
         """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Resolving id' % (self.IE_NAME, video_id))
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Retrieving stream' % (self.IE_NAME, video_id))
+        self.to_screen(u'%s: Resolving id' % video_id)
 
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
@@ -2839,11 +2782,7 @@ class SoundcloudSetIE(InfoExtractor):
 
     def report_resolve(self, video_id):
         """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Resolving id' % (self.IE_NAME, video_id))
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Retrieving stream' % (self.IE_NAME, video_id))
+        self.to_screen(u'%s: Resolving id' % video_id)
 
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
@@ -2908,10 +2847,6 @@ class InfoQIE(InfoExtractor):
     """Information extractor for infoq.com"""
     _VALID_URL = r'^(?:https?://)?(?:www\.)?infoq\.com/[^/]+/[^/]+$'
 
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, video_id))
-
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
         if mobj is None:
@@ -2970,11 +2905,7 @@ class MixcloudIE(InfoExtractor):
 
     def report_download_json(self, file_id):
         """Report JSON download."""
-        self._downloader.to_screen(u'[%s] Downloading json' % self.IE_NAME)
-
-    def report_extraction(self, file_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, file_id))
+        self.to_screen(u'Downloading json')
 
     def get_urls(self, jsonData, fmt, bitrate='best'):
         """Get urls from 'audio_formats' section in json"""
@@ -3081,11 +3012,7 @@ class StanfordOpenClassroomIE(InfoExtractor):
 
     def report_download_webpage(self, objid):
         """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Downloading webpage' % (self.IE_NAME, objid))
-
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, video_id))
+        self.to_screen(u'%s: Downloading webpage' % objid)
 
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
@@ -3191,10 +3118,6 @@ class MTVIE(InfoExtractor):
     _VALID_URL = r'^(?P<proto>https?://)?(?:www\.)?mtv\.com/videos/[^/]+/(?P<videoid>[0-9]+)/[^/]+$'
     IE_NAME = u'mtv'
 
-    def report_extraction(self, video_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, video_id))
-
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
         if mobj is None:
@@ -3271,11 +3194,7 @@ class YoukuIE(InfoExtractor):
 
     def report_download_webpage(self, file_id):
         """Report webpage download."""
-        self._downloader.to_screen(u'[%s] %s: Downloading webpage' % (self.IE_NAME, file_id))
-
-    def report_extraction(self, file_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, file_id))
+        self.to_screen(u'%s: Downloading webpage' % file_id)
 
     def _gen_sid(self):
         nowTime = int(time.time() * 1000)
@@ -3388,11 +3307,7 @@ class XNXXIE(InfoExtractor):
 
     def report_webpage(self, video_id):
         """Report information extraction"""
-        self._downloader.to_screen(u'[%s] %s: Downloading webpage' % (self.IE_NAME, video_id))
-
-    def report_extraction(self, video_id):
-        """Report information extraction"""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, video_id))
+        self.to_screen(u'%s: Downloading webpage' % video_id)
 
     def _real_extract(self, url):
         mobj = re.match(self._VALID_URL, url)
@@ -3452,23 +3367,23 @@ class GooglePlusIE(InfoExtractor):
 
     def report_extract_entry(self, url):
         """Report downloading extry"""
-        self._downloader.to_screen(u'[plus.google] Downloading entry: %s' % url)
+        self.to_screen(u'Downloading entry: %s' % url)
 
     def report_date(self, upload_date):
         """Report downloading extry"""
-        self._downloader.to_screen(u'[plus.google] Entry date: %s' % upload_date)
+        self.to_screen(u'Entry date: %s' % upload_date)
 
     def report_uploader(self, uploader):
         """Report downloading extry"""
-        self._downloader.to_screen(u'[plus.google] Uploader: %s' % uploader)
+        self.to_screen(u'Uploader: %s' % uploader)
 
     def report_title(self, video_title):
         """Report downloading extry"""
-        self._downloader.to_screen(u'[plus.google] Title: %s' % video_title)
+        self.to_screen(u'Title: %s' % video_title)
 
     def report_extract_vid_page(self, video_page):
         """Report information extraction."""
-        self._downloader.to_screen(u'[plus.google] Extracting video page: %s' % video_page)
+        self.to_screen(u'Extracting video page: %s' % video_page)
 
     def _real_extract(self, url):
         # Extract id from URL
@@ -3612,14 +3527,10 @@ class JustinTVIE(InfoExtractor):
     _JUSTIN_PAGE_LIMIT = 100
     IE_NAME = u'justin.tv'
 
-    def report_extraction(self, file_id):
-        """Report information extraction."""
-        self._downloader.to_screen(u'[%s] %s: Extracting information' % (self.IE_NAME, file_id))
-
     def report_download_page(self, channel, offset):
         """Report attempt to download a single page of videos."""
-        self._downloader.to_screen(u'[%s] %s: Downloading video information from %d to %d' %
-                (self.IE_NAME, channel, offset, offset + self._JUSTIN_PAGE_LIMIT))
+        self.to_screen(u'%s: Downloading video information from %d to %d' %
+                (channel, offset, offset + self._JUSTIN_PAGE_LIMIT))
 
     # Return count of items, list of *valid* items
     def _parse_page(self, url):
@@ -3741,10 +3652,13 @@ class SteamIE(InfoExtractor):
 
     def _real_extract(self, url):
         m = re.match(self._VALID_URL, url, re.VERBOSE)
-        urlRE = r"'movie_(?P<videoID>\d+)': \{\s*FILENAME: \"(?P<videoURL>[\w:/\.\?=]+)\"(,\s*MOVIE_NAME: \"(?P<videoName>[\w:/\.\?=\+-]+)\")?\s*\},"
         gameID = m.group('gameID')
-        videourl = 'http://store.steampowered.com/video/%s/' % gameID
+        videourl = 'http://store.steampowered.com/agecheck/video/%s/?snr=1_agecheck_agecheck__age-gate&ageDay=1&ageMonth=January&ageYear=1970' % gameID
+        self.report_age_confirmation()
         webpage = self._download_webpage(videourl, gameID)
+        game_title = re.search(r'<h2 class="pageheader">(?P<game_title>.*?)</h2>', webpage).group('game_title')
+        
+        urlRE = r"'movie_(?P<videoID>\d+)': \{\s*FILENAME: \"(?P<videoURL>[\w:/\.\?=]+)\"(,\s*MOVIE_NAME: \"(?P<videoName>[\w:/\.\?=\+-]+)\")?\s*\},"
         mweb = re.finditer(urlRE, webpage)
         namesRE = r'<span class="title">(?P<videoName>.+?)</span>'
         titles = re.finditer(namesRE, webpage)
@@ -3766,7 +3680,7 @@ class SteamIE(InfoExtractor):
                 'thumbnail': video_thumb
                   }
             videos.append(info)
-        return videos
+        return [self.playlist_result(videos, gameID, game_title)]
 
 class UstreamIE(InfoExtractor):
     _VALID_URL = r'https?://www\.ustream\.tv/recorded/(?P<videoID>\d+)'
@@ -3948,7 +3862,7 @@ class YouPornIE(InfoExtractor):
         if(len(links) == 0):
             raise ExtractorError(u'ERROR: no known formats available for video')
 
-        self._downloader.to_screen(u'[youporn] Links found: %d' % len(links))
+        self.to_screen(u'Links found: %d' % len(links))
 
         formats = []
         for link in links:
@@ -3984,7 +3898,7 @@ class YouPornIE(InfoExtractor):
             return
 
         req_format = self._downloader.params.get('format', None)
-        self._downloader.to_screen(u'[youporn] Format: %s' % req_format)
+        self.to_screen(u'Format: %s' % req_format)
 
         if req_format is None or req_format == 'best':
             return [formats[0]]
@@ -4179,7 +4093,7 @@ class TEDIE(InfoExtractor):
         else :
             playlist_id=m.group('playlist_id')
             name=m.group('name')
-            self._downloader.to_screen(u'[%s] Getting info of playlist %s: "%s"' % (self.IE_NAME,playlist_id,name))
+            self.to_screen(u'Getting info of playlist %s: "%s"' % (playlist_id,name))
             return [self._playlist_videos_info(url,name,playlist_id)]
 
     def _talk_video_link(self,mediaSlug):
@@ -4404,7 +4318,7 @@ class ARDIE(InfoExtractor):
         # there's two possibilities: RTMP stream or HTTP download
         info = {'id': video_id, 'title': title, 'ext': 'mp4'}
         if stream['rtmp_url']:
-            self._downloader.to_screen(u'[%s] RTMP download detected' % self.IE_NAME)
+            self.to_screen(u'RTMP download detected')
             assert stream['video_url'].startswith('mp4:')
             info["url"] = stream["rtmp_url"]
             info["play_path"] = stream['video_url']
@@ -4413,6 +4327,40 @@ class ARDIE(InfoExtractor):
             info["url"] = stream["video_url"]
         return [info]
 
+class TumblrIE(InfoExtractor):
+    _VALID_URL = r'http://(?P<blog_name>.*?).tumblr.com/((post)|(video))/(?P<id>\d*)/(.*?)'
+
+    def _real_extract(self, url):
+        m_url = re.match(self._VALID_URL, url)
+        video_id = m_url.group('id')
+        blog = m_url.group('blog_name')
+
+        url = 'http://%s.tumblr.com/post/%s/' % (blog, video_id)
+        webpage = self._download_webpage(url, video_id)
+
+        re_video = r'src=\\x22(?P<video_url>http://%s.tumblr.com/video_file/%s/(.*?))\\x22 type=\\x22video/(?P<ext>.*?)\\x22' % (blog, video_id)
+        video = re.search(re_video, webpage)
+        if video is None:
+            self.to_screen("No video founded")
+            return []
+        video_url = video.group('video_url')
+        ext = video.group('ext')
+
+        re_thumb = r'posters(.*?)\[\\x22(?P<thumb>.*?)\\x22'  # We pick the first poster
+        thumb = re.search(re_thumb, webpage).group('thumb').replace('\\', '')
+
+        # The only place where you can get a title, it's not complete,
+        # but searching in other places doesn't work for all videos
+        re_title = r'<title>(.*?) - (?P<title>.*?)</title>'
+        title = unescapeHTML(re.search(re_title, webpage).group('title'))
+
+        return [{'id': video_id,
+                 'url': video_url,
+                 'title': title,
+                 'thumbnail': thumb,
+                 'ext': ext
+                 }]
+
 
 def gen_extractors():
     """ Return a list of an instance of every supported extractor.
@@ -4467,6 +4415,7 @@ def gen_extractors():
         SpiegelIE(),
         LiveLeakIE(),
         ARDIE(),
+        TumblrIE(),
         GenericIE()
     ]