Merge pull request #797 from AI0867/patch-1
authorPhilipp Hagemeister <phihag@phihag.de>
Mon, 22 Apr 2013 21:13:52 +0000 (14:13 -0700)
committerPhilipp Hagemeister <phihag@phihag.de>
Mon, 22 Apr 2013 21:13:52 +0000 (14:13 -0700)
Use standard unit symbols in format_bytes

README.md
test/tests.json
youtube_dl/FileDownloader.py
youtube_dl/InfoExtractors.py
youtube_dl/__init__.py
youtube_dl/version.py

index d42aab44a8ddbf9f13c5ffc3fa4a228fd850bff1..5c7d8b66ac0ea40d055f22ec95bdb7bc374e912a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -56,10 +56,12 @@ which means you can modify it, redistribute it or use it however you like.
                                extension, %(upload_date)s for the upload date
                                (YYYYMMDD), %(extractor)s for the provider
                                (youtube, metacafe, etc), %(id)s for the video id
-                               and %% for a literal percent. Use - to output to
-                               stdout. Can also be used to download to a
-                               different directory, for example with -o '/my/dow
-                               nloads/%(uploader)s/%(title)s-%(id)s.%(ext)s' .
+                               , %(playlist)s for the playlist the video is in,
+                               %(playlist_index)s for the position in the
+                               playlist and %% for a literal percent. Use - to
+                               output to stdout. Can also be used to download to
+                               a different directory, for example with -o '/my/d
+                               ownloads/%(uploader)s/%(title)s-%(id)s.%(ext)s' .
     --autonumber-size NUMBER   Specifies the number of digits in %(autonumber)s
                                when it is present in output filename template or
                                --autonumber option is given
index 7808a07de24e7326ee7a690fb8d122e99fd6cfa1..2b56738a07c71fb9ab9282ed0d2e9fd8e1db210e 100644 (file)
         "title": "11.04.2013 09:23 Uhr - Tagesschau in 100 Sekunden"
     },
     "skip": "Requires rtmpdump"
+  },
+  {
+    "name": "Tumblr",
+    "url": "http://birthdayproject2012.tumblr.com/post/17258355236/a-sample-video-from-leeann-if-you-need-an-idea",
+    "file": "17258355236.mp4",
+    "md5": "7c6a514d691b034ccf8567999e9e88a3",
+    "info_dict": {
+        "title": "A sample video from LeeAnn. (If you need an idea..."
+    }
   }
 
 ]
index 19766153c477dd7a90bb3282ec51c9ea1001274e..100779756d956033ace52742d9be3ef13b821323 100644 (file)
@@ -458,6 +458,8 @@ class FileDownloader(object):
             # Extract information from URL and process it
             try:
                 ie_results = ie.extract(url)
+                if ie_results is None: # Finished already (backwards compatibility; listformats and friends should be moved here)
+                    break
                 results = []
                 for ie_result in ie_results:
                     if not 'extractor' in ie_result:
