diff options
| -rw-r--r-- | devscripts/youtube_genalgo.py | 8 | ||||
| -rw-r--r-- | youtube_dl/FileDownloader.py | 46 | ||||
| -rw-r--r-- | youtube_dl/extractor/__init__.py | 2 | ||||
| -rw-r--r-- | youtube_dl/extractor/facebook.py | 4 | ||||
| -rw-r--r-- | youtube_dl/extractor/francetv.py | 50 | ||||
| -rw-r--r-- | youtube_dl/extractor/youku.py | 7 | ||||
| -rw-r--r-- | youtube_dl/extractor/youtube.py | 4 | ||||
| -rw-r--r-- | youtube_dl/version.py | 2 | 
8 files changed, 104 insertions, 19 deletions
| diff --git a/devscripts/youtube_genalgo.py b/devscripts/youtube_genalgo.py index f91e8855d..3b90a2fed 100644 --- a/devscripts/youtube_genalgo.py +++ b/devscripts/youtube_genalgo.py @@ -27,15 +27,15 @@ tests = [      # 87      ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<",       "uioplkjhgfdsazxcvbnm1t34567890QWE2TYUIOPLKJHGFDSAZXCVeNM!@#$^&*()_-+={[]}|:;?/>.<"), -    # 86 - vfluy6kdb 2013/09/06 +    # 86 - vflHql6Pr 2013/09/24      ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<", -     "yuioplkjhgfdsazxcvbnm12345678q0QWrRTYUIOELKJHGFD-AZXCVBNM!@#$%^&*()_<+={[|};?/>.S"), +     ";}|[{=+-d)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYT_EWQ0987654321mnbvcxzas/fghjklpoiuytrewq"),      # 85 - vflkuzxcs 2013/09/11      ('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[',       '3456789a0cdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS[UVWXYZ!"#$%&\'()*+,-./:;<=>?@'), -    # 84 - vflg0g8PQ 2013/08/29 (sporadic) +    # 84 - vflHql6Pr 2013/09/24 (sporadic)      ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?>.<", -     ">?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWq0987654321mnbvcxzasdfghjklpoiuytr"), +     "}[{=+-_)g*&^%$#@!MNBVCXZASDFGHJKLPOIUYTRE(Q0987654321mnbvcxzasdf?hjklpoiuytrewq"),      # 83      ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!#$%^&*()_+={[};?/>.<",       ".>/?;}[{=+_)(*&^%<#!MNBVCXZASPFGHJKLwOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytreq"), diff --git a/youtube_dl/FileDownloader.py b/youtube_dl/FileDownloader.py index 0b5a5d77d..d6673fd3a 100644 --- a/youtube_dl/FileDownloader.py +++ b/youtube_dl/FileDownloader.py @@ -77,26 +77,43 @@ class FileDownloader(object):      @staticmethod      def calc_percent(byte_counter, data_len):          if data_len is None: +            return None +        return float(byte_counter) / float(data_len) * 100.0 + +    @staticmethod +    def format_percent(percent): +        if percent is None:              return '---.-%' -        return '%6s' % ('%3.1f%%' % (float(byte_counter) / float(data_len) * 100.0)) +        return '%6s' % ('%3.1f%%' % percent)      @staticmethod      def calc_eta(start, now, total, current):          if total is None: -            return '--:--' +            return None          dif = now - start          if current == 0 or dif < 0.001: # One millisecond -            return '--:--' +            return None          rate = float(current) / dif -        eta = int((float(total) - float(current)) / rate) +        return int((float(total) - float(current)) / rate) + +    @staticmethod +    def format_eta(eta): +        if eta is None: +            return '--:--'          return FileDownloader.format_seconds(eta)      @staticmethod      def calc_speed(start, now, bytes):          dif = now - start          if bytes == 0 or dif < 0.001: # One millisecond +            return None +        return float(bytes) / dif + +    @staticmethod +    def format_speed(speed): +        if speed is None:              return '%10s' % '---b/s' -        return '%10s' % ('%s/s' % FileDownloader.format_bytes(float(bytes) / dif)) +        return '%10s' % ('%s/s' % FileDownloader.format_bytes(speed))      @staticmethod      def best_block_size(elapsed_time, bytes): @@ -205,11 +222,14 @@ class FileDownloader(object):          """Report destination filename."""          self.to_screen(u'[download] Destination: ' + filename) -    def report_progress(self, percent_str, data_len_str, speed_str, eta_str): +    def report_progress(self, percent, data_len_str, speed, eta):          """Report download progress."""          if self.params.get('noprogress', False):              return          clear_line = (u'\x1b[K' if sys.stderr.isatty() and os.name != 'nt' else u'') +        eta_str = self.format_eta(eta) +        percent_str = self.format_percent(percent) +        speed_str = self.format_speed(speed)          if self.params.get('progress_with_newline', False):              self.to_screen(u'[download] %s of %s at %s ETA %s' %                  (percent_str, data_len_str, speed_str, eta_str)) @@ -378,6 +398,7 @@ class FileDownloader(object):              self._hook_progress({                  'filename': filename,                  'status': 'finished', +                'total_bytes': os.path.getsize(encodeFilename(filename)),              })              return True @@ -524,13 +545,14 @@ class FileDownloader(object):                  block_size = self.best_block_size(after - before, len(data_block))              # Progress message -            speed_str = self.calc_speed(start, time.time(), byte_counter - resume_len) +            speed = self.calc_speed(start, time.time(), byte_counter - resume_len)              if data_len is None:                  self.report_progress('Unknown %', data_len_str, speed_str, 'Unknown ETA') +                eta = None              else: -                percent_str = self.calc_percent(byte_counter, data_len) -                eta_str = self.calc_eta(start, time.time(), data_len - resume_len, byte_counter - resume_len) -                self.report_progress(percent_str, data_len_str, speed_str, eta_str) +                percent = self.calc_percent(byte_counter, data_len) +                eta = self.calc_eta(start, time.time(), data_len - resume_len, byte_counter - resume_len) +                self.report_progress(percent, data_len_str, speed, eta)              self._hook_progress({                  'downloaded_bytes': byte_counter, @@ -538,6 +560,8 @@ class FileDownloader(object):                  'tmpfilename': tmpfilename,                  'filename': filename,                  'status': 'downloading', +                'eta': eta, +                'speed': speed,              })              # Apply rate limit @@ -580,6 +604,8 @@ class FileDownloader(object):          * downloaded_bytes: Bytes on disks          * total_bytes: Total bytes, None if unknown          * tmpfilename: The filename we're currently writing to +        * eta: The estimated time in seconds, None if unknown +        * speed: The download speed in bytes/second, None if unknown          Hooks are guaranteed to be called at least once (with status "finished")          if the download is successful. diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 949f59a44..d1b7e5f99 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -42,6 +42,8 @@ from .flickr import FlickrIE  from .francetv import (      PluzzIE,      FranceTvInfoIE, +    France2IE, +    GenerationQuoiIE  )  from .freesound import FreesoundIE  from .funnyordie import FunnyOrDieIE diff --git a/youtube_dl/extractor/facebook.py b/youtube_dl/extractor/facebook.py index beaa5b4bd..9d1bc0751 100644 --- a/youtube_dl/extractor/facebook.py +++ b/youtube_dl/extractor/facebook.py @@ -106,8 +106,8 @@ class FacebookIE(InfoExtractor):          video_duration = int(video_data['video_duration'])          thumbnail = video_data['thumbnail_src'] -        video_title = self._html_search_regex('<h2 class="uiHeaderTitle">([^<]+)</h2>', -            webpage, u'title') +        video_title = self._html_search_regex( +            r'<h2 class="uiHeaderTitle">([^<]*)</h2>', webpage, u'title')          info = {              'id': video_id, diff --git a/youtube_dl/extractor/francetv.py b/youtube_dl/extractor/francetv.py index b8fe82e47..b1530e549 100644 --- a/youtube_dl/extractor/francetv.py +++ b/youtube_dl/extractor/francetv.py @@ -1,6 +1,7 @@  # encoding: utf-8  import re  import xml.etree.ElementTree +import json  from .common import InfoExtractor  from ..utils import ( @@ -65,3 +66,52 @@ class FranceTvInfoIE(FranceTVBaseInfoExtractor):          webpage = self._download_webpage(url, page_title)          video_id = self._search_regex(r'id-video=(\d+?)"', webpage, u'video id')          return self._extract_video(video_id) + + +class France2IE(FranceTVBaseInfoExtractor): +    IE_NAME = u'france2.fr' +    _VALID_URL = r'https?://www\.france2\.fr/emissions/.*?/videos/(?P<id>\d+)' + +    _TEST = { +        u'url': u'http://www.france2.fr/emissions/13h15-le-samedi-le-dimanche/videos/75540104', +        u'file': u'75540104.mp4', +        u'info_dict': { +            u'title': u'13h15, le samedi...', +            u'description': u'md5:2e5b58ba7a2d3692b35c792be081a03d', +        }, +        u'params': { +            u'skip_download': True, +        }, +    } + +    def _real_extract(self, url): +        mobj = re.match(self._VALID_URL, url) +        video_id = mobj.group('id') +        return self._extract_video(video_id) + + +class GenerationQuoiIE(InfoExtractor): +    IE_NAME = u'http://generation-quoi.france2.fr' +    _VALID_URL = r'https?://generation-quoi\.france2\.fr/portrait/(?P<name>.*)(\?|$)' + +    _TEST = { +        u'url': u'http://generation-quoi.france2.fr/portrait/garde-a-vous', +        u'file': u'k7FJX8VBcvvLmX4wA5Q.mp4', +        u'info_dict': { +            u'title': u'Génération Quoi - Garde à Vous', +            u'uploader': u'Génération Quoi', +        }, +        u'params': { +            # It uses Dailymotion +            u'skip_download': True, +        }, +    } + +    def _real_extract(self, url): +        mobj = re.match(self._VALID_URL, url) +        name = mobj.group('name') +        info_url = compat_urlparse.urljoin(url, '/medias/video/%s.json' % name) +        info_json = self._download_webpage(info_url, name) +        info = json.loads(info_json) +        return self.url_result('http://www.dailymotion.com/video/%s' % info['id'], +            ie='Dailymotion') diff --git a/youtube_dl/extractor/youku.py b/youtube_dl/extractor/youku.py index 996d38478..00fa2ccb5 100644 --- a/youtube_dl/extractor/youku.py +++ b/youtube_dl/extractor/youku.py @@ -66,6 +66,12 @@ class YoukuIE(InfoExtractor):          self.report_extraction(video_id)          try:              config = json.loads(jsondata) +            error_code = config['data'][0].get('error_code') +            if error_code: +                # -8 means blocked outside China. +                error = config['data'][0].get('error')  # Chinese and English, separated by newline. +                raise ExtractorError(error or u'Server reported error %i' % error_code, +                    expected=True)              video_title =  config['data'][0]['title']              seed = config['data'][0]['seed'] @@ -89,6 +95,7 @@ class YoukuIE(InfoExtractor):              fileid = config['data'][0]['streamfileids'][format]              keys = [s['k'] for s in config['data'][0]['segs'][format]] +            # segs is usually a dictionary, but an empty *list* if an error occured.          except (UnicodeDecodeError, ValueError, KeyError):              raise ExtractorError(u'Unable to extract info section') diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index e883a2c54..6beda8f3b 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -361,7 +361,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor):              u"info_dict": {                  u"upload_date": u"20120506",                  u"title": u"Icona Pop - I Love It (feat. Charli XCX) [OFFICIAL VIDEO]", -                u"description": u"md5:3e2666e0a55044490499ea45fe9037b7", +                u"description": u"md5:bdac09887d209a4ed54b8f76b2bdaa8b",                  u"uploader": u"Icona Pop",                  u"uploader_id": u"IconaPop"              } @@ -1096,7 +1096,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor, SubtitlesInfoExtractor):          elif len(s) == 85:              return s[3:11] + s[0] + s[12:55] + s[84] + s[56:84]          elif len(s) == 84: -            return s[81:36:-1] + s[0] + s[35:2:-1] +            return s[78:70:-1] + s[14] + s[69:37:-1] + s[70] + s[36:14:-1] + s[80] + s[:14][::-1]          elif len(s) == 83:              return s[81:64:-1] + s[82] + s[63:52:-1] + s[45] + s[51:45:-1] + s[1] + s[44:1:-1] + s[0]          elif len(s) == 82: diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 88d70b47a..e33421216 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.09.20.1' +__version__ = '2013.09.24' | 
