diff options
| -rw-r--r-- | README.md | 10 | ||||
| -rw-r--r-- | test/tests.json | 9 | ||||
| -rw-r--r-- | youtube_dl/FileDownloader.py | 2 | ||||
| -rwxr-xr-x | youtube_dl/InfoExtractors.py | 65 | ||||
| -rw-r--r-- | youtube_dl/__init__.py | 44 | ||||
| -rw-r--r-- | youtube_dl/version.py | 2 | 
6 files changed, 95 insertions, 37 deletions
| @@ -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 diff --git a/test/tests.json b/test/tests.json index 7808a07de..2b56738a0 100644 --- a/test/tests.json +++ b/test/tests.json @@ -337,6 +337,15 @@          "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..." +    }    }  ] diff --git a/youtube_dl/FileDownloader.py b/youtube_dl/FileDownloader.py index 19766153c..100779756 100644 --- a/youtube_dl/FileDownloader.py +++ b/youtube_dl/FileDownloader.py @@ -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: diff --git a/youtube_dl/InfoExtractors.py b/youtube_dl/InfoExtractors.py index 7c9f09f77..6a6545c9b 100755 --- a/youtube_dl/InfoExtractors.py +++ b/youtube_dl/InfoExtractors.py @@ -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()      ] diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index f46143e01..f60fb841e 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -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: diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 2fd5f40c8..ac8a05ab5 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.04.18' +__version__ = '2013.04.22' | 