index 7c9f09f77b6d093e62e91735cf8ee8bb01db7408..6a6545c9b578fba948962542d602bc5352b86840 100755 (executable)
@@ -152,6 +152,10 @@ class InfoExtractor(object):
         """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):
@@ -250,10 +254,6 @@ class YoutubeIE(InfoExtractor):
         """Report attempt to log in."""
         self.to_screen(u'Logging in')
 
-    def report_age_confirmation(self):
-        """Report attempt to confirm age."""
-        self.to_screen(u'Confirming age')
-
     def report_video_webpage_download(self, video_id):
         """Report attempt to download video webpage."""
         self.to_screen(u'%s: Downloading video webpage' % video_id)
@@ -622,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
@@ -643,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:
@@ -690,10 +687,6 @@ class MetacafeIE(InfoExtractor):
         """Report disclaimer retrieval."""
         self.to_screen(u'Retrieving disclaimer')
 
-    def report_age_confirmation(self):
-        """Report attempt to confirm age."""
-        self.to_screen(u'Confirming age')
-
     def report_download_webpage(self, video_id):
         """Report webpage download."""
         self.to_screen(u'%s: Downloading webpage' % video_id)
@@ -3659,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)
@@ -3684,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+)'
@@ -4331,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.
@@ -4385,6 +4415,7 @@ def gen_extractors():
         SpiegelIE(),
         LiveLeakIE(),
         ARDIE(),
+        TumblrIE(),
         GenericIE()
     ]
 
index f46143e01b38c5af7cc2999402bbfa2f2ae51d7e..f60fb841e35e50eb576274f46ce7d776cb8c7ccf 100644 (file)
@@ -47,7 +47,7 @@ from .FileDownloader import *
 from .InfoExtractors import gen_extractors
 from .PostProcessor import *
 
-def parseOpts():
+def parseOpts(overrideArguments=None):
     def _readOptions(filename_bytes):
         try:
             optionf = open(filename_bytes)
@@ -238,7 +238,16 @@ def parseOpts():
             action='store_true', dest='autonumber',
             help='number downloaded files starting from 00000', default=False)
     filesystem.add_option('-o', '--output',
-            dest='outtmpl', metavar='TEMPLATE', help='output filename template. Use %(title)s to get the title, %(uploader)s for the uploader name, %(uploader_id)s for the uploader nickname if different, %(autonumber)s to get an automatically incremented number, %(ext)s for the filename extension, %(upload_date)s for the upload date (YYYYMMDD), %(extractor)s for the provider (youtube, metacafe, etc), %(id)s for the video id and %% for a literal percent. Use - to output to stdout. Can also be used to download to a different directory, for example with -o \'/my/downloads/%(uploader)s/%(title)s-%(id)s.%(ext)s\' .')
+            dest='outtmpl', metavar='TEMPLATE',
+            help=('output filename template. Use %(title)s to get the title, '
+                  '%(uploader)s for the uploader name, %(uploader_id)s for the uploader nickname if different, '
+                  '%(autonumber)s to get an automatically incremented number, '
+                  '%(ext)s for the filename extension, %(upload_date)s for the upload date (YYYYMMDD), '
+                  '%(extractor)s for the provider (youtube, metacafe, etc), '
+                  '%(id)s for the video id , %(playlist)s for the playlist the video is in, '
+                  '%(playlist_index)s for the position in the playlist and %% for a literal percent. '
+                  'Use - to output to stdout. Can also be used to download to a different directory, '
+                  'for example with -o \'/my/downloads/%(uploader)s/%(title)s-%(id)s.%(ext)s\' .'))
     filesystem.add_option('--autonumber-size',
             dest='autonumber_size', metavar='NUMBER',
             help='Specifies the number of digits in %(autonumber)s when it is present in output filename template or --autonumber option is given')
@@ -291,16 +300,21 @@ def parseOpts():
     parser.add_option_group(authentication)
     parser.add_option_group(postproc)
 
-    xdg_config_home = os.environ.get('XDG_CONFIG_HOME')
-    if xdg_config_home:
-        userConfFile = os.path.join(xdg_config_home, 'youtube-dl.conf')
+    if overrideArguments is not None:
+        opts, args = parser.parse_args(overrideArguments)
+        if opts.verbose:
+            print(u'[debug] Override config: ' + repr(overrideArguments))
     else:
-        userConfFile = os.path.join(os.path.expanduser('~'), '.config', 'youtube-dl.conf')
-    systemConf = _readOptions('/etc/youtube-dl.conf')
-    userConf = _readOptions(userConfFile)
-    commandLineConf = sys.argv[1:]
-    argv = systemConf + userConf + commandLineConf
-    opts, args = parser.parse_args(argv)
+        xdg_config_home = os.environ.get('XDG_CONFIG_HOME')
+        if xdg_config_home:
+            userConfFile = os.path.join(xdg_config_home, 'youtube-dl.conf')
+        else:
+            userConfFile = os.path.join(os.path.expanduser('~'), '.config', 'youtube-dl.conf')
+        systemConf = _readOptions('/etc/youtube-dl.conf')
+        userConf = _readOptions(userConfFile)
+        commandLineConf = sys.argv[1:] 
+        argv = systemConf + userConf + commandLineConf
+        opts, args = parser.parse_args(argv)
 
     if opts.verbose:
         print(u'[debug] System config: ' + repr(systemConf))
@@ -309,8 +323,8 @@ def parseOpts():
 
     return parser, opts, args
 
-def _real_main():
-    parser, opts, args = parseOpts()
+def _real_main(argv=None):
+    parser, opts, args = parseOpts(argv)
 
     # Open appropriate CookieJar
     if opts.cookiefile is None:
@@ -544,9 +558,9 @@ def _real_main():
 
     sys.exit(retcode)
 
-def main():
+def main(argv=None):
     try:
-        _real_main()
+        _real_main(argv)
     except DownloadError:
         sys.exit(1)
     except SameFileError:
index 2fd5f40c80c9cfab4964ad7d524aa488bbef57de..ac8a05ab57b98343e1c5e273f9d300c763062b87 100644 (file)
@@ -1,2 +1,2 @@
 
-__version__ = '2013.04.18'
+__version__ = '2013.04.22'