From 56c7366547462ecec0536df58971249a8a870ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Mon, 8 Jul 2013 15:14:27 +0200 Subject: [PATCH 001/113] YoutubeIE: reuse instances of InfoExtractors (closes #998) When a IE is added to the list, it's also added to a dictionary. When a IE is requested it first looks in the dictionary and if there's no instance it will create a new one. That way _real_initialize is only called once for each IE, saving time if it needs to login for example. --- youtube_dl/YoutubeDL.py | 18 +++++++++++++++--- youtube_dl/extractor/common.py | 5 +++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index d3281fed2..cd3d6ea7b 100644 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -97,6 +97,7 @@ class YoutubeDL(object): def __init__(self, params): """Create a FileDownloader object with the given options.""" self._ies = [] + self._ies_instances = {} self._pps = [] self._progress_hooks = [] self._download_retcode = 0 @@ -111,8 +112,21 @@ def __init__(self, params): def add_info_extractor(self, ie): """Add an InfoExtractor object to the end of the list.""" self._ies.append(ie) + self._ies_instances[ie.ie_key()] = ie ie.set_downloader(self) + def get_info_extractor(self, ie_key): + """ + Get an instance of an IE with name ie_key, it will try to get one from + the _ies list, if there's no instance it will create a new one and add + it to the extractor list. + """ + ie = self._ies_instances.get(ie_key) + if ie is None: + ie = get_info_extractor(ie_key)() + self.add_info_extractor(ie) + return ie + def add_default_info_extractors(self): """ Add the InfoExtractors returned by gen_extractors to the end of the list @@ -294,9 +308,7 @@ def extract_info(self, url, download=True, ie_key=None, extra_info={}): ''' if ie_key: - ie = get_info_extractor(ie_key)() - ie.set_downloader(self) - ies = [ie] + ies = [self.get_info_extractor(ie_key)] else: ies = self._ies diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index 1d98222ce..236c7b12c 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -106,6 +106,11 @@ def _real_extract(self, url): """Real extraction process. Redefine in subclasses.""" pass + @classmethod + def ie_key(cls): + """A string for getting the InfoExtractor with get_info_extractor""" + return cls.__name__[:-2] + @property def IE_NAME(self): return type(self).__name__[:-2] From 6d3a7d03e14fcbc704bf30d305fb95c5829e55a6 Mon Sep 17 00:00:00 2001 From: huohuarong Date: Fri, 2 Aug 2013 15:26:11 +0800 Subject: [PATCH 002/113] fix bug: kankan extractor not support http://vod.kankan.com/v/70/70309.shtml --- youtube_dl/extractor/kankan.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/kankan.py b/youtube_dl/extractor/kankan.py index 8537ba584..445d46501 100644 --- a/youtube_dl/extractor/kankan.py +++ b/youtube_dl/extractor/kankan.py @@ -21,8 +21,10 @@ def _real_extract(self, url): video_id = mobj.group('id') webpage = self._download_webpage(url, video_id) - title = self._search_regex(r'G_TITLE=[\'"](.+?)[\'"]', webpage, u'video title') - gcid = self._search_regex(r'lurl:[\'"]http://.+?/.+?/(.+?)/', webpage, u'gcid') + title = self._search_regex(r'(?:G_TITLE=|G_MOVIE_TITLE = )[\'"](.+?)[\'"]', webpage, u'video title') + surls = re.search(r'surls:\[\'.+?\'\]|lurl:\'.+?\.flv\'', webpage).group(0) + gcids = re.findall(r"http://.+?/.+?/(.+?)/", surls) + gcid = gcids[-1] video_info_page = self._download_webpage('http://p2s.cl.kankan.com/getCdnresource_flv?gcid=%s' % gcid, video_id, u'Downloading video url info') From 6624a2b07dafad4de895b4e84f4595214817518d Mon Sep 17 00:00:00 2001 From: huohuarong Date: Fri, 2 Aug 2013 17:58:46 +0800 Subject: [PATCH 003/113] add an extractor for tv.sohu.com --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/sohu.py | 97 ++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 youtube_dl/extractor/sohu.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index c20172a53..3a08d676f 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -55,6 +55,7 @@ from .ringtv import RingTVIE from .roxwel import RoxwelIE from .sina import SinaIE +from .sohu import SohuIE from .soundcloud import SoundcloudIE, SoundcloudSetIE from .spiegel import SpiegelIE from .stanfordoc import StanfordOpenClassroomIE diff --git a/youtube_dl/extractor/sohu.py b/youtube_dl/extractor/sohu.py new file mode 100644 index 000000000..830814221 --- /dev/null +++ b/youtube_dl/extractor/sohu.py @@ -0,0 +1,97 @@ +# encoding: utf-8 + +import re +import json +import time +import logging +import urllib2 + +from .common import InfoExtractor +from ..utils import compat_urllib_request + + +class SohuIE(InfoExtractor): + _VALID_URL = r'https?://tv\.sohu\.com/\d+?/n(?P\d+)\.shtml.*?' + + _TEST = { + u'url': u'http://tv.sohu.com/20130724/n382479172.shtml#super', + u'file': u'382479172.flv', + u'md5': u'cc84eed6b6fbf0f2f9a8d3cb9da1939b', + u'info_dict': { + u'title': u'The Illest - Far East Movement Riff Raff', + }, + } + + def _clearn_html(self, string): + tags = re.findall(r'<.+?>', string) + for t in tags: + string = string.replace(t, ' ') + for i in range(2): + spaces = re.findall(r'\s+', string) + for s in spaces: + string = string.replace(s, ' ') + string = string.strip() + return string + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + webpage = self._download_webpage(url, video_id) + pattern = r'

\n*?(.+?)\n*?

' + compiled = re.compile(pattern, re.DOTALL) + title = self._search_regex(compiled, webpage, u'video title').strip('\t\n') + title = self._clearn_html(title) + pattern = re.compile(r'var vid="(\d+)"') + result = re.search(pattern, webpage) + if not result: + logging.info('[Sohu] could not get vid') + return None + vid = result.group(1) + logging.info('vid: %s' % vid) + base_url_1 = 'http://hot.vrs.sohu.com/vrs_flash.action?vid=' + url_1 = base_url_1 + vid + logging.info('json url: %s' % url_1) + json_1 = json.loads(urllib2.urlopen(url_1).read()) + # get the highest definition video vid and json infomation. + vids = [] + qualities = ('oriVid', 'superVid', 'highVid', 'norVid') + for vid_name in qualities: + vids.append(json_1['data'][vid_name]) + clearest_vid = 0 + for i, v in enumerate(vids): + if v != 0: + clearest_vid = v + logging.info('quality definition: %s' % qualities[i][:-3]) + break + if not clearest_vid: + logging.warning('could not find valid clearest_vid') + return None + if vid != clearest_vid: + url_1 = '%s%d' % (base_url_1, clearest_vid) + logging.info('highest definition json url: %s' % url_1) + json_1 = json.loads(urllib2.urlopen(url_1).read()) + allot = json_1['allot'] + prot = json_1['prot'] + clipsURL = json_1['data']['clipsURL'] + su = json_1['data']['su'] + num_of_parts = json_1['data']['totalBlocks'] + logging.info('Total parts: %d' % num_of_parts) + base_url_3 = 'http://allot/?prot=prot&file=clipsURL[i]&new=su[i]' + files_info = [] + for i in range(num_of_parts): + middle_url = 'http://%s/?prot=%s&file=%s&new=%s' % (allot, prot, clipsURL[i], su[i]) + logging.info('middle url part %d: %s' % (i, middle_url)) + middle_info = urllib2.urlopen(middle_url).read().split('|') + middle_part_1 = middle_info[0] + download_url = '%s%s?key=%s' % (middle_info[0], su[i], middle_info[3]) + + info = { + 'id': '%s_part%02d' % (video_id, i + 1), + 'title': title, + 'url': download_url, + 'ext': 'mp4', + } + files_info.append(info) + time.sleep(1) + + return files_info From 4ec929dc9b55a2588b4a27e64871c5bfa900bf37 Mon Sep 17 00:00:00 2001 From: huohuarong Date: Sat, 3 Aug 2013 10:29:58 +0800 Subject: [PATCH 004/113] use ..utils/clean_html() --- youtube_dl/extractor/sohu.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/youtube_dl/extractor/sohu.py b/youtube_dl/extractor/sohu.py index 830814221..cf0ab5478 100644 --- a/youtube_dl/extractor/sohu.py +++ b/youtube_dl/extractor/sohu.py @@ -7,7 +7,7 @@ import urllib2 from .common import InfoExtractor -from ..utils import compat_urllib_request +from ..utils import compat_urllib_request, clean_html class SohuIE(InfoExtractor): @@ -22,16 +22,6 @@ class SohuIE(InfoExtractor): }, } - def _clearn_html(self, string): - tags = re.findall(r'<.+?>', string) - for t in tags: - string = string.replace(t, ' ') - for i in range(2): - spaces = re.findall(r'\s+', string) - for s in spaces: - string = string.replace(s, ' ') - string = string.strip() - return string def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) @@ -40,7 +30,7 @@ def _real_extract(self, url): pattern = r'

\n*?(.+?)\n*?

' compiled = re.compile(pattern, re.DOTALL) title = self._search_regex(compiled, webpage, u'video title').strip('\t\n') - title = self._clearn_html(title) + title = clean_html(title) pattern = re.compile(r'var vid="(\d+)"') result = re.search(pattern, webpage) if not result: @@ -93,5 +83,8 @@ def _real_extract(self, url): } files_info.append(info) time.sleep(1) - + if num_of_parts == 1: + info = files_info[0] + info['id'] = video_id + return info return files_info From 968b5e0112a83f2a4637226d4d743b394ebed038 Mon Sep 17 00:00:00 2001 From: Dan Church Date: Sun, 4 Aug 2013 12:45:24 -0500 Subject: [PATCH 005/113] Add some verbosity when reporting finished downloads For example: [download] Resuming download at byte 1868140 [download] Destination: Entry #1-Bn59FJ4HrmU.flv [download] 100% of 3.27MiB in 4s This format is meant to somewhat mirror the behavior of wget(1) when reporting finished downloads: 100%[==================>] 54,836,682 788KB/s in 74s 2013-08-04 12:32:05 (728 KB/s) - 'google-chrome-stable_current_x86_64.rpm' saved [54836682/54836682] --- youtube_dl/FileDownloader.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/youtube_dl/FileDownloader.py b/youtube_dl/FileDownloader.py index ea6b9d626..ab06533c0 100644 --- a/youtube_dl/FileDownloader.py +++ b/youtube_dl/FileDownloader.py @@ -230,12 +230,14 @@ def report_unable_to_resume(self): """Report it was impossible to resume download.""" self.to_screen(u'[download] Unable to resume') - def report_finish(self): + def report_finish(self, data_len_str, tot_time): """Report download finished.""" if self.params.get('noprogress', False): self.to_screen(u'[download] Download completed') else: - self.to_screen(u'') + clear_line = (u'\x1b[K' if sys.stderr.isatty() and os.name != 'nt' else u'') + self.to_screen(u'\r%s[download] 100%% of %s in %ss' % + (clear_line, data_len_str, int(tot_time))) def _download_with_rtmpdump(self, filename, url, player_url, page_url, play_path, tc_url): self.report_destination(filename) @@ -538,7 +540,7 @@ def _do_download(self, filename, info_dict): self.report_error(u'Did not get any data blocks') return False stream.close() - self.report_finish() + self.report_finish(data_len_str, (time.time() - start)) if data_len is not None and byte_counter != data_len: raise ContentTooShortError(byte_counter, int(data_len)) self.try_rename(tmpfilename, filename) From b5a6d408181c118bf51382f486a2492643ed74ec Mon Sep 17 00:00:00 2001 From: huohuarong Date: Mon, 5 Aug 2013 22:51:54 +0800 Subject: [PATCH 006/113] fix parse title bug --- youtube_dl/extractor/sohu.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/youtube_dl/extractor/sohu.py b/youtube_dl/extractor/sohu.py index cf0ab5478..cd049b6f0 100644 --- a/youtube_dl/extractor/sohu.py +++ b/youtube_dl/extractor/sohu.py @@ -27,10 +27,10 @@ def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) video_id = mobj.group('id') webpage = self._download_webpage(url, video_id) - pattern = r'

\n*?(.+?)\n*?

' + pattern = r'(.+?)' compiled = re.compile(pattern, re.DOTALL) - title = self._search_regex(compiled, webpage, u'video title').strip('\t\n') - title = clean_html(title) + title = self._search_regex(compiled, webpage, u'video title') + title = clean_html(title).split('-')[0].strip() pattern = re.compile(r'var vid="(\d+)"') result = re.search(pattern, webpage) if not result: @@ -41,7 +41,8 @@ def _real_extract(self, url): base_url_1 = 'http://hot.vrs.sohu.com/vrs_flash.action?vid=' url_1 = base_url_1 + vid logging.info('json url: %s' % url_1) - json_1 = json.loads(urllib2.urlopen(url_1).read()) + webpage = self._download_webpage(url_1, vid) + json_1 = json.loads(webpage) # get the highest definition video vid and json infomation. vids = [] qualities = ('oriVid', 'superVid', 'highVid', 'norVid') From 461cead4f788f6a69902f350b9143a5e1588b57d Mon Sep 17 00:00:00 2001 From: tsantala Date: Tue, 6 Aug 2013 04:34:24 +0300 Subject: [PATCH 007/113] changes --- youtube_dl/extractor/AddAnime.py | 54 ++++++++++++++++++++++++++++++++ youtube_dl/extractor/__init__.py | 2 ++ 2 files changed, 56 insertions(+) create mode 100644 youtube_dl/extractor/AddAnime.py diff --git a/youtube_dl/extractor/AddAnime.py b/youtube_dl/extractor/AddAnime.py new file mode 100644 index 000000000..43b0b24fe --- /dev/null +++ b/youtube_dl/extractor/AddAnime.py @@ -0,0 +1,54 @@ +import re + +from .common import InfoExtractor +from ..utils import ( + ExtractorError, +) +from bs4 import BeautifulSoup + + +class AddAnimeIE(InfoExtractor): + + _VALID_URL = r'^(?:http?://)?(?:\w+\.)?add-anime\.net/watch_video.php\?(?:.*?)v=(?P[\w_]+)(?:.*)' + IE_NAME = u'AddAnime' + _TEST = { + u'url': u'http://www.add-anime.net/watch_video.php?v=24MR3YO5SAS9', + u'file': u'137499050692ced.flv', + u'md5': u'0813c2430bea7a46bf13acf3406992f4', + u'info_dict': { + u"description": u"One Piece 606", + u"uploader": u"mugiwaraQ8", + u"title": u"One Piece 606" + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + if mobj is None: + raise ExtractorError(u'Invalid URL: %s' % url) + + video_id = mobj.group('video_id') + + webpage = self._download_webpage(url, video_id) + + video_url = self._search_regex(r'var normal_video_file = "(.*?)",', + webpage, u'video URL') + + video_title = self._og_search_title(webpage) + + video_description = self._og_search_description(webpage) + + soup = BeautifulSoup(webpage) + + video_uploader= soup.find("meta", {"author":""})['content'] + + info = { + 'id': video_id, + 'url': video_url, + 'ext': 'flv', + 'title': video_title, + 'description': video_description, + 'uploader': video_uploader + } + + return [info] diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 84c02c2ed..28dcb2cc4 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -1,3 +1,5 @@ + +from .AddAnime import AddAnimeIE from .archiveorg import ArchiveOrgIE from .ard import ARDIE from .arte import ArteTvIE From d5b00ee6e0ba70fd5d87752e8772fc1c39e4bd59 Mon Sep 17 00:00:00 2001 From: huohuarong Date: Tue, 6 Aug 2013 10:26:57 +0800 Subject: [PATCH 008/113] improve sohu extractor --- youtube_dl/extractor/sohu.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/youtube_dl/extractor/sohu.py b/youtube_dl/extractor/sohu.py index cd049b6f0..24fc3a5d7 100644 --- a/youtube_dl/extractor/sohu.py +++ b/youtube_dl/extractor/sohu.py @@ -31,6 +31,7 @@ def _real_extract(self, url): compiled = re.compile(pattern, re.DOTALL) title = self._search_regex(compiled, webpage, u'video title') title = clean_html(title).split('-')[0].strip() + self.to_screen('Title: %s' % title) pattern = re.compile(r'var vid="(\d+)"') result = re.search(pattern, webpage) if not result: @@ -70,6 +71,7 @@ def _real_extract(self, url): base_url_3 = 'http://allot/?prot=prot&file=clipsURL[i]&new=su[i]' files_info = [] for i in range(num_of_parts): + self.to_screen('Geting json infomation of part %s/%s' % (i + 1, num_of_parts)) middle_url = 'http://%s/?prot=%s&file=%s&new=%s' % (allot, prot, clipsURL[i], su[i]) logging.info('middle url part %d: %s' % (i, middle_url)) middle_info = urllib2.urlopen(middle_url).read().split('|') From f3bcebb1d2ebf6a69f06b72e1e365bc76970e1e2 Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Fri, 9 Aug 2013 18:36:01 +0200 Subject: [PATCH 009/113] add an aes implementation --- youtube_dl/aes.py | 200 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 youtube_dl/aes.py diff --git a/youtube_dl/aes.py b/youtube_dl/aes.py new file mode 100644 index 000000000..2fa9238e3 --- /dev/null +++ b/youtube_dl/aes.py @@ -0,0 +1,200 @@ +__all__ = ['aes_encrypt', 'key_expansion', 'aes_ctr_decrypt', 'aes_decrypt_text'] + +import base64 +from math import ceil + +BLOCK_SIZE_BYTES = 16 + +def aes_ctr_decrypt(data, key, counter): + """ + Decrypt with aes in counter mode + + @param {int[]} data cipher + @param {int[]} key 16/24/32-Byte cipher key + @param {instance} counter Instance whose next_value function (@returns {int[]} 16-Byte block) + returns the next counter block + @returns {int[]} decrypted data + """ + expanded_key = key_expansion(key) + block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES)) + + decrypted_data=[] + for i in range(block_count): + counter_block = counter.next_value() + block = data[i*BLOCK_SIZE_BYTES : (i+1)*BLOCK_SIZE_BYTES] + block += [0]*(BLOCK_SIZE_BYTES - len(block)) + + cipher_counter_block = aes_encrypt(counter_block, expanded_key) + decrypted_data += xor(block, cipher_counter_block) + decrypted_data = decrypted_data[:len(data)] + + return decrypted_data + +def key_expansion(data): + """ + Generate key schedule + + @param {int[]} data 16/24/32-Byte cipher key + @returns {int[]} 176/208/240-Byte expanded key + """ + data = data[:] # copy + rcon_iteration = 1 + key_size_bytes = len(data) + expanded_key_size_bytes = (key_size_bytes/4 + 7) * BLOCK_SIZE_BYTES + + while len(data) < expanded_key_size_bytes: + temp = data[-4:] + temp = key_schedule_core(temp, rcon_iteration) + rcon_iteration += 1 + data += xor(temp, data[-key_size_bytes : 4-key_size_bytes]) + + for _ in range(3): + temp = data[-4:] + data += xor(temp, data[-key_size_bytes : 4-key_size_bytes]) + + if key_size_bytes == 32: + temp = data[-4:] + temp = sub_bytes(temp) + data += xor(temp, data[-key_size_bytes : 4-key_size_bytes]) + + for _ in range(3 if key_size_bytes == 32 else 2 if key_size_bytes == 24 else 0): + temp = data[-4:] + data += xor(temp, data[-key_size_bytes : 4-key_size_bytes]) + data = data[:expanded_key_size_bytes] + + return data + +def aes_encrypt(data, expanded_key): + """ + Encrypt one block with aes + + @param {int[]} data 16-Byte state + @param {int[]} expanded_key 176/208/240-Byte expanded key + @returns {int[]} 16-Byte cipher + """ + rounds = len(expanded_key) / BLOCK_SIZE_BYTES - 1 + + data = xor(data, expanded_key[:BLOCK_SIZE_BYTES]) + for i in range(1, rounds+1): + data = sub_bytes(data) + data = shift_rows(data) + if i != rounds: + data = mix_columns(data) + data = xor(data, expanded_key[i*BLOCK_SIZE_BYTES : (i+1)*BLOCK_SIZE_BYTES]) + + return data + +def aes_decrypt_text(data, password, key_size_bytes): + """ + Decrypt text + - The first 8 Bytes of decoded 'data' are the 8 high Bytes of the counter + - The cipher key is retrieved by encrypting the first 16 Byte of 'password' + with the first 'key_size_bytes' Bytes from 'password' (if necessary filled with 0's) + - Mode of operation is 'counter' + + @param {str} data Base64 encoded string + @param {str,unicode} password Password (will be encoded with utf-8) + @param {int} key_size_bytes Possible values: 16 for 128-Bit, 24 for 192-Bit or 32 for 256-Bit + @returns {str} Decrypted data + """ + NONCE_LENGTH_BYTES = 8 + + data = map(lambda c: ord(c), base64.b64decode(data)) + password = map(lambda c: ord(c), password.encode('utf-8')) + + key = password[:key_size_bytes] + [0]*(key_size_bytes - len(password)) + key = aes_encrypt(key[:BLOCK_SIZE_BYTES], key_expansion(key)) * (key_size_bytes / BLOCK_SIZE_BYTES) + + nonce = data[:NONCE_LENGTH_BYTES] + cipher = data[NONCE_LENGTH_BYTES:] + + class Counter: + __value = nonce + [0]*(BLOCK_SIZE_BYTES - NONCE_LENGTH_BYTES) + def next_value(self): + temp = self.__value + self.__value = inc(self.__value) + return temp + + decrypted_data = aes_ctr_decrypt(cipher, key, Counter()) + plaintext = ''.join(map(lambda x: chr(x), decrypted_data)) + + return plaintext + +RCON = (0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36) +SBOX = (0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16) +MIX_COLUMN_MATRIX = ((2,3,1,1), + (1,2,3,1), + (1,1,2,3), + (3,1,1,2)) + +def sub_bytes(data): + return map(lambda x: SBOX[x], data) + +def rotate(data): + return data[1:] + [data[0]] + +def key_schedule_core(data, rcon_iteration): + data = rotate(data) + data = sub_bytes(data) + data[0] = data[0] ^ RCON[rcon_iteration] + + return data + +def xor(data1, data2): + return map(lambda (x,y): x^y, zip(data1, data2)) + +def mix_column(data): + data_mixed = [] + for row in range(4): + mixed = 0 + for column in range(4): + addend = data[column] + if MIX_COLUMN_MATRIX[row][column] in (2,3): + addend <<= 1 + if addend > 0xff: + addend &= 0xff + addend ^= 0x1b + if MIX_COLUMN_MATRIX[row][column] == 3: + addend ^= data[column] + mixed ^= addend & 0xff + data_mixed.append(mixed) + return data_mixed + +def mix_columns(data): + data_mixed = [] + for i in range(4): + column = data[i*4 : (i+1)*4] + data_mixed += mix_column(column) + return data_mixed + +def shift_rows(data): + data_shifted = [] + for column in range(4): + for row in range(4): + data_shifted.append( data[((column + row) & 0b11) * 4 + row] ) + return data_shifted + +def inc(data): + data = data[:] # copy + for i in range(len(data)-1,-1,-1): + if data[i] == 255: + data[i] = 0 + else: + data[i] = data[i] + 1 + break + return data From 97b3656c2e37e45d556816b8f1f15c20d14f1acd Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Fri, 9 Aug 2013 18:37:33 +0200 Subject: [PATCH 010/113] YoupornIE: Add support for hd videos and update Test --- youtube_dl/extractor/youporn.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/youporn.py b/youtube_dl/extractor/youporn.py index d1156bf42..cc9c37027 100644 --- a/youtube_dl/extractor/youporn.py +++ b/youtube_dl/extractor/youporn.py @@ -12,14 +12,16 @@ unescapeHTML, unified_strdate, ) - +from ..aes import ( + aes_decrypt_text +) class YouPornIE(InfoExtractor): _VALID_URL = r'^(?:https?://)?(?:\w+\.)?youporn\.com/watch/(?P[0-9]+)/(?P[^/]+)' _TEST = { u'url': u'http://www.youporn.com/watch/505835/sex-ed-is-it-safe-to-masturbate-daily/', u'file': u'505835.mp4', - u'md5': u'c37ddbaaa39058c76a7e86c6813423c1', + u'md5': u'71ec5fcfddacf80f495efa8b6a8d9a89', u'info_dict': { u"upload_date": u"20101221", u"description": u"Love & Sex Answers: http://bit.ly/DanAndJenn -- Is It Unhealthy To Masturbate Daily?", @@ -75,6 +77,14 @@ def _real_extract(self, url): # Get all of the links from the page LINK_RE = r'(?s)<a href="(?P<url>[^"]+)">' links = re.findall(LINK_RE, download_list_html) + + # Get link of hd video + encrypted_video_url = self._html_search_regex(r'var encryptedURL = \'(?P<encrypted_video_url>[a-zA-Z0-9+/]+={0,2})\';', + webpage, u'encrypted_video_url') + video_url = unicode( aes_decrypt_text(encrypted_video_url, video_title, 32), 'utf-8') + if video_url.split('/')[6].split('_')[0] == u'720p': # only add if 720p to avoid duplicates + links = [video_url] + links + if(len(links) == 0): raise ExtractorError(u'ERROR: no known formats available for video') From e3a88568b0457f18a03a2a894287a03f7cc2dbbe Mon Sep 17 00:00:00 2001 From: Yasoob <yasoob@yasoob.(none)> Date: Sun, 11 Aug 2013 22:23:05 +0500 Subject: [PATCH 011/113] Added an IE for hark.com --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/hark.py | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 youtube_dl/extractor/hark.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 84c02c2ed..ca5664577 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -29,6 +29,7 @@ from .generic import GenericIE from .googleplus import GooglePlusIE from .googlesearch import GoogleSearchIE +from .hark import HarkIE from .hotnewhiphop import HotNewHipHopIE from .howcast import HowcastIE from .hypem import HypemIE diff --git a/youtube_dl/extractor/hark.py b/youtube_dl/extractor/hark.py new file mode 100644 index 000000000..ab0a69697 --- /dev/null +++ b/youtube_dl/extractor/hark.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- + +import re + +from .common import InfoExtractor +from ..utils import determine_ext + +class HarkIE(InfoExtractor): + _VALID_URL = r'https?://www\.hark\.com/clips/(.+?)-.+' + _TEST = { + u'url': u'http://www.hark.com/clips/mmbzyhkgny-obama-beyond-the-afghan-theater-we-only-target-al-qaeda-on-may-23-2013', + u'file': u'mmbzyhkgny.mp3', + u'md5': u'6783a58491b47b92c7c1af5a77d4cbee', + u'info_dict': { + u"title": u"Obama: 'Beyond The Afghan Theater, We Only Target Al Qaeda' On May 23, 2013 ", + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group(1) + embed_url = "http://www.hark.com/clips/%s/homepage_embed" %(video_id) + webpage = self._download_webpage(embed_url, video_id) + + final_url = self._search_regex(r'src="(.+?).mp3"', + webpage, 'video url')+'.mp3' + title = self._html_search_regex(r'<title>(.+?)', + webpage, 'video title').replace(' Sound Clip and Quote - Hark','').replace( + 'Sound Clip , Quote, MP3, and Ringtone - Hark','') + + return {'id': video_id, + 'url' : final_url, + 'title': title, + 'ext': determine_ext(final_url), + } From 5a27ecdd2ec83ba6e1069428c4c0fb3bd61f638c Mon Sep 17 00:00:00 2001 From: kkalpakloglou Date: Fri, 16 Aug 2013 23:54:09 +0300 Subject: [PATCH 012/113] Update AddAnime.py --- youtube_dl/extractor/AddAnime.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/youtube_dl/extractor/AddAnime.py b/youtube_dl/extractor/AddAnime.py index 43b0b24fe..a312fa97e 100644 --- a/youtube_dl/extractor/AddAnime.py +++ b/youtube_dl/extractor/AddAnime.py @@ -1,11 +1,6 @@ import re from .common import InfoExtractor -from ..utils import ( - ExtractorError, -) -from bs4 import BeautifulSoup - class AddAnimeIE(InfoExtractor): @@ -17,7 +12,6 @@ class AddAnimeIE(InfoExtractor): u'md5': u'0813c2430bea7a46bf13acf3406992f4', u'info_dict': { u"description": u"One Piece 606", - u"uploader": u"mugiwaraQ8", u"title": u"One Piece 606" } } @@ -31,24 +25,27 @@ def _real_extract(self, url): webpage = self._download_webpage(url, video_id) - video_url = self._search_regex(r'var normal_video_file = "(.*?)",', - webpage, u'video URL') + + def find_between( webpage, first, last ): + try: + start = webpage.index( first ) + len( first ) + end = webpage.index( last, start ) + return webpage[start:end] + except ValueError: + return "" + + video_url = find_between( webpage, "var normal_video_file = '", "';" ) video_title = self._og_search_title(webpage) video_description = self._og_search_description(webpage) - - soup = BeautifulSoup(webpage) - - video_uploader= soup.find("meta", {"author":""})['content'] info = { 'id': video_id, 'url': video_url, 'ext': 'flv', 'title': video_title, - 'description': video_description, - 'uploader': video_uploader + 'description': video_description } return [info] From 943f7f7a399c6fb3006eb2bd68070f28a272171f Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Sun, 18 Aug 2013 16:11:47 +0200 Subject: [PATCH 013/113] Download videos from jeuxvideo.com --- youtube-dl | Bin 3445 -> 173825 bytes youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/jeuxvideo.py | 33 ++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 youtube_dl/extractor/jeuxvideo.py diff --git a/youtube-dl b/youtube-dl index e3eb8774caa258ddbaa51323938fbd36c4fc170d..ae8cc98e33b73af6d7cb35fef44dc9e7f5a3ebbd 100755 GIT binary patch literal 173825 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%0D42;5lvZJw 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

)&tdVq)c(n#}UD)NxZ+>3Q6cNmrg0rW=`%BA-$ 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 XF9Gom4b2Yt703g;^A`ZbC$#?q&q@*K literal 3445 zcmbVOdvDuD692pU6yp>ajEG1SN zkH;R0Oy=l16*r||&a|cDTB99iwEE17*->GCgxOYmD>K`V*^ zST}-V06PD+fz(%_S{QUDJB<+3-D9Nhj&Mk#;$Fmu*c-lt#jy-h0{zGSu z;=5IPFsO;|?o|KCe6(Yv^-9rt>(9U@$bI(9vy+s8fs35- zu!DnaOq1e^yaIukYcLX;I_CzVG#aY{q(In8g<#4pdiR1}=QmWo-;^45WmOS$iW46_-EykA5swW1*s#@yONOd4* zTRS?~|G_?>Qq&FQWB~NHe2b6aJe>S6P)!Pg9YHjN1U6<|tv_2xntXWo>gD^Z)rXtk z>E_wyI~I5OIDaA$ikw?mOKga5E)C7m}P;#SS}-;_#s0Uu{?>xY`F{; z82a;Q5vN(=$IF0z&|l7zWn5$hV`&^0AqGqI=NR$@!zE`diW2(g8FH4)eU4eUD6)_^ z(l{jxvxIS$&Dng8ewgMg^BK!A4lpdp_(d89i`-A3is7kv8X^t$yu(aWzzQ*O^9N zn!%Zji+jg_ObsWz9#{#x3+chT3c0p#_W*ot@2QQW^2mffdd>)Rj)nVyz4h}cjrKVX zgl)8d0LFF>D~mvl03##lXljGG2QO0^-b%5yN=IcB!a+i->h8pj2b!a*|8?D)ellsb zvCErn{U~S@eo-V!@tIfUBhM$j zyI(s##KC#E8VdE9b`cAw%%y`?k%Dcm>jKG*$J0S z=?7h}Z?i{&skg!X&}`d^9X;rHsW(6Jl|4MN?Tf4pW>JyaSKewSTd6kdE~P1nLPDLo==9nF(C+$%f8xu~nEwBuO7gYCt*lYXrtu`K-)Q`= XXg)ZDx7{cKgcG0|aWYnP6T^Q26dqrA diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 84c02c2ed..b9bd3a429 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -36,6 +36,7 @@ from .ina import InaIE from .infoq import InfoQIE from .instagram import InstagramIE +from .jeuxvideo import JeuxVideoIE from .jukebox import JukeboxIE from .justintv import JustinTVIE from .kankan import KankanIE diff --git a/youtube_dl/extractor/jeuxvideo.py b/youtube_dl/extractor/jeuxvideo.py new file mode 100644 index 000000000..d74a1c9b4 --- /dev/null +++ b/youtube_dl/extractor/jeuxvideo.py @@ -0,0 +1,33 @@ +import json +import re + +from .common import InfoExtractor + +class JeuxVideoIE(InfoExtractor): + _VALID_URL = r'http://.*?\.jeuxvideo\.com/.*/(.*?)-\d+\.htm' + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + title = re.match(self._VALID_URL, url).group(1) + webpage = self._download_webpage(url, title) + m_download = re.search(r'', webpage) + + xml_link = m_download.group(1) + + id = re.search(r'http://www.jeuxvideo.com/config/\w+/0011/(.*?)/\d+_player\.xml', xml_link).group(1) + + xml_config = self._download_webpage(xml_link, title, + 'Downloading XML config') + info = re.search(r'(.*?)', + xml_config, re.MULTILINE|re.DOTALL).group(1) + info = json.loads(info)['versions'][0] + + video_url = 'http://video720.jeuxvideo.com/' + info['file'] + + track_info = {'id':id, + 'title' : title, + 'ext' : 'mp4', + 'url' : video_url + } + + return [track_info] From 7070b83687ed134af6d9a71bbf2ec759a56965d5 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Thu, 22 Aug 2013 12:54:17 +0200 Subject: [PATCH 014/113] Merge remote-tracking branch 'upstream/master' --- youtube_dl/extractor/jeuxvideo.py | 1 - 1 file changed, 1 deletion(-) diff --git a/youtube_dl/extractor/jeuxvideo.py b/youtube_dl/extractor/jeuxvideo.py index c8a8ae1b3..4327bc13d 100644 --- a/youtube_dl/extractor/jeuxvideo.py +++ b/youtube_dl/extractor/jeuxvideo.py @@ -31,7 +31,6 @@ def _real_extract(self, url): xml_config = self._download_webpage(xml_link, title, 'Downloading XML config') - config = xml.etree.ElementTree.fromstring(xml_config.encode('utf-8')) info = re.search(r'(.*?)', xml_config, re.MULTILINE|re.DOTALL).group(1) From 05a2926c5c7737e6f17ccf96a35a01ec05fe092b Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Thu, 22 Aug 2013 12:55:58 +0200 Subject: [PATCH 015/113] Merge remote-tracking branch 'upstream/master' --- youtube-dl | Bin 173825 -> 3445 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/youtube-dl b/youtube-dl index ae8cc98e33b73af6d7cb35fef44dc9e7f5a3ebbd..e3eb8774caa258ddbaa51323938fbd36c4fc170d 100755 GIT binary patch literal 3445 zcmbVOdvDuD692pU6yp>ajEG1SN zkH;R0Oy=l16*r||&a|cDTB99iwEE17*->GCgxOYmD>K`V*^ zST}-V06PD+fz(%_S{QUDJB<+3-D9Nhj&Mk#;$Fmu*c-lt#jy-h0{zGSu z;=5IPFsO;|?o|KCe6(Yv^-9rt>(9U@$bI(9vy+s8fs35- zu!DnaOq1e^yaIukYcLX;I_CzVG#aY{q(In8g<#4pdiR1}=QmWo-;^45WmOS$iW46_-EykA5swW1*s#@yONOd4* zTRS?~|G_?>Qq&FQWB~NHe2b6aJe>S6P)!Pg9YHjN1U6<|tv_2xntXWo>gD^Z)rXtk z>E_wyI~I5OIDaA$ikw?mOKga5E)C7m}P;#SS}-;_#s0Uu{?>xY`F{; z82a;Q5vN(=$IF0z&|l7zWn5$hV`&^0AqGqI=NR$@!zE`diW2(g8FH4)eU4eUD6)_^ z(l{jxvxIS$&Dng8ewgMg^BK!A4lpdp_(d89i`-A3is7kv8X^t$yu(aWzzQ*O^9N zn!%Zji+jg_ObsWz9#{#x3+chT3c0p#_W*ot@2QQW^2mffdd>)Rj)nVyz4h}cjrKVX zgl)8d0LFF>D~mvl03##lXljGG2QO0^-b%5yN=IcB!a+i->h8pj2b!a*|8?D)ellsb zvCErn{U~S@eo-V!@tIfUBhM$j zyI(s##KC#E8VdE9b`cAw%%y`?k%Dcm>jKG*$J0S z=?7h}Z?i{&skg!X&}`d^9X;rHsW(6Jl|4MN?Tf4pW>JyaSKewSTd6kdE~P1nLPDLo==9nF(C+$%f8xu~nEwBuO7gYCt*lYXrtu`K-)Q`= XXg)ZDx7{cKgcG0|aWYnP6T^Q26dqrA literal 173825 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%0D42;5lvZJw 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

)&tdVq)c(n#}UD)NxZ+>3Q6cNmrg0rW=`%BA-$ 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 XF9Gom4b2Yt703g;^A`ZbC$#?q&q@*K From cd0abcc0bb4c218fd02850a139b626d252e22599 Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Thu, 22 Aug 2013 13:54:23 +0200 Subject: [PATCH 016/113] Extractor for canalc2.tv --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/canalc2.py | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 youtube_dl/extractor/canalc2.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 9d12608e1..576b8433a 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -7,6 +7,7 @@ from .breakcom import BreakIE from .brightcove import BrightcoveIE from .canalplus import CanalplusIE +from .canalc2 import Canalc2IE from .collegehumor import CollegeHumorIE from .comedycentral import ComedyCentralIE from .condenast import CondeNastIE diff --git a/youtube_dl/extractor/canalc2.py b/youtube_dl/extractor/canalc2.py new file mode 100644 index 000000000..d0e2ed536 --- /dev/null +++ b/youtube_dl/extractor/canalc2.py @@ -0,0 +1,37 @@ +# coding: utf-8 +"""Extractor for canalc2.tv""" +import re +import lxml.html + +from .common import InfoExtractor + +class Canalc2IE(InfoExtractor): + """Extractor for canalc2.tv""" + _VALID_URL = r'http://.*?\.canalc2\.tv/video\.asp\?idVideo=(\d+)&voir=oui' + + _TEST = { + u'url': u'http://www.canalc2.tv/video.asp?idVideo=12163&voir=oui', + u'file': u'12163.mp4', + u'md5': u'c00fa80517373764ff5c0b5eb5a58780', + u'info_dict': { + u'title': u'Terrasses du Numérique' + } + } + + def _real_extract(self, url): + video_id = re.match(self._VALID_URL, url).group(1) + webpage = self._download_webpage(url, video_id) + file_name = re.search(r"so\.addVariable\('file','(.*?)'\);", + webpage).group(1) + + video_url = 'http://vod-flash.u-strasbg.fr:8080/' + file_name + + html = lxml.html.fromstring(webpage) + + title = html.cssselect('.evenement8')[0].text_content() + + return {'id': video_id, + 'ext' : 'mp4', + 'url' : video_url, + 'title' : title + } From ff2424595adf02cbe5d1f1071e53c3b2e5f32c9e Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Thu, 22 Aug 2013 14:47:51 +0200 Subject: [PATCH 017/113] lxml is not part of the standard library. --- youtube_dl/extractor/canalc2.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/youtube_dl/extractor/canalc2.py b/youtube_dl/extractor/canalc2.py index d0e2ed536..215abf537 100644 --- a/youtube_dl/extractor/canalc2.py +++ b/youtube_dl/extractor/canalc2.py @@ -1,7 +1,6 @@ # coding: utf-8 """Extractor for canalc2.tv""" import re -import lxml.html from .common import InfoExtractor @@ -25,10 +24,9 @@ def _real_extract(self, url): webpage).group(1) video_url = 'http://vod-flash.u-strasbg.fr:8080/' + file_name - - html = lxml.html.fromstring(webpage) - - title = html.cssselect('.evenement8')[0].text_content() + + title = self._html_search_regex(r'class="evenement8">(.*?)', + webpage, u'title') return {'id': video_id, 'ext' : 'mp4', From ce34e9ce5ec5cc403cf407ce8046b6271835cd6c Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Fri, 23 Aug 2013 16:33:41 +0200 Subject: [PATCH 018/113] XHamsterIE: Fix video extension Cut off GET parameter --- youtube_dl/extractor/xhamster.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/extractor/xhamster.py b/youtube_dl/extractor/xhamster.py index 0f1feeffd..5bedc25ce 100644 --- a/youtube_dl/extractor/xhamster.py +++ b/youtube_dl/extractor/xhamster.py @@ -36,7 +36,7 @@ def _real_extract(self,url): video_url = compat_urllib_parse.unquote(mobj.group('file')) else: video_url = mobj.group('server')+'/key='+mobj.group('file') - video_extension = video_url.split('.')[-1] + video_extension = video_url.split('.')[-1].split('?')[0] video_title = self._html_search_regex(r'(?P<title>.+?) - xHamster\.com', webpage, u'title') From 4353cf51a0d5a812ab8a6bda59be7c58149fb40e Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Fri, 23 Aug 2013 16:40:20 +0200 Subject: [PATCH 019/113] XHamsterIE: Add video description --- youtube_dl/extractor/xhamster.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/youtube_dl/extractor/xhamster.py b/youtube_dl/extractor/xhamster.py index 5bedc25ce..0fd077583 100644 --- a/youtube_dl/extractor/xhamster.py +++ b/youtube_dl/extractor/xhamster.py @@ -3,7 +3,7 @@ from .common import InfoExtractor from ..utils import ( compat_urllib_parse, - + unescapeHTML, ExtractorError, ) @@ -41,10 +41,12 @@ def _real_extract(self,url): video_title = self._html_search_regex(r'(?P<title>.+?) - xHamster\.com', webpage, u'title') - # Can't see the description anywhere in the UI - # video_description = self._html_search_regex(r'Description: (?P[^<]+)', - # webpage, u'description', fatal=False) - # if video_description: video_description = unescapeHTML(video_description) + # Only a few videos have an description + mobj = re.search('Description: (?P[^<]+)', webpage) + if mobj: + video_description = unescapeHTML(mobj.group('description')) + else: + video_description = None mobj = re.search(r'hint=\'(?P[0-9]{4})-(?P[0-9]{2})-(?P[0-9]{2}) [0-9]{2}:[0-9]{2}:[0-9]{2} [A-Z]{3,4}\'', webpage) if mobj: @@ -64,7 +66,7 @@ def _real_extract(self,url): 'url': video_url, 'ext': video_extension, 'title': video_title, - # 'description': video_description, + 'description': video_description, 'upload_date': video_upload_date, 'uploader_id': video_uploader_id, 'thumbnail': video_thumbnail From fc483bb6af4bce923c65a67618019a72071f30ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Fri, 23 Aug 2013 17:23:34 +0200 Subject: [PATCH 020/113] [xhamster] use determine_ext --- youtube_dl/extractor/xhamster.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/xhamster.py b/youtube_dl/extractor/xhamster.py index 0fd077583..88b8b6be0 100644 --- a/youtube_dl/extractor/xhamster.py +++ b/youtube_dl/extractor/xhamster.py @@ -4,6 +4,7 @@ from ..utils import ( compat_urllib_parse, unescapeHTML, + determine_ext, ExtractorError, ) @@ -36,7 +37,6 @@ def _real_extract(self,url): video_url = compat_urllib_parse.unquote(mobj.group('file')) else: video_url = mobj.group('server')+'/key='+mobj.group('file') - video_extension = video_url.split('.')[-1].split('?')[0] video_title = self._html_search_regex(r'(?P<title>.+?) - xHamster\.com', webpage, u'title') @@ -64,7 +64,7 @@ def _real_extract(self,url): return [{ 'id': video_id, 'url': video_url, - 'ext': video_extension, + 'ext': determine_ext(video_url), 'title': video_title, 'description': video_description, 'upload_date': video_upload_date, From 9af73dc4fc7dc54def861f94f9db4399b8bf928e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Fri, 23 Aug 2013 18:17:43 +0200 Subject: [PATCH 021/113] Print a message before embedding the subtitles --- youtube_dl/PostProcessor.py | 1 + 1 file changed, 1 insertion(+) diff --git a/youtube_dl/PostProcessor.py b/youtube_dl/PostProcessor.py index 336a42559..c02ed7148 100644 --- a/youtube_dl/PostProcessor.py +++ b/youtube_dl/PostProcessor.py @@ -458,6 +458,7 @@ def run(self, information): opts.extend(['-f', 'mp4']) temp_filename = filename + u'.temp' + self._downloader.to_screen(u'[ffmpeg] Embedding subtitles in \'%s\'' % filename) self.run_ffmpeg_multiple_files(input_files, temp_filename, opts) os.remove(encodeFilename(filename)) os.rename(encodeFilename(temp_filename), encodeFilename(filename)) From aa6a10c44a8e2e86f709c5301f9ea6ac3f01f002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Fri, 23 Aug 2013 18:34:57 +0200 Subject: [PATCH 022/113] Allow to specify multiple subtitles languages separated by commas (closes #518) --- test/test_youtube_subtitles.py | 13 +++++++++++-- youtube_dl/YoutubeDL.py | 2 +- youtube_dl/__init__.py | 12 ++++++++---- youtube_dl/extractor/youtube.py | 29 ++++++++++++++++------------- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/test/test_youtube_subtitles.py b/test/test_youtube_subtitles.py index fe0eac680..641206277 100644 --- a/test/test_youtube_subtitles.py +++ b/test/test_youtube_subtitles.py @@ -40,7 +40,7 @@ def test_youtube_subtitles(self): def test_youtube_subtitles_it(self): DL = FakeYDL() DL.params['writesubtitles'] = True - DL.params['subtitleslang'] = 'it' + DL.params['subtitleslangs'] = ['it'] IE = YoutubeIE(DL) info_dict = IE.extract('QRS8MkLhQmM') sub = info_dict[0]['subtitles']['it'] @@ -85,11 +85,20 @@ def test_youtube_list_subtitles(self): def test_youtube_automatic_captions(self): DL = FakeYDL() DL.params['writeautomaticsub'] = True - DL.params['subtitleslang'] = 'it' + DL.params['subtitleslangs'] = ['it'] IE = YoutubeIE(DL) info_dict = IE.extract('8YoUxe5ncPo') sub = info_dict[0]['subtitles']['it'] self.assertTrue(sub is not None) + def test_youtube_multiple_langs(self): + DL = FakeYDL() + DL.params['writesubtitles'] = True + langs = ['it', 'fr', 'de'] + DL.params['subtitleslangs'] = langs + IE = YoutubeIE(DL) + subtitles = IE.extract('QRS8MkLhQmM')[0]['subtitles'] + for lang in langs: + self.assertTrue(subtitles.get(lang) is not None, u'Subtitles for \'%s\' not extracted' % lang) if __name__ == '__main__': unittest.main() diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 1fd610a6e..3fc4ec378 100644 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -76,7 +76,7 @@ class YoutubeDL(object): allsubtitles: Downloads all the subtitles of the video listsubtitles: Lists all available subtitles for the video subtitlesformat: Subtitle format [srt/sbv/vtt] (default=srt) - subtitleslang: Language of the subtitles to download + subtitleslangs: List of languages of the subtitles to download keepvideo: Keep the video file after post-processing daterange: A DateRange object, download only if the upload_date is in the range. skip_download: Skip the actual download of the video file diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index 441ca6b6a..614429073 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -83,6 +83,9 @@ def _format_option_string(option): return "".join(opts) + def _comma_separated_values_options_callback(option, opt_str, value, parser): + setattr(parser.values, option.dest, value.split(',')) + def _find_term_columns(): columns = os.environ.get('COLUMNS', None) if columns: @@ -206,9 +209,10 @@ def _find_term_columns(): subtitles.add_option('--sub-format', action='store', dest='subtitlesformat', metavar='FORMAT', help='subtitle format (default=srt) ([sbv/vtt] youtube only)', default='srt') - subtitles.add_option('--sub-lang', '--srt-lang', - action='store', dest='subtitleslang', metavar='LANG', - help='language of the subtitles to download (optional) use IETF language tags like \'en\'') + subtitles.add_option('--sub-lang', '--sub-langs', '--srt-lang', + action='callback', dest='subtitleslang', metavar='LANGS', type='str', + default=[], callback=_comma_separated_values_options_callback, + help='languages of the subtitles to download (optional) separated by commas, use IETF language tags like \'en,pt\'') downloader.add_option('-r', '--rate-limit', dest='ratelimit', metavar='LIMIT', help='maximum download rate (e.g. 50k or 44.6m)') @@ -573,7 +577,7 @@ def _real_main(argv=None): 'allsubtitles': opts.allsubtitles, 'listsubtitles': opts.listsubtitles, 'subtitlesformat': opts.subtitlesformat, - 'subtitleslang': opts.subtitleslang, + 'subtitleslangs': opts.subtitleslang, 'matchtitle': decodeOption(opts.matchtitle), 'rejecttitle': decodeOption(opts.rejecttitle), 'max_downloads': opts.max_downloads, diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 446d53f64..5f843a871 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -496,7 +496,7 @@ def _request_subtitle(self, sub_lang, sub_name, video_id, format): def _request_automatic_caption(self, video_id, webpage): """We need the webpage for getting the captions url, pass it as an argument to speed up the process.""" - sub_lang = self._downloader.params.get('subtitleslang') or 'en' + sub_lang = (self._downloader.params.get('subtitleslangs') or ['en'])[0] sub_format = self._downloader.params.get('subtitlesformat') self.to_screen(u'%s: Looking for automatic captions' % video_id) mobj = re.search(r';ytplayer.config = ({.*?});', webpage) @@ -530,23 +530,26 @@ def _extract_subtitles(self, video_id): Return a dictionary: {language: subtitles} or {} if the subtitles couldn't be found """ - sub_lang_list = self._get_available_subtitles(video_id) + available_subs_list = self._get_available_subtitles(video_id) sub_format = self._downloader.params.get('subtitlesformat') - if not sub_lang_list: #There was some error, it didn't get the available subtitles + if not available_subs_list: #There was some error, it didn't get the available subtitles return {} if self._downloader.params.get('allsubtitles', False): - pass + sub_lang_list = available_subs_list else: - if self._downloader.params.get('subtitleslang', False): - sub_lang = self._downloader.params.get('subtitleslang') - elif 'en' in sub_lang_list: - sub_lang = 'en' + if self._downloader.params.get('subtitleslangs', False): + reqested_langs = self._downloader.params.get('subtitleslangs') + elif 'en' in available_subs_list: + reqested_langs = ['en'] else: - sub_lang = list(sub_lang_list.keys())[0] - if not sub_lang in sub_lang_list: - self._downloader.report_warning(u'no closed captions found in the specified language "%s"' % sub_lang) - return {} - sub_lang_list = {sub_lang: sub_lang_list[sub_lang]} + reqested_langs = [list(available_subs_list.keys())[0]] + + sub_lang_list = {} + for sub_lang in reqested_langs: + if not sub_lang in available_subs_list: + self._downloader.report_warning(u'no closed captions found in the specified language "%s"' % sub_lang) + continue + sub_lang_list[sub_lang] = available_subs_list[sub_lang] subtitles = {} for sub_lang in sub_lang_list: subtitle = self._request_subtitle(sub_lang, sub_lang_list[sub_lang].encode('utf-8'), video_id, sub_format) From 306170518f016ac7ebf8311d7d2a23937aeaf1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Fri, 23 Aug 2013 22:36:59 +0200 Subject: [PATCH 023/113] [youtube] update algo for length 86 (fixes #1302) --- devscripts/youtube_genalgo.py | 4 ++-- youtube_dl/extractor/youtube.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/devscripts/youtube_genalgo.py b/devscripts/youtube_genalgo.py index 663ccc422..014324439 100644 --- a/devscripts/youtube_genalgo.py +++ b/devscripts/youtube_genalgo.py @@ -20,9 +20,9 @@ # 87 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<", "uioplkjhgfdsazxcvbnm1t34567890QWE2TYUIOPLKJHGFDSAZXCVeNM!@#$^&*()_-+={[]}|:;?/>.<"), - # 86 + # 86 - vflh9ybst 2013/08/23 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<", - "yuioplkjhgfdsazecvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<"), + "yuioplkjhgfdsazxcvbnm1234567890QWERrYUIOPLKqHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<"), # 85 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<", ".>/?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWQ0q876543r1mnbvcx9asdfghjklpoiuyt2"), diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 5f843a871..e4987b2b3 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -423,7 +423,7 @@ def _decrypt_signature(self, s): elif len(s) == 87: return s[6:27] + s[4] + s[28:39] + s[27] + s[40:59] + s[2] + s[60:] elif len(s) == 86: - return s[5:20] + s[2] + s[21:] + return s[5:40] + s[3] + s[41:48] + s[0] + s[49:86] elif len(s) == 85: return s[83:34:-1] + s[0] + s[33:27:-1] + s[3] + s[26:19:-1] + s[34] + s[18:3:-1] + s[27] elif len(s) == 84: From 8ae7be3ef4873509241d98fd1adc2b82956f8def Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Fri, 23 Aug 2013 23:09:53 +0200 Subject: [PATCH 024/113] release 2013.08.23 --- README.md | 16 ++++++++++------ youtube_dl/version.py | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 560bcdca1..75068fe56 100644 --- a/README.md +++ b/README.md @@ -120,18 +120,20 @@ ## Video Format Options: --max-quality FORMAT highest quality format to download -F, --list-formats list all available formats (currently youtube only) + +## Subtitle Options: --write-sub write subtitle file (currently youtube only) --write-auto-sub write automatic subtitle file (currently youtube only) --only-sub [deprecated] alias of --skip-download --all-subs downloads all the available subtitles of the - video (currently youtube only) + video --list-subs lists all available subtitles for the video - (currently youtube only) - --sub-format FORMAT subtitle format [srt/sbv/vtt] (default=srt) - (currently youtube only) - --sub-lang LANG language of the subtitles to download (optional) - use IETF language tags like 'en' + --sub-format FORMAT subtitle format (default=srt) ([sbv/vtt] youtube + only) + --sub-lang LANGS languages of the subtitles to download (optional) + separated by commas, use IETF language tags like + 'en,pt' ## Authentication Options: -u, --username USERNAME account username @@ -153,6 +155,8 @@ ## Post-processing Options: processing; the video is erased by default --no-post-overwrites do not overwrite post-processed files; the post- processed files are overwritten by default + --embed-subs embed subtitles in the video (only for mp4 + videos) # CONFIGURATION diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 3536e923f..c10ebd4e8 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.08.22' +__version__ = '2013.08.23' From d2d1eb5b0a3ad2aa9d4867ba09b4b922b170f36a Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Fri, 23 Aug 2013 23:57:23 +0200 Subject: [PATCH 025/113] Switch to domain yt-dl.org --- devscripts/gh-pages/add-version.py | 26 +++++++++++++++----------- devscripts/gh-pages/update-feed.py | 3 +-- devscripts/release.sh | 2 +- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/devscripts/gh-pages/add-version.py b/devscripts/gh-pages/add-version.py index 6af8bb9d8..116420ef2 100755 --- a/devscripts/gh-pages/add-version.py +++ b/devscripts/gh-pages/add-version.py @@ -6,28 +6,32 @@ import urllib.request if len(sys.argv) <= 1: - print('Specify the version number as parameter') - sys.exit() + print('Specify the version number as parameter') + sys.exit() version = sys.argv[1] with open('update/LATEST_VERSION', 'w') as f: - f.write(version) + f.write(version) versions_info = json.load(open('update/versions.json')) if 'signature' in versions_info: - del versions_info['signature'] + del versions_info['signature'] new_version = {} -filenames = {'bin': 'youtube-dl', 'exe': 'youtube-dl.exe', 'tar': 'youtube-dl-%s.tar.gz' % version} +filenames = { + 'bin': 'youtube-dl', + 'exe': 'youtube-dl.exe', + 'tar': 'youtube-dl-%s.tar.gz' % version} for key, filename in filenames.items(): - print('Downloading and checksumming %s...' %filename) - url = 'http://youtube-dl.org/downloads/%s/%s' % (version, filename) - data = urllib.request.urlopen(url).read() - sha256sum = hashlib.sha256(data).hexdigest() - new_version[key] = (url, sha256sum) + print('Downloading and checksumming %s...' % filename) + url = 'https://yt-dl.org/downloads/%s/%s' % (version, filename) + data = urllib.request.urlopen(url).read() + sha256sum = hashlib.sha256(data).hexdigest() + new_version[key] = (url, sha256sum) versions_info['versions'][version] = new_version versions_info['latest'] = version -json.dump(versions_info, open('update/versions.json', 'w'), indent=4, sort_keys=True) \ No newline at end of file +with open('update/versions.json', 'w') as jsonf: + json.dump(versions_info, jsonf, indent=4, sort_keys=True) diff --git a/devscripts/gh-pages/update-feed.py b/devscripts/gh-pages/update-feed.py index cfff05fc8..16571a924 100755 --- a/devscripts/gh-pages/update-feed.py +++ b/devscripts/gh-pages/update-feed.py @@ -22,7 +22,7 @@

@@ -54,4 +54,3 @@ with open('update/releases.atom','w',encoding='utf-8') as atom_file: atom_file.write(atom_template) - diff --git a/devscripts/release.sh b/devscripts/release.sh index 46c31e437..24c9ad8d8 100755 --- a/devscripts/release.sh +++ b/devscripts/release.sh @@ -67,7 +67,7 @@ RELEASE_FILES="youtube-dl youtube-dl.exe youtube-dl-$version.tar.gz" (cd build/$version/ && sha512sum $RELEASE_FILES > SHA2-512SUMS) git checkout HEAD -- youtube-dl youtube-dl.exe -/bin/echo -e "\n### Signing and uploading the new binaries to youtube-dl.org..." +/bin/echo -e "\n### Signing and uploading the new binaries to yt-dl.org ..." for f in $RELEASE_FILES; do gpg --detach-sig "build/$version/$f"; done scp -r "build/$version" ytdl@yt-dl.org:html/tmp/ ssh ytdl@yt-dl.org "mv html/tmp/$version html/downloads/" From f2aeefe29c72e7c6165a35ba8153b52f96ee42af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Sat, 24 Aug 2013 10:48:12 +0200 Subject: [PATCH 026/113] [youtube] update algo for length 84 --- devscripts/youtube_genalgo.py | 4 ++-- youtube_dl/extractor/youtube.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/devscripts/youtube_genalgo.py b/devscripts/youtube_genalgo.py index 014324439..6f1d6ef99 100644 --- a/devscripts/youtube_genalgo.py +++ b/devscripts/youtube_genalgo.py @@ -26,9 +26,9 @@ # 85 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<", ".>/?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWQ0q876543r1mnbvcx9asdfghjklpoiuyt2"), - # 84 + # 84 - vflh9ybst 2013/08/23 (sporadic) ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?>.<", - "<.>?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWQ09876543q1mnbvcxzasdfghjklpoiuew2"), + "yuioplkjhgfdsazxcvbnm1234567890QWERrYUIOPLKqHGFDSAZXCVBNM!@#$%^&*()_-+={[};?>.<"), # 83 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!#$%^&*()_+={[};?/>.<", ".>/?;}[{=+_)(*&^%<#!MNBVCXZASPFGHJKLwOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytreq"), diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index e4987b2b3..af01c9da0 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -427,7 +427,7 @@ def _decrypt_signature(self, s): elif len(s) == 85: return s[83:34:-1] + s[0] + s[33:27:-1] + s[3] + s[26:19:-1] + s[34] + s[18:3:-1] + s[27] elif len(s) == 84: - return s[83:27:-1] + s[0] + s[26:5:-1] + s[2:0:-1] + s[27] + return s[5:40] + s[3] + s[41:48] + s[0] + s[49:84] 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: From d68730a56e9c26366758d66cd99f589cebad4686 Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Sat, 24 Aug 2013 13:22:28 +0200 Subject: [PATCH 027/113] Add SUPER RTL NOW to RTLnow extractor --- youtube_dl/extractor/rtlnow.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/rtlnow.py b/youtube_dl/extractor/rtlnow.py index d993a990a..67f341bcc 100644 --- a/youtube_dl/extractor/rtlnow.py +++ b/youtube_dl/extractor/rtlnow.py @@ -5,8 +5,8 @@ from ..utils import ExtractorError class RTLnowIE(InfoExtractor): - """Information Extractor for RTLnow, RTL2now and VOXnow""" - _VALID_URL = r'(?:http://)?(?P(?Prtl(?:(?P2)|-)now\.rtl(?(is_rtl2)2|)\.de/|(?:www\.)?voxnow\.de/)[a-zA-Z0-9-]+/[a-zA-Z0-9-]+\.php\?(?:container_id|film_id)=(?P[0-9]+)&player=1(?:&season=[0-9]+)?(?:&.*)?)' + """Information Extractor for RTL NOW, RTL2 NOW, SUPER RTL NOW and VOX NOW""" + _VALID_URL = r'(?:http://)?(?P(?Prtl-now\.rtl\.de/|rtl2now\.rtl2\.de/|(?:www\.)?voxnow\.de/|(?:www\.)?superrtlnow\.de/)[a-zA-Z0-9-]+/[a-zA-Z0-9-]+\.php\?(?:container_id|film_id)=(?P[0-9]+)&player=1(?:&season=[0-9]+)?(?:&.*)?)' _TESTS = [{ u'url': u'http://rtl-now.rtl.de/ahornallee/folge-1.php?film_id=90419&player=1&season=1', u'file': u'90419.flv', @@ -43,6 +43,19 @@ class RTLnowIE(InfoExtractor): u'params': { u'skip_download': True, }, + }, + { + u'url': u'http://superrtlnow.de/medicopter-117/angst.php?film_id=99205&player=1', + u'file': u'99205.flv', + u'info_dict': { + u'upload_date': u'20080928', + u'title': u'Medicopter 117 - Angst!', + u'description': u'Angst!', + u'thumbnail': u'http://autoimg.static-fra.de/superrtlnow/287529/1500x1500/image2.jpg' + }, + u'params': { + u'skip_download': True, + }, }] def _real_extract(self,url): From 9460db832ce2dc61456b2ad82e3b6190465a2133 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Sat, 24 Aug 2013 21:10:03 +0200 Subject: [PATCH 028/113] [ro220] Add support for 220.ro --- youtube_dl/extractor/__init__.py | 3 +++ youtube_dl/extractor/ro220.py | 42 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 youtube_dl/extractor/ro220.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index b4db8f0bf..39c530ba3 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -57,6 +57,7 @@ from .rbmaradio import RBMARadioIE from .redtube import RedTubeIE from .ringtv import RingTVIE +from .ro220 import Ro220IE from .roxwel import RoxwelIE from .rtlnow import RTLnowIE from .sina import SinaIE @@ -116,12 +117,14 @@ ] _ALL_CLASSES.append(GenericIE) + def gen_extractors(): """ Return a list of an instance of every supported extractor. The order does matter; the first extractor matched is the one handling the URL. """ return [klass() for klass in _ALL_CLASSES] + def get_info_extractor(ie_name): """Returns the info extractor class with the given ie_name""" return globals()[ie_name+'IE'] diff --git a/youtube_dl/extractor/ro220.py b/youtube_dl/extractor/ro220.py new file mode 100644 index 000000000..c32f64d99 --- /dev/null +++ b/youtube_dl/extractor/ro220.py @@ -0,0 +1,42 @@ +import re + +from .common import InfoExtractor +from ..utils import ( + clean_html, + compat_parse_qs, +) + + +class Ro220IE(InfoExtractor): + IE_NAME = '220.ro' + _VALID_URL = r'(?x)(?:https?://)?(?:www\.)?220\.ro/(?P[^/]+)/(?P[^/]+)/(?P[^/]+)' + _TEST = { + u"url": u"http://www.220.ro/sport/Luati-Le-Banii-Sez-4-Ep-1/LYV6doKo7f/", + u'file': u'LYV6doKo7f.mp4', + u'md5': u'03af18b73a07b4088753930db7a34add', + u'info_dict': { + u"title": u"Luati-le Banii sez 4 ep 1", + u"description": u"Iata-ne reveniti dupa o binemeritata vacanta. Va astept si pe Facebook cu pareri si comentarii.", + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('video_id') + + webpage = self._download_webpage(url, video_id) + flashVars_str = self._search_regex( + r' Date: Sat, 24 Aug 2013 22:49:22 +0200 Subject: [PATCH 029/113] Install our own HTTPS handler as well (#1309) --- youtube_dl/utils.py | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 52cfb8a6d..ab1049cc0 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -476,7 +476,7 @@ def formatSeconds(secs): def make_HTTPS_handler(opts): if sys.version_info < (3,2): # Python's 2.x handler is very simplistic - return compat_urllib_request.HTTPSHandler() + return YoutubeDLHandlerHTTPS() else: import ssl context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) @@ -485,7 +485,7 @@ def make_HTTPS_handler(opts): context.verify_mode = (ssl.CERT_NONE if opts.no_check_certificate else ssl.CERT_REQUIRED) - return compat_urllib_request.HTTPSHandler(context=context) + return YoutubeDLHandlerHTTPS(context=context) class ExtractorError(Exception): """Error during info extraction.""" @@ -569,7 +569,8 @@ def __init__(self, downloaded, expected): self.downloaded = downloaded self.expected = expected -class YoutubeDLHandler(compat_urllib_request.HTTPHandler): + +class YoutubeDLHandler_Template: # Old-style class, like HTTPHandler """Handler for HTTP requests and responses. This class, when installed with an OpenerDirector, automatically adds @@ -602,8 +603,8 @@ def addinfourl_wrapper(stream, headers, url, code): ret.code = code return ret - def http_request(self, req): - for h,v in std_headers.items(): + def _http_request(self, req): + for h, v in std_headers.items(): if h in req.headers: del req.headers[h] req.add_header(h, v) @@ -618,7 +619,7 @@ def http_request(self, req): del req.headers['Youtubedl-user-agent'] return req - def http_response(self, req, resp): + def _http_response(self, req, resp): old_resp = resp # gzip if resp.headers.get('Content-encoding', '') == 'gzip': @@ -632,8 +633,16 @@ def http_response(self, req, resp): resp.msg = old_resp.msg return resp - https_request = http_request - https_response = http_response + +class YoutubeDLHandler(YoutubeDLHandler_Template, compat_urllib_request.HTTPHandler): + http_request = YoutubeDLHandler_Template._http_request + http_response = YoutubeDLHandler_Template._http_response + + +class YoutubeDLHandlerHTTPS(YoutubeDLHandler_Template, compat_urllib_request.HTTPSHandler): + https_request = YoutubeDLHandler_Template._http_request + https_response = YoutubeDLHandler_Template._http_response + def unified_strdate(date_str): """Return a string with the date in the format YYYYMMDD""" From 0838239e8e454c55903f3d69560cf53e25ce69f4 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Sat, 24 Aug 2013 22:49:52 +0200 Subject: [PATCH 030/113] [generic] Support double slash URLs (Fixes #1309) --- youtube_dl/extractor/generic.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index da016f7ee..ccbbdd255 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -7,12 +7,14 @@ from ..utils import ( compat_urllib_error, compat_urllib_parse, + compat_urllib_parse_urlparse, compat_urllib_request, ExtractorError, ) from .brightcove import BrightcoveIE + class GenericIE(InfoExtractor): IE_DESC = u'Generic downloader that works on some sites' _VALID_URL = r'.*' @@ -23,7 +25,7 @@ class GenericIE(InfoExtractor): u'file': u'13601338388002.mp4', u'md5': u'85b90ccc9d73b4acd9138d3af4c27f89', u'info_dict': { - u"uploader": u"www.hodiho.fr", + u"uploader": u"www.hodiho.fr", u"title": u"R\u00e9gis plante sa Jeep" } }, @@ -161,6 +163,8 @@ def _real_extract(self, url): raise ExtractorError(u'Invalid URL: %s' % url) video_url = compat_urllib_parse.unquote(mobj.group(1)) + if video_url.startswith('//'): + video_url = compat_urllib_parse_urlparse(url).scheme + ':' + video_url video_id = os.path.basename(video_url) # here's a fun little line of code for you: From 9585f890f8c0eff70eb874c7962dc30baea1049c Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Sat, 24 Aug 2013 22:56:37 +0200 Subject: [PATCH 031/113] [generic] add support for relative URLs (Fixes #1308) --- youtube_dl/extractor/generic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index ccbbdd255..8488dca05 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -165,6 +165,8 @@ def _real_extract(self, url): video_url = compat_urllib_parse.unquote(mobj.group(1)) if video_url.startswith('//'): video_url = compat_urllib_parse_urlparse(url).scheme + ':' + video_url + if '://' not in video_url: + video_url = url + ('' if url.endswith('/') else '/') + video_url video_id = os.path.basename(video_url) # here's a fun little line of code for you: From 627a91a9a827b48270d3f5e288404388946f0733 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Mon, 26 Aug 2013 21:29:31 +0200 Subject: [PATCH 032/113] [generic] small typo --- youtube_dl/extractor/generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index 8488dca05..d034a11bb 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -126,7 +126,7 @@ def _real_extract(self, url): raise ExtractorError(u'Invalid URL: %s' % url) self.report_extraction(video_id) - # Look for BrigthCove: + # Look for BrightCove: m_brightcove = re.search(r'', webpage, re.DOTALL) if m_brightcove is not None: self.to_screen(u'Brightcove video detected.') From 976fc7d137c9f23533c9bcf5942af72d3c861b14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=2EYasoob=20Ullah=20Khalid=20=E2=98=BA?= Date: Tue, 27 Aug 2013 01:00:17 +0500 Subject: [PATCH 033/113] fixed tests for c56 and dailymotion --- youtube_dl/extractor/c56.py | 4 ++-- youtube_dl/extractor/dailymotion.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/youtube_dl/extractor/c56.py b/youtube_dl/extractor/c56.py index 4c8a8af09..dc3a8d47d 100644 --- a/youtube_dl/extractor/c56.py +++ b/youtube_dl/extractor/c56.py @@ -12,8 +12,8 @@ class C56IE(InfoExtractor): _TEST ={ u'url': u'http://www.56.com/u39/v_OTM0NDA3MTY.html', - u'file': u'93440716.mp4', - u'md5': u'9dc07b5c8e978112a6441f9e75d2b59e', + u'file': u'93440716.flv', + u'md5': u'e59995ac63d0457783ea05f93f12a866', u'info_dict': { u'title': u'网事知多少 第32期:车怒', }, diff --git a/youtube_dl/extractor/dailymotion.py b/youtube_dl/extractor/dailymotion.py index fa8c630d0..1ea449ca8 100644 --- a/youtube_dl/extractor/dailymotion.py +++ b/youtube_dl/extractor/dailymotion.py @@ -21,7 +21,7 @@ class DailymotionIE(InfoExtractor): u'file': u'x33vw9.mp4', u'md5': u'392c4b85a60a90dc4792da41ce3144eb', u'info_dict': { - u"uploader": u"Alex and Van .", + u"uploader": u"Amphora Alex and Van .", u"title": u"Tutoriel de Youtubeur\"DL DES VIDEO DE YOUTUBE\"" } } From 341ca8d74c8f090bd696111353400f0cef2ba9bc Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Tue, 27 Aug 2013 01:59:00 +0200 Subject: [PATCH 034/113] [trilulilu] Add support for trilulilu.ro Fun fact: The ads (not yet supported) are loaded from youtube ;) --- youtube_dl/extractor/__init__.py | 5 +- youtube_dl/extractor/trilulilu.py | 76 +++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 youtube_dl/extractor/trilulilu.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index f71ae2713..fa53d9af9 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -6,6 +6,7 @@ from .bliptv import BlipTVIE, BlipTVUserIE from .breakcom import BreakIE from .brightcove import BrightcoveIE +from .c56 import C56IE from .canalplus import CanalplusIE from .collegehumor import CollegeHumorIE from .comedycentral import ComedyCentralIE @@ -73,18 +74,18 @@ from .tf1 import TF1IE from .thisav import ThisAVIE from .traileraddict import TrailerAddictIE +from .trilulilu import TriluliluIE from .tudou import TudouIE from .tumblr import TumblrIE from .tutv import TutvIE -from .ustream import UstreamIE from .unistra import UnistraIE +from .ustream import UstreamIE from .vbox7 import Vbox7IE from .veoh import VeohIE from .vevo import VevoIE from .videofyme import VideofyMeIE from .vimeo import VimeoIE, VimeoChannelIE from .vine import VineIE -from .c56 import C56IE from .wat import WatIE from .weibo import WeiboIE from .wimp import WimpIE diff --git a/youtube_dl/extractor/trilulilu.py b/youtube_dl/extractor/trilulilu.py new file mode 100644 index 000000000..1c46156c7 --- /dev/null +++ b/youtube_dl/extractor/trilulilu.py @@ -0,0 +1,76 @@ +import json +import re +import xml.etree.ElementTree + +from .common import InfoExtractor +from ..utils import ( + ExtractorError, +) + + +class TriluliluIE(InfoExtractor): + _VALID_URL = r'(?x)(?:https?://)?(?:www\.)?trilulilu\.ro/video-(?P[^/]+)/(?P[^/]+)' + _TEST = { + u"url": u"http://www.trilulilu.ro/video-animatie/big-buck-bunny-1", + u'file': u"big-buck-bunny-1.mp4", + u'info_dict': { + u"title": u"Big Buck Bunny", + u"description": u":) pentru copilul din noi", + }, + # Server ignores Range headers (--test) + u"params": { + u"skip_download": True + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('video_id') + + webpage = self._download_webpage(url, video_id) + + title = self._og_search_title(webpage) + thumbnail = self._og_search_thumbnail(webpage) + description = self._og_search_description(webpage) + + log_str = self._search_regex( + r'block_flash_vars[ ]=[ ]({[^}]+})', webpage, u'log info') + log = json.loads(log_str) + + format_url = (u'http://fs%(server)s.trilulilu.ro/%(hash)s/' + u'video-formats2' % log) + format_str = self._download_webpage( + format_url, video_id, + note=u'Downloading formats', + errnote=u'Error while downloading formats') + + format_doc = xml.etree.ElementTree.fromstring(format_str) + + video_url_template = ( + u'http://fs%(server)s.trilulilu.ro/stream.php?type=video' + u'&source=site&hash=%(hash)s&username=%(userid)s&' + u'key=ministhebest&format=%%s&sig=&exp=' % + log) + formats = [ + { + 'format': fnode.text, + 'url': video_url_template % fnode.text, + } + + for fnode in format_doc.findall('./formats/format') + ] + + info = { + '_type': 'video', + 'id': video_id, + 'formats': formats, + 'title': title, + 'description': description, + 'thumbnail': thumbnail, + } + + # TODO: Remove when #980 has been merged + info['url'] = formats[-1]['url'] + info['ext'] = formats[-1]['format'].partition('-')[0] + + return info From b3889f702396b1e9641f2329d793915e5ae1454c Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Tue, 27 Aug 2013 02:30:47 +0200 Subject: [PATCH 035/113] release 2013.08.27 --- youtube_dl/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/version.py b/youtube_dl/version.py index c10ebd4e8..dff568640 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.08.23' +__version__ = '2013.08.27' From 069d098f846ca53073ec646f335f77dac4439844 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Tue, 27 Aug 2013 10:21:57 +0200 Subject: [PATCH 036/113] [canalplus] Accept player.canalplus.fr urls --- youtube_dl/extractor/canalplus.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/extractor/canalplus.py b/youtube_dl/extractor/canalplus.py index 3b1c88876..1f02519a0 100644 --- a/youtube_dl/extractor/canalplus.py +++ b/youtube_dl/extractor/canalplus.py @@ -5,7 +5,7 @@ from ..utils import unified_strdate class CanalplusIE(InfoExtractor): - _VALID_URL = r'https?://www\.canalplus\.fr/.*?\?vid=(?P\d+)' + _VALID_URL = r'https?://(www\.canalplus\.fr/.*?\?vid=|player\.canalplus\.fr/#/)(?P\d+)' _VIDEO_INFO_TEMPLATE = 'http://service.canal-plus.com/video/rest/getVideosLiees/cplus/%s' IE_NAME = u'canalplus.fr' From 2a7b4da9b2ee11e88976e0e93796fd8460aa053d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Tue, 27 Aug 2013 10:25:38 +0200 Subject: [PATCH 037/113] [hark] get the song info in JSON and extract more information. --- youtube_dl/extractor/hark.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/youtube_dl/extractor/hark.py b/youtube_dl/extractor/hark.py index ab0a69697..5bdd08afa 100644 --- a/youtube_dl/extractor/hark.py +++ b/youtube_dl/extractor/hark.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- import re +import json from .common import InfoExtractor from ..utils import determine_ext @@ -12,24 +13,25 @@ class HarkIE(InfoExtractor): u'file': u'mmbzyhkgny.mp3', u'md5': u'6783a58491b47b92c7c1af5a77d4cbee', u'info_dict': { - u"title": u"Obama: 'Beyond The Afghan Theater, We Only Target Al Qaeda' On May 23, 2013 ", + u'title': u"Obama: 'Beyond The Afghan Theater, We Only Target Al Qaeda' on May 23, 2013", + u'description': u'President Barack Obama addressed the nation live on May 23, 2013 in a speech aimed at addressing counter-terrorism policies including the use of drone strikes, detainees at Guantanamo Bay prison facility, and American citizens who are terrorists.', + u'duration': 11, } } def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) video_id = mobj.group(1) - embed_url = "http://www.hark.com/clips/%s/homepage_embed" %(video_id) - webpage = self._download_webpage(embed_url, video_id) - - final_url = self._search_regex(r'src="(.+?).mp3"', - webpage, 'video url')+'.mp3' - title = self._html_search_regex(r'(.+?)', - webpage, 'video title').replace(' Sound Clip and Quote - Hark','').replace( - 'Sound Clip , Quote, MP3, and Ringtone - Hark','') + json_url = "http://www.hark.com/clips/%s.json" %(video_id) + info_json = self._download_webpage(json_url, video_id) + info = json.loads(info_json) + final_url = info['url'] return {'id': video_id, 'url' : final_url, - 'title': title, + 'title': info['name'], 'ext': determine_ext(final_url), + 'description': info['description'], + 'thumbnail': info['image_original'], + 'duration': info['duration'], } From e86ea47c029c1f95a696e43df7bea2e3e617fbc3 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Tue, 27 Aug 2013 10:35:20 +0200 Subject: [PATCH 038/113] [canalc2] Small improvements --- youtube_dl/extractor/canalc2.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/youtube_dl/extractor/canalc2.py b/youtube_dl/extractor/canalc2.py index 215abf537..50832217a 100644 --- a/youtube_dl/extractor/canalc2.py +++ b/youtube_dl/extractor/canalc2.py @@ -1,17 +1,17 @@ # coding: utf-8 -"""Extractor for canalc2.tv""" import re from .common import InfoExtractor + class Canalc2IE(InfoExtractor): - """Extractor for canalc2.tv""" + _IE_NAME = 'canalc2.tv' _VALID_URL = r'http://.*?\.canalc2\.tv/video\.asp\?idVideo=(\d+)&voir=oui' _TEST = { u'url': u'http://www.canalc2.tv/video.asp?idVideo=12163&voir=oui', u'file': u'12163.mp4', - u'md5': u'c00fa80517373764ff5c0b5eb5a58780', + u'md5': u'060158428b650f896c542dfbb3d6487f', u'info_dict': { u'title': u'Terrasses du Numérique' } @@ -20,16 +20,16 @@ class Canalc2IE(InfoExtractor): def _real_extract(self, url): video_id = re.match(self._VALID_URL, url).group(1) webpage = self._download_webpage(url, video_id) - file_name = re.search(r"so\.addVariable\('file','(.*?)'\);", - webpage).group(1) - + file_name = self._search_regex( + r"so\.addVariable\('file','(.*?)'\);", + webpage, 'file name') video_url = 'http://vod-flash.u-strasbg.fr:8080/' + file_name - title = self._html_search_regex(r'class="evenement8">(.*?)', - webpage, u'title') + title = self._html_search_regex( + r'class="evenement8">(.*?)', webpage, u'title') return {'id': video_id, - 'ext' : 'mp4', - 'url' : video_url, - 'title' : title + 'ext': 'mp4', + 'url': video_url, + 'title': title, } From 1a582dd49d628914fa6a056b490914738f15c56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Tue, 27 Aug 2013 11:56:48 +0200 Subject: [PATCH 039/113] Add an extractor for CNN (closes #1318) --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/cnn.py | 47 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 youtube_dl/extractor/cnn.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index eeeb3db50..ea2af0d0e 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -9,6 +9,7 @@ from .c56 import C56IE from .canalplus import CanalplusIE from .canalc2 import Canalc2IE +from .cnn import CNNIE from .collegehumor import CollegeHumorIE from .comedycentral import ComedyCentralIE from .condenast import CondeNastIE diff --git a/youtube_dl/extractor/cnn.py b/youtube_dl/extractor/cnn.py new file mode 100644 index 000000000..cee78765b --- /dev/null +++ b/youtube_dl/extractor/cnn.py @@ -0,0 +1,47 @@ +import re +import xml.etree.ElementTree + +from .common import InfoExtractor +from ..utils import determine_ext + +class CNNIE(InfoExtractor): + _VALID_URL = r'https?://(edition\.)?cnn\.com/video/(data/.+?|\?)/(?P.+?/(?P[^/]+?)\.cnn)' + + _TEST = { + u'url': u'http://edition.cnn.com/video/?/video/sports/2013/06/09/nadal-1-on-1.cnn', + u'file': u'sports_2013_06_09_nadal-1-on-1.cnn.mp4', + u'md5': u'3e6121ea48df7e2259fe73a0628605c4', + u'info_dict': { + u'title': u'Nadal wins 8th French Open title', + u'description': u'World Sport\'s Amanda Davies chats with 2013 French Open champion Rafael Nadal.', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + path = mobj.group('path') + page_title = mobj.group('title') + info_xml = self._download_webpage( + 'http://cnn.com/video/data/3.0/%s/index.xml' % path, page_title) + info = xml.etree.ElementTree.fromstring(info_xml.encode('utf-8')) + + formats = [] + for f in info.findall('files/file'): + mf = re.match(r'(\d+)x(\d+)(?:_(.*)k)?',f.attrib['bitrate']) + if mf is not None: + formats.append((int(mf.group(1)), int(mf.group(2)), int(mf.group(3) or 0), f.text)) + formats = sorted(formats) + (_,_,_, video_path) = formats[-1] + video_url = 'http://ht.cdn.turner.com/cnn/big%s' % video_path + + thumbnails = sorted([((int(t.attrib['height']),int(t.attrib['width'])), t.text) for t in info.findall('images/image')]) + thumbs_dict = [{'resolution': res, 'url': t_url} for (res, t_url) in thumbnails] + + return {'id': info.attrib['id'], + 'title': info.find('headline').text, + 'url': video_url, + 'ext': determine_ext(video_url), + 'thumbnail': thumbnails[-1][1], + 'thumbnails': thumbs_dict, + 'description': info.find('description').text, + } From 0bc56fa66a4b0f1b6bf827bd3550a119d3e3b231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Tue, 27 Aug 2013 12:38:30 +0200 Subject: [PATCH 040/113] Add an extractor for NBC news (closes #1320) --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/nbc.py | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 youtube_dl/extractor/nbc.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index ea2af0d0e..27bbcc0f7 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -54,6 +54,7 @@ from .myspass import MySpassIE from .myvideo import MyVideoIE from .nba import NBAIE +from .nbc import NBCNewsIE from .ooyala import OoyalaIE from .pbs import PBSIE from .photobucket import PhotobucketIE diff --git a/youtube_dl/extractor/nbc.py b/youtube_dl/extractor/nbc.py new file mode 100644 index 000000000..3bc9dae6d --- /dev/null +++ b/youtube_dl/extractor/nbc.py @@ -0,0 +1,33 @@ +import re +import xml.etree.ElementTree + +from .common import InfoExtractor +from ..utils import find_xpath_attr, compat_str + + +class NBCNewsIE(InfoExtractor): + _VALID_URL = r'https?://www\.nbcnews\.com/video/.+?/(?P<id>\d+)' + + _TEST = { + u'url': u'http://www.nbcnews.com/video/nbc-news/52753292', + u'file': u'52753292.flv', + u'md5': u'47abaac93c6eaf9ad37ee6c4463a5179', + u'info_dict': { + u'title': u'Crew emerges after four-month Mars food study', + u'description': u'md5:24e632ffac72b35f8b67a12d1b6ddfc1', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + info_xml = self._download_webpage('http://www.nbcnews.com/id/%s/displaymode/1219' % video_id, video_id) + info = xml.etree.ElementTree.fromstring(info_xml.encode('utf-8')).find('video') + + return {'id': video_id, + 'title': info.find('headline').text, + 'ext': 'flv', + 'url': find_xpath_attr(info, 'media', 'type', 'flashVideo').text, + 'description': compat_str(info.find('caption').text), + 'thumbnail': find_xpath_attr(info, 'media', 'type', 'thumbnail').text, + } From 7f3c4f4f65ddb4f8374b31b74428780e60a373de Mon Sep 17 00:00:00 2001 From: Jeff Smith <whydoubt@yahoo.com> Date: Tue, 27 Aug 2013 14:38:50 -0500 Subject: [PATCH 041/113] Initial slash in Google+ photos link was removed --- youtube_dl/extractor/googleplus.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/googleplus.py b/youtube_dl/extractor/googleplus.py index 9f7fc19a4..f1cd88983 100644 --- a/youtube_dl/extractor/googleplus.py +++ b/youtube_dl/extractor/googleplus.py @@ -57,8 +57,8 @@ def _real_extract(self, url): webpage, 'title', default=u'NA') # Step 2, Simulate clicking the image box to launch video - DOMAIN = 'https://plus.google.com' - video_page = self._search_regex(r'<a href="((?:%s)?/photos/.*?)"' % re.escape(DOMAIN), + DOMAIN = 'https://plus.google.com/' + video_page = self._search_regex(r'<a href="((?:%s)?photos/.*?)"' % re.escape(DOMAIN), webpage, u'video page URL') if not video_page.startswith(DOMAIN): video_page = DOMAIN + video_page From acebc9cd6bd713c518e80d00af13e3120614e115 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Tue, 27 Aug 2013 23:15:01 +0200 Subject: [PATCH 042/113] Revert "Install our own HTTPS handler as well (#1309)" This reverts commit 36399e85765a6a04fd84126264af75382fcfd1f6 and fixes #1322. --- youtube_dl/utils.py | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index ab1049cc0..52cfb8a6d 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -476,7 +476,7 @@ def formatSeconds(secs): def make_HTTPS_handler(opts): if sys.version_info < (3,2): # Python's 2.x handler is very simplistic - return YoutubeDLHandlerHTTPS() + return compat_urllib_request.HTTPSHandler() else: import ssl context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) @@ -485,7 +485,7 @@ def make_HTTPS_handler(opts): context.verify_mode = (ssl.CERT_NONE if opts.no_check_certificate else ssl.CERT_REQUIRED) - return YoutubeDLHandlerHTTPS(context=context) + return compat_urllib_request.HTTPSHandler(context=context) class ExtractorError(Exception): """Error during info extraction.""" @@ -569,8 +569,7 @@ def __init__(self, downloaded, expected): self.downloaded = downloaded self.expected = expected - -class YoutubeDLHandler_Template: # Old-style class, like HTTPHandler +class YoutubeDLHandler(compat_urllib_request.HTTPHandler): """Handler for HTTP requests and responses. This class, when installed with an OpenerDirector, automatically adds @@ -603,8 +602,8 @@ def addinfourl_wrapper(stream, headers, url, code): ret.code = code return ret - def _http_request(self, req): - for h, v in std_headers.items(): + def http_request(self, req): + for h,v in std_headers.items(): if h in req.headers: del req.headers[h] req.add_header(h, v) @@ -619,7 +618,7 @@ def _http_request(self, req): del req.headers['Youtubedl-user-agent'] return req - def _http_response(self, req, resp): + def http_response(self, req, resp): old_resp = resp # gzip if resp.headers.get('Content-encoding', '') == 'gzip': @@ -633,16 +632,8 @@ def _http_response(self, req, resp): resp.msg = old_resp.msg return resp - -class YoutubeDLHandler(YoutubeDLHandler_Template, compat_urllib_request.HTTPHandler): - http_request = YoutubeDLHandler_Template._http_request - http_response = YoutubeDLHandler_Template._http_response - - -class YoutubeDLHandlerHTTPS(YoutubeDLHandler_Template, compat_urllib_request.HTTPSHandler): - https_request = YoutubeDLHandler_Template._http_request - https_response = YoutubeDLHandler_Template._http_response - + https_request = http_request + https_response = http_response def unified_strdate(date_str): """Return a string with the date in the format YYYYMMDD""" From 88a79ce6a6edb6d3f8b6e3319f6ca1d3d2954c16 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Tue, 27 Aug 2013 23:31:24 +0200 Subject: [PATCH 043/113] Delete default user agent (Fixes #1309) --- youtube_dl/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index 614429073..bc6a6d180 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -430,6 +430,10 @@ def _real_main(argv=None): proxy_handler = compat_urllib_request.ProxyHandler(proxies) https_handler = make_HTTPS_handler(opts) opener = compat_urllib_request.build_opener(https_handler, proxy_handler, cookie_processor, YoutubeDLHandler()) + # Delete the default user-agent header, which would otherwise apply in + # cases where our custom HTTP handler doesn't come into play + # (See https://github.com/rg3/youtube-dl/issues/1309 for details) + opener.addheaders =[] compat_urllib_request.install_opener(opener) socket.setdefaulttimeout(300) # 5 minutes should be enough (famous last words) From 1619e22f40883ba3c39f4d2a020cba3a1eebd34f Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Tue, 27 Aug 2013 23:31:36 +0200 Subject: [PATCH 044/113] release 2013.08.28 --- youtube_dl/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/version.py b/youtube_dl/version.py index dff568640..0b56e48dc 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.08.27' +__version__ = '2013.08.28' From 273f603efb2028a54e04cca314b72bc2a9d767ef Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 00:14:19 +0200 Subject: [PATCH 045/113] [cnn] Allow more URLs --- youtube_dl/extractor/cnn.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/youtube_dl/extractor/cnn.py b/youtube_dl/extractor/cnn.py index cee78765b..4338bd180 100644 --- a/youtube_dl/extractor/cnn.py +++ b/youtube_dl/extractor/cnn.py @@ -4,10 +4,12 @@ from .common import InfoExtractor from ..utils import determine_ext -class CNNIE(InfoExtractor): - _VALID_URL = r'https?://(edition\.)?cnn\.com/video/(data/.+?|\?)/(?P<path>.+?/(?P<title>[^/]+?)\.cnn)' - _TEST = { +class CNNIE(InfoExtractor): + _VALID_URL = r'''(?x)https?://(edition\.)?cnn\.com/video/(data/.+?|\?)/ + (?P<path>.+?/(?P<title>[^/]+?)(?:\.cnn|(?=&)))''' + + _TESTS = [{ u'url': u'http://edition.cnn.com/video/?/video/sports/2013/06/09/nadal-1-on-1.cnn', u'file': u'sports_2013_06_09_nadal-1-on-1.cnn.mp4', u'md5': u'3e6121ea48df7e2259fe73a0628605c4', @@ -15,14 +17,24 @@ class CNNIE(InfoExtractor): u'title': u'Nadal wins 8th French Open title', u'description': u'World Sport\'s Amanda Davies chats with 2013 French Open champion Rafael Nadal.', }, - } + }, + { + u"url": u"http://edition.cnn.com/video/?/video/us/2013/08/21/sot-student-gives-epic-speech.georgia-institute-of-technology&utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+rss%2Fcnn_topstories+%28RSS%3A+Top+Stories%29", + u"file": u"us_2013_08_21_sot-student-gives-epic-speech.georgia-institute-of-technology.mp4", + u"md5": u"b5cc60c60a3477d185af8f19a2a26f4e", + u"info_dict": { + u"title": "Student's epic speech stuns new freshmen", + u"description": "A Georgia Tech student welcomes the incoming freshmen with an epic speech backed by music from \"2001: A Space Odyssey.\"" + } + }] def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) path = mobj.group('path') page_title = mobj.group('title') - info_xml = self._download_webpage( - 'http://cnn.com/video/data/3.0/%s/index.xml' % path, page_title) + info_url = u'http://cnn.com/video/data/3.0/%s/index.xml' % path + print(info_url) + info_xml = self._download_webpage(info_url, page_title) info = xml.etree.ElementTree.fromstring(info_xml.encode('utf-8')) formats = [] From 44586389e4676dfd926255cf76e36684dcf4742d Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 02:18:44 +0200 Subject: [PATCH 046/113] [appletrailers] Add support --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/appletrailers.py | 167 ++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 youtube_dl/extractor/appletrailers.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 27bbcc0f7..2f86f2aca 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -1,3 +1,4 @@ +from .appletrailers import AppleTrailersIE from .archiveorg import ArchiveOrgIE from .ard import ARDIE from .arte import ArteTvIE diff --git a/youtube_dl/extractor/appletrailers.py b/youtube_dl/extractor/appletrailers.py new file mode 100644 index 000000000..7d126e2d2 --- /dev/null +++ b/youtube_dl/extractor/appletrailers.py @@ -0,0 +1,167 @@ +import re +import xml.etree.ElementTree + +from .common import InfoExtractor +from ..utils import ( + determine_ext, + ExtractorError, +) + + +class AppleTrailersIE(InfoExtractor): + _VALID_URL = r'https?://(?:www\.)?trailers.apple.com/trailers/(?P<company>[^/]+)/(?P<movie>[^/]+)' + _TEST = { + u"url": u"http://trailers.apple.com/trailers/wb/manofsteel/", + u"playlist": [ + { + u"file": u"manofsteel-trailer4.mov", + u"md5": u"11874af099d480cc09e103b189805d5f", + u"info_dict": { + u"duration": 111, + u"thumbnail": u"http://trailers.apple.com/trailers/wb/manofsteel/images/thumbnail_11624.jpg", + u"title": u"Trailer 4", + u"upload_date": u"20130523", + u"uploader_id": u"wb", + }, + }, + { + u"file": u"manofsteel-trailer3.mov", + u"md5": u"07a0a262aae5afe68120eed61137ab34", + u"info_dict": { + u"duration": 182, + u"thumbnail": u"http://trailers.apple.com/trailers/wb/manofsteel/images/thumbnail_10793.jpg", + u"title": u"Trailer 3", + u"upload_date": u"20130417", + u"uploader_id": u"wb", + }, + }, + { + u"file": u"manofsteel-trailer.mov", + u"md5": u"e401fde0813008e3307e54b6f384cff1", + u"info_dict": { + u"duration": 148, + u"thumbnail": u"http://trailers.apple.com/trailers/wb/manofsteel/images/thumbnail_8703.jpg", + u"title": u"Trailer", + u"upload_date": u"20121212", + u"uploader_id": u"wb", + }, + }, + { + u"file": u"manofsteel-teaser.mov", + u"md5": u"76b392f2ae9e7c98b22913c10a639c97", + u"info_dict": { + u"duration": 93, + u"thumbnail": u"http://trailers.apple.com/trailers/wb/manofsteel/images/thumbnail_6899.jpg", + u"title": u"Teaser", + u"upload_date": u"20120721", + u"uploader_id": u"wb", + }, + } + ] + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + movie = mobj.group('movie') + uploader_id = mobj.group('company') + + playlist_url = url.partition(u'?')[0] + u'/includes/playlists/web.inc' + playlist_snippet = self._download_webpage(playlist_url, movie) + playlist_cleaned = re.sub(r'(?s)<script>.*?</script>', u'', playlist_snippet) + playlist_html = u'<html>' + playlist_cleaned + u'</html>' + + size_cache = {} + + doc = xml.etree.ElementTree.fromstring(playlist_html) + playlist = [] + for li in doc.findall('./div/ul/li'): + title = li.find('.//h3').text + video_id = movie + '-' + re.sub(r'[^a-zA-Z0-9]', '', title).lower() + thumbnail = li.find('.//img').attrib['src'] + + date_el = li.find('.//p') + upload_date = None + m = re.search(r':\s?(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/(?P<year>[0-9]{2})', date_el.text) + if m: + upload_date = u'20' + m.group('year') + m.group('month') + m.group('day') + runtime_el = date_el.find('./br') + m = re.search(r':\s?(?P<minutes>[0-9]+):(?P<seconds>[0-9]{1,2})', runtime_el.tail) + duration = None + if m: + duration = 60 * int(m.group('minutes')) + int(m.group('seconds')) + + formats = [] + for formats_el in li.findall('.//li/a'): + if formats_el.attrib['class'] != 'OverlayPanel': + continue + target = formats_el.attrib['target'] + + format_code = formats_el.text + if 'Automatic' in format_code: + continue + + size_q = formats_el.attrib['href'] + size_id = size_q.rpartition('#videos-')[2] + if size_id not in size_cache: + size_url = url + size_q + sizepage_html = self._download_webpage( + size_url, movie, + note=u'Downloading size info %s' % size_id, + errnote=u'Error while downloading size info %s' % size_id, + ) + _doc = xml.etree.ElementTree.fromstring(sizepage_html) + size_cache[size_id] = _doc + + sizepage_doc = size_cache[size_id] + links = sizepage_doc.findall('.//{http://www.w3.org/1999/xhtml}ul/{http://www.w3.org/1999/xhtml}li/{http://www.w3.org/1999/xhtml}a') + for vid_a in links: + href = vid_a.get('href') + if not href.endswith(target): + continue + detail_q = href.partition('#')[0] + detail_url = url + '/' + detail_q + + m = re.match(r'includes/(?P<detail_id>[^/]+)/', detail_q) + detail_id = m.group('detail_id') + + detail_html = self._download_webpage( + detail_url, movie, + note=u'Downloading detail %s %s' % (detail_id, size_id), + errnote=u'Error while downloading detail %s %s' % (detail_id, size_id) + ) + detail_doc = xml.etree.ElementTree.fromstring(detail_html) + movie_link_el = detail_doc.find('.//{http://www.w3.org/1999/xhtml}a') + assert movie_link_el.get('class') == 'movieLink' + movie_link = movie_link_el.get('href').partition('?')[0].replace('_', '_h') + ext = determine_ext(movie_link) + assert ext == 'mov' + + formats.append({ + 'format': format_code, + 'ext': ext, + 'url': movie_link, + }) + + info = { + '_type': 'video', + 'id': video_id, + 'title': title, + 'formats': formats, + 'title': title, + 'duration': duration, + 'thumbnail': thumbnail, + 'upload_date': upload_date, + 'uploader_id': uploader_id, + 'user_agent': 'QuickTime compatible (youtube-dl)', + } + # TODO: Remove when #980 has been merged + info['url'] = formats[-1]['url'] + info['ext'] = formats[-1]['ext'] + + playlist.append(info) + + return { + '_type': 'playlist', + 'id': movie, + 'entries': playlist, + } From 0e283428f777a23de3c5a522aa283f87cda1b40a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Wed, 28 Aug 2013 10:18:39 +0200 Subject: [PATCH 047/113] HTTPError is in urllib.error in Python 3, not in http.error --- youtube_dl/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index f78b5fe78..e6fa634a7 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -61,7 +61,7 @@ import httplib as compat_http_client try: - from http.error import HTTPError as compat_HTTPError + from urllib.error import HTTPError as compat_HTTPError except ImportError: # Python 2 from urllib2 import HTTPError as compat_HTTPError From a1bb0f8773e0fff787ffe7bd1729073f3385d2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Wed, 28 Aug 2013 10:20:37 +0200 Subject: [PATCH 048/113] [cnn] remove debug print call. --- youtube_dl/extractor/cnn.py | 1 - 1 file changed, 1 deletion(-) diff --git a/youtube_dl/extractor/cnn.py b/youtube_dl/extractor/cnn.py index 4338bd180..a79f881cd 100644 --- a/youtube_dl/extractor/cnn.py +++ b/youtube_dl/extractor/cnn.py @@ -33,7 +33,6 @@ def _real_extract(self, url): path = mobj.group('path') page_title = mobj.group('title') info_url = u'http://cnn.com/video/data/3.0/%s/index.xml' % path - print(info_url) info_xml = self._download_webpage(info_url, page_title) info = xml.etree.ElementTree.fromstring(info_xml.encode('utf-8')) From 3e223834d9f358bc7cb1c3748dc63d1ab40d9b87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Wed, 28 Aug 2013 10:26:44 +0200 Subject: [PATCH 049/113] [youtube] update algo for length 88, thanks to @Ramhack (fixes #1328) --- devscripts/youtube_genalgo.py | 4 ++-- youtube_dl/extractor/youtube.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/devscripts/youtube_genalgo.py b/devscripts/youtube_genalgo.py index 6f1d6ef99..917e8f79d 100644 --- a/devscripts/youtube_genalgo.py +++ b/devscripts/youtube_genalgo.py @@ -14,9 +14,9 @@ # 89 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[]}|:;?/>.<'", "/?;:|}<[{=+-_)(*&^%$#@!MqBVCXZASDFGHJKLPOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuyt"), - # 88 + # 88 - vflapUV9V 2013/08/28 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[]}|:;?/>.<", - "J:|}][{=+-_)(*&;%$#@>MNBVCXZASDFGH^KLPOIUYTREWQ0987654321mnbvcxzasdfghrklpoiuytej"), + "ioplkjhgfdsazxcvbnm12<4567890QWERTYUIOZLKJHGFDSAeXCVBNM!@#$%^&*()_-+={[]}|:;?/>.3"), # 87 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<", "uioplkjhgfdsazxcvbnm1t34567890QWE2TYUIOPLKJHGFDSAZXCVeNM!@#$^&*()_-+={[]}|:;?/>.<"), diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index af01c9da0..8e486afd0 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -419,7 +419,7 @@ def _decrypt_signature(self, s): elif len(s) == 89: return s[84:78:-1] + s[87] + s[77:60:-1] + s[0] + s[59:3:-1] elif len(s) == 88: - return s[48] + s[81:67:-1] + s[82] + s[66:62:-1] + s[85] + s[61:48:-1] + s[67] + s[47:12:-1] + s[3] + s[11:3:-1] + s[2] + s[12] + return s[7:28] + s[87] + s[29:45] + s[55] + s[46:55] + s[2] + s[56:87] + s[28] elif len(s) == 87: return s[6:27] + s[4] + s[28:39] + s[27] + s[40:59] + s[2] + s[60:] elif len(s) == 86: From 4f5f18acb93ea2bf70f80c7f76e6bb6b8dee3fbf Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 10:28:16 +0200 Subject: [PATCH 050/113] [addanime] add file --- youtube_dl/extractor/addanime.py | 76 ++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 youtube_dl/extractor/addanime.py diff --git a/youtube_dl/extractor/addanime.py b/youtube_dl/extractor/addanime.py new file mode 100644 index 000000000..46db8262f --- /dev/null +++ b/youtube_dl/extractor/addanime.py @@ -0,0 +1,76 @@ +import ast +import re + +from .common import InfoExtractor +from ..utils import ( + compat_HTTPError, + compat_str, + compat_urllib_parse, + compat_urllib_parse_urlparse, + + ExtractorError, +) + + +class AddAnimeIE(InfoExtractor): + + _VALID_URL = r'^http://(?:\w+\.)?add-anime\.net/watch_video.php\?(?:.*?)v=(?P<video_id>[\w_]+)(?:.*)' + IE_NAME = u'AddAnime' + _TEST = { + u'url': u'http://www.add-anime.net/watch_video.php?v=24MR3YO5SAS9', + u'file': u'24MR3YO5SAS9.flv', + u'md5': u'1036a0e0cd307b95bd8a8c3a5c8cfaf1', + u'info_dict': { + u"description": u"One Piece 606", + u"title": u"One Piece 606" + } + } + + def _real_extract(self, url): + try: + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('video_id') + webpage = self._download_webpage(url, video_id) + except ExtractorError as ee: + if not isinstance(ee.cause, compat_HTTPError): + raise + + redir_webpage = ee.cause.read().decode('utf-8') + action = self._search_regex( + r'<form id="challenge-form" action="([^"]+)"', + redir_webpage, u'Redirect form') + vc = self._search_regex( + r'<input type="hidden" name="jschl_vc" value="([^"]+)"/>', + redir_webpage, u'redirect vc value') + av = re.search( + r'a\.value = ([0-9]+)[+]([0-9]+)[*]([0-9]+);', + redir_webpage) + if av is None: + raise ExtractorError(u'Cannot find redirect math task') + av_res = int(av.group(1)) + int(av.group(2)) * int(av.group(3)) + + parsed_url = compat_urllib_parse_urlparse(url) + av_val = av_res + len(parsed_url.netloc) + confirm_url = ( + parsed_url.scheme + u'://' + parsed_url.netloc + + action + '?' + + compat_urllib_parse.urlencode({ + 'jschl_vc': vc, 'jschl_answer': compat_str(av_val)})) + self._download_webpage( + confirm_url, video_id, + note=u'Confirming after redirect') + webpage = self._download_webpage(url, video_id) + + video_url = self._search_regex(r"var normal_video_file = '(.*?)';", + webpage, u'video file URL') + video_title = self._og_search_title(webpage) + video_description = self._og_search_description(webpage) + + return { + '_type': 'video', + 'id': video_id, + 'url': video_url, + 'ext': 'flv', + 'title': video_title, + 'description': video_description + } From af8bd6a82d140e5a776185707a9b21d5b8a9fe52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Wed, 28 Aug 2013 10:55:31 +0200 Subject: [PATCH 051/113] Show the time taken to download in the same format as the ETA --- youtube_dl/FileDownloader.py | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/youtube_dl/FileDownloader.py b/youtube_dl/FileDownloader.py index 4f6a23835..7c5ac4bc2 100644 --- a/youtube_dl/FileDownloader.py +++ b/youtube_dl/FileDownloader.py @@ -63,6 +63,17 @@ def format_bytes(bytes): converted = float(bytes) / float(1024 ** exponent) return '%.2f%s' % (converted, suffix) + @staticmethod + def format_seconds(seconds): + (mins, secs) = divmod(seconds, 60) + (hours, eta_mins) = divmod(mins, 60) + if hours > 99: + return '--:--:--' + if hours == 0: + return '%02d:%02d' % (mins, secs) + else: + return '%02d:%02d:%02d' % (hours, mins, secs) + @staticmethod def calc_percent(byte_counter, data_len): if data_len is None: @@ -78,14 +89,7 @@ def calc_eta(start, now, total, current): return '--:--' rate = float(current) / dif eta = int((float(total) - float(current)) / rate) - (eta_mins, eta_secs) = divmod(eta, 60) - (eta_hours, eta_mins) = divmod(eta_mins, 60) - if eta_hours > 99: - return '--:--:--' - if eta_hours == 0: - return '%02d:%02d' % (eta_mins, eta_secs) - else: - return '%02d:%02d:%02d' % (eta_hours, eta_mins, eta_secs) + return FileDownloader.format_seconds(eta) @staticmethod def calc_speed(start, now, bytes): @@ -240,8 +244,8 @@ def report_finish(self, data_len_str, tot_time): self.to_screen(u'[download] Download completed') else: clear_line = (u'\x1b[K' if sys.stderr.isatty() and os.name != 'nt' else u'') - self.to_screen(u'\r%s[download] 100%% of %s in %ss' % - (clear_line, data_len_str, int(tot_time))) + self.to_screen(u'\r%s[download] 100%% of %s in %s' % + (clear_line, data_len_str, self.format_seconds(tot_time))) def _download_with_rtmpdump(self, filename, url, player_url, page_url, play_path, tc_url): self.report_destination(filename) From aa3e950764337ef9800c936f4de89b31c00dfcf5 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 11:57:13 +0200 Subject: [PATCH 052/113] Tolerate junk at the end of gzip-compressed content (#1268) --- youtube_dl/utils.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index e6fa634a7..be788cf5a 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -628,8 +628,23 @@ def http_response(self, req, resp): old_resp = resp # gzip if resp.headers.get('Content-encoding', '') == 'gzip': - gz = gzip.GzipFile(fileobj=io.BytesIO(resp.read()), mode='r') - resp = self.addinfourl_wrapper(gz, old_resp.headers, old_resp.url, old_resp.code) + content = resp.read() + gz = gzip.GzipFile(fileobj=io.BytesIO(content), mode='rb') + try: + uncompressed = io.BytesIO(gz.read()) + except IOError as original_ioerror: + # There may be junk add the end of the file + # See http://stackoverflow.com/q/4928560/35070 for details + for i in range(1, 1024): + try: + gz = gzip.GzipFile(fileobj=io.BytesIO(content[:-i]), mode='rb') + uncompressed = io.BytesIO(gz.read()) + except IOError: + continue + break + else: + raise original_ioerror + resp = self.addinfourl_wrapper(uncompressed, old_resp.headers, old_resp.url, old_resp.code) resp.msg = old_resp.msg # deflate if resp.headers.get('Content-encoding', '') == 'deflate': From ae3531adf926998d42d1fb52453491c85e33b5f0 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 12:04:44 +0200 Subject: [PATCH 053/113] [generic] Fix URL concatenation When the url is something like http://example.org/foo/bar?x=y and the added is file/video.mp4 , we want http://example.org/foo/file/video.mp4 Fixes #1268. --- youtube_dl/extractor/generic.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index d034a11bb..bfc9bff49 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -166,7 +166,12 @@ def _real_extract(self, url): if video_url.startswith('//'): video_url = compat_urllib_parse_urlparse(url).scheme + ':' + video_url if '://' not in video_url: - video_url = url + ('' if url.endswith('/') else '/') + video_url + up = compat_urllib_parse_urlparse(url) + if video_url.startswith('/'): + video_url = up.scheme + '://' + up.netloc + video_url + else: # relative path + video_url = (up.scheme + '://' + up.netloc + + up.path.rpartition('/')[0] + '/' + video_url) video_id = os.path.basename(video_url) # here's a fun little line of code for you: From edde6c56ac20af57d7fd494810834125bbd3728d Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 12:14:45 +0200 Subject: [PATCH 054/113] Print playpath with --get-url (Fixes #1334) --- youtube_dl/YoutubeDL.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 3fc4ec378..d5f7c81eb 100644 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -448,7 +448,8 @@ def process_info(self, info_dict): if self.params.get('forceid', False): compat_print(info_dict['id']) if self.params.get('forceurl', False): - compat_print(info_dict['url']) + # For RTMP URLs, also include the playpath + compat_print(info_dict['url'] + info_dict.get('play_path', u'')) if self.params.get('forcethumbnail', False) and 'thumbnail' in info_dict: compat_print(info_dict['thumbnail']) if self.params.get('forcedescription', False) and 'description' in info_dict: From a5caba1eb02665cdc982d6be4a933aafd79243de Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 12:47:27 +0200 Subject: [PATCH 055/113] [generic] simply use urljoin --- youtube_dl/extractor/generic.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/youtube_dl/extractor/generic.py b/youtube_dl/extractor/generic.py index bfc9bff49..dc4dea4ad 100644 --- a/youtube_dl/extractor/generic.py +++ b/youtube_dl/extractor/generic.py @@ -7,8 +7,8 @@ from ..utils import ( compat_urllib_error, compat_urllib_parse, - compat_urllib_parse_urlparse, compat_urllib_request, + compat_urlparse, ExtractorError, ) @@ -163,15 +163,7 @@ def _real_extract(self, url): raise ExtractorError(u'Invalid URL: %s' % url) video_url = compat_urllib_parse.unquote(mobj.group(1)) - if video_url.startswith('//'): - video_url = compat_urllib_parse_urlparse(url).scheme + ':' + video_url - if '://' not in video_url: - up = compat_urllib_parse_urlparse(url) - if video_url.startswith('/'): - video_url = up.scheme + '://' + up.netloc + video_url - else: # relative path - video_url = (up.scheme + '://' + up.netloc + - up.path.rpartition('/')[0] + '/' + video_url) + video_url = compat_urlparse.urljoin(url, video_url) video_id = os.path.basename(video_url) # here's a fun little line of code for you: From ce6a696e4d964aeb27de46a31a899b28d7ca7754 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 12:47:38 +0200 Subject: [PATCH 056/113] Remove unused imports --- youtube_dl/extractor/addanime.py | 1 - youtube_dl/extractor/appletrailers.py | 1 - youtube_dl/extractor/trilulilu.py | 3 --- youtube_dl/extractor/wat.py | 1 - 4 files changed, 6 deletions(-) diff --git a/youtube_dl/extractor/addanime.py b/youtube_dl/extractor/addanime.py index 46db8262f..82a785a19 100644 --- a/youtube_dl/extractor/addanime.py +++ b/youtube_dl/extractor/addanime.py @@ -1,4 +1,3 @@ -import ast import re from .common import InfoExtractor diff --git a/youtube_dl/extractor/appletrailers.py b/youtube_dl/extractor/appletrailers.py index b3bdb2955..8b191c196 100644 --- a/youtube_dl/extractor/appletrailers.py +++ b/youtube_dl/extractor/appletrailers.py @@ -4,7 +4,6 @@ from .common import InfoExtractor from ..utils import ( determine_ext, - ExtractorError, ) diff --git a/youtube_dl/extractor/trilulilu.py b/youtube_dl/extractor/trilulilu.py index 1c46156c7..f278951ba 100644 --- a/youtube_dl/extractor/trilulilu.py +++ b/youtube_dl/extractor/trilulilu.py @@ -3,9 +3,6 @@ import xml.etree.ElementTree from .common import InfoExtractor -from ..utils import ( - ExtractorError, -) class TriluliluIE(InfoExtractor): diff --git a/youtube_dl/extractor/wat.py b/youtube_dl/extractor/wat.py index 7d228edac..29c25f0e3 100644 --- a/youtube_dl/extractor/wat.py +++ b/youtube_dl/extractor/wat.py @@ -6,7 +6,6 @@ from .common import InfoExtractor from ..utils import ( - compat_urllib_parse, unified_strdate, ) From 67b22dd03686d9e360d87a7751de74b321d3f231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Wed, 28 Aug 2013 12:51:22 +0200 Subject: [PATCH 057/113] Add extractors for video.mit.edu and techtv.mit.edu (closes #1327) video.mit.edu just embeds the videos from techtv.mit.edu --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/mit.py | 76 ++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 youtube_dl/extractor/mit.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index c76b99a81..21e9e5d37 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -50,6 +50,7 @@ from .liveleak import LiveLeakIE from .livestream import LivestreamIE from .metacafe import MetacafeIE +from .mit import TechTVMITIE, MITIE from .mixcloud import MixcloudIE from .mtv import MTVIE from .muzu import MuzuTVIE diff --git a/youtube_dl/extractor/mit.py b/youtube_dl/extractor/mit.py new file mode 100644 index 000000000..d09d03e36 --- /dev/null +++ b/youtube_dl/extractor/mit.py @@ -0,0 +1,76 @@ +import re +import json + +from .common import InfoExtractor +from ..utils import ( + clean_html, + get_element_by_id, +) + + +class TechTVMITIE(InfoExtractor): + IE_NAME = u'techtv.mit.edu' + _VALID_URL = r'https?://techtv\.mit\.edu/(videos|embeds)/(?P<id>\d+)' + + _TEST = { + u'url': u'http://techtv.mit.edu/videos/25418-mit-dna-learning-center-set', + u'file': u'25418.mp4', + u'md5': u'1f8cb3e170d41fd74add04d3c9330e5f', + u'info_dict': { + u'title': u'MIT DNA Learning Center Set', + u'description': u'md5:82313335e8a8a3f243351ba55bc1b474', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + webpage = self._download_webpage( + 'http://techtv.mit.edu/videos/%s' % video_id, video_id) + embed_page = self._download_webpage( + 'http://techtv.mit.edu/embeds/%s/' % video_id, video_id, + note=u'Downloading embed page') + + base_url = self._search_regex(r'ipadUrl: \'(.+?cloudfront.net/)', + embed_page, u'base url') + formats_json = self._search_regex(r'bitrates: (\[.+?\])', embed_page, + u'video formats') + formats = json.loads(formats_json) + formats = sorted(formats, key=lambda f: f['bitrate']) + + title = get_element_by_id('edit-title', webpage) + description = clean_html(get_element_by_id('edit-description', webpage)) + thumbnail = self._search_regex(r'playlist:.*?url: \'(.+?)\'', + embed_page, u'thumbnail', flags=re.DOTALL) + + return {'id': video_id, + 'title': title, + 'url': base_url + formats[-1]['url'].replace('mp4:', ''), + 'ext': 'mp4', + 'description': description, + 'thumbnail': thumbnail, + } + + +class MITIE(TechTVMITIE): + IE_NAME = u'video.mit.edu' + _VALID_URL = r'https?://video\.mit\.edu/watch/(?P<title>[^/]+)' + + _TEST = { + u'url': u'http://video.mit.edu/watch/the-government-is-profiling-you-13222/', + u'file': u'21783.mp4', + u'md5': u'7db01d5ccc1895fc5010e9c9e13648da', + u'info_dict': { + u'title': u'The Government is Profiling You', + u'description': u'md5:ad5795fe1e1623b73620dbfd47df9afd', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + page_title = mobj.group('title') + webpage = self._download_webpage(url, page_title) + self.to_screen('%s: Extracting %s url' % (page_title, TechTVMITIE.IE_NAME)) + embed_url = self._search_regex(r'<iframe .*?src="(.+?)"', webpage, + u'embed url') + return self.url_result(embed_url, ie='TechTVMIT') From c496ca96e7639e5dd0020074b7ada18c2bd4ae3e Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 12:57:10 +0200 Subject: [PATCH 058/113] Fix platform name in Python 2 with --verbose (Closes #1228) --- youtube_dl/__init__.py | 3 ++- youtube_dl/utils.py | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index bc6a6d180..b33a18a26 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -45,6 +45,7 @@ import warnings import platform + from .utils import * from .update import update_self from .version import __version__ @@ -611,7 +612,7 @@ def _real_main(argv=None): sys.exc_clear() except: pass - sys.stderr.write(u'[debug] Python version %s - %s' %(platform.python_version(), platform.platform()) + u'\n') + sys.stderr.write(u'[debug] Python version %s - %s' %(platform.python_version(), platform_name()) + u'\n') sys.stderr.write(u'[debug] Proxy map: ' + str(proxy_handler.proxies) + u'\n') ydl.add_default_info_extractors() diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index be788cf5a..64ab30910 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -1,19 +1,20 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import datetime +import email.utils import errno import gzip import io import json import locale import os +import platform import re +import socket import sys import traceback import zlib -import email.utils -import socket -import datetime try: import urllib.request as compat_urllib_request @@ -732,3 +733,13 @@ def __contains__(self, date): return self.start <= date <= self.end def __str__(self): return '%s - %s' % ( self.start.isoformat(), self.end.isoformat()) + + +def platform_name(): + """ Returns the platform name as a compat_str """ + res = platform.platform() + if isinstance(res, bytes): + res = res.decode(preferredencoding()) + + assert isinstance(res, compat_str) + return res From 8ae97d76eee1bf9e9098797db3be2d7b816196b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= <jaime.marquinez.ferrandiz@gmail.com> Date: Wed, 28 Aug 2013 13:37:31 +0200 Subject: [PATCH 059/113] PostProcessingError holds the message in the 'msg' property, not in 'message' (fixes #1323) Causes DeprecationWarning: http://www.python.org/dev/peps/pep-0352/ --- youtube_dl/PostProcessor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/youtube_dl/PostProcessor.py b/youtube_dl/PostProcessor.py index c02ed7148..ae56d2082 100644 --- a/youtube_dl/PostProcessor.py +++ b/youtube_dl/PostProcessor.py @@ -137,7 +137,7 @@ def run_ffmpeg(self, path, out_path, codec, more_opts): try: FFmpegPostProcessor.run_ffmpeg(self, path, out_path, opts) except FFmpegPostProcessorError as err: - raise AudioConversionError(err.message) + raise AudioConversionError(err.msg) def run(self, information): path = information['filepath'] @@ -207,7 +207,7 @@ def run(self, information): except: etype,e,tb = sys.exc_info() if isinstance(e, AudioConversionError): - msg = u'audio conversion failed: ' + e.message + msg = u'audio conversion failed: ' + e.msg else: msg = u'error running ' + (self._exes['avconv'] and 'avconv' or 'ffmpeg') raise PostProcessingError(msg) From f143d86ad2fc0633d8e2da598cf21e73ff0f2872 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister <phihag@phihag.de> Date: Wed, 28 Aug 2013 13:59:08 +0200 Subject: [PATCH 060/113] [sohu] Handle encoding, and fix tests --- youtube_dl/extractor/common.py | 9 ++- youtube_dl/extractor/sohu.py | 133 ++++++++++++++++----------------- 2 files changed, 72 insertions(+), 70 deletions(-) diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index 77a13aea5..a2986cebe 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -145,12 +145,17 @@ def _download_webpage_handle(self, url_or_request, video_id, note=None, errnote= urlh = self._request_webpage(url_or_request, video_id, note, errnote) content_type = urlh.headers.get('Content-Type', '') + webpage_bytes = urlh.read() m = re.match(r'[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+\s*;\s*charset=(.+)', content_type) if m: encoding = m.group(1) else: - encoding = 'utf-8' - webpage_bytes = urlh.read() + m = re.search(br'<meta[^>]+charset="?([^"]+)[ /">]', + webpage_bytes[:1024]) + if m: + encoding = m.group(1).decode('ascii') + else: + encoding = 'utf-8' if self._downloader.params.get('dump_intermediate_pages', False): try: url = url_or_request.get_full_url() diff --git a/youtube_dl/extractor/sohu.py b/youtube_dl/extractor/sohu.py index 24fc3a5d7..77bb0a8dc 100644 --- a/youtube_dl/extractor/sohu.py +++ b/youtube_dl/extractor/sohu.py @@ -1,13 +1,10 @@ # encoding: utf-8 -import re import json -import time -import logging -import urllib2 +import re from .common import InfoExtractor -from ..utils import compat_urllib_request, clean_html +from ..utils import ExtractorError class SohuIE(InfoExtractor): @@ -15,79 +12,79 @@ class SohuIE(InfoExtractor): _TEST = { u'url': u'http://tv.sohu.com/20130724/n382479172.shtml#super', - u'file': u'382479172.flv', - u'md5': u'cc84eed6b6fbf0f2f9a8d3cb9da1939b', + u'file': u'382479172.mp4', + u'md5': u'bde8d9a6ffd82c63a1eefaef4eeefec7', u'info_dict': { - u'title': u'The Illest - Far East Movement Riff Raff', + u'title': u'MV:Far East Movement《The Illest》', }, } - def _real_extract(self, url): + + def _fetch_data(vid_id): + base_data_url = u'http://hot.vrs.sohu.com/vrs_flash.action?vid=' + data_url = base_data_url + str(vid_id) + data_json = self._download_webpage( + data_url, video_id, + note=u'Downloading JSON data for ' + str(vid_id)) + return json.loads(data_json) + mobj = re.match(self._VALID_URL, url) video_id = mobj.group('id') - webpage = self._download_webpage(url, video_id) - pattern = r'<title>(.+?)' - compiled = re.compile(pattern, re.DOTALL) - title = self._search_regex(compiled, webpage, u'video title') - title = clean_html(title).split('-')[0].strip() - self.to_screen('Title: %s' % title) - pattern = re.compile(r'var vid="(\d+)"') - result = re.search(pattern, webpage) - if not result: - logging.info('[Sohu] could not get vid') - return None - vid = result.group(1) - logging.info('vid: %s' % vid) - base_url_1 = 'http://hot.vrs.sohu.com/vrs_flash.action?vid=' - url_1 = base_url_1 + vid - logging.info('json url: %s' % url_1) - webpage = self._download_webpage(url_1, vid) - json_1 = json.loads(webpage) - # get the highest definition video vid and json infomation. - vids = [] - qualities = ('oriVid', 'superVid', 'highVid', 'norVid') - for vid_name in qualities: - vids.append(json_1['data'][vid_name]) - clearest_vid = 0 - for i, v in enumerate(vids): - if v != 0: - clearest_vid = v - logging.info('quality definition: %s' % qualities[i][:-3]) - break - if not clearest_vid: - logging.warning('could not find valid clearest_vid') - return None - if vid != clearest_vid: - url_1 = '%s%d' % (base_url_1, clearest_vid) - logging.info('highest definition json url: %s' % url_1) - json_1 = json.loads(urllib2.urlopen(url_1).read()) - allot = json_1['allot'] - prot = json_1['prot'] - clipsURL = json_1['data']['clipsURL'] - su = json_1['data']['su'] - num_of_parts = json_1['data']['totalBlocks'] - logging.info('Total parts: %d' % num_of_parts) - base_url_3 = 'http://allot/?prot=prot&file=clipsURL[i]&new=su[i]' - files_info = [] - for i in range(num_of_parts): - self.to_screen('Geting json infomation of part %s/%s' % (i + 1, num_of_parts)) - middle_url = 'http://%s/?prot=%s&file=%s&new=%s' % (allot, prot, clipsURL[i], su[i]) - logging.info('middle url part %d: %s' % (i, middle_url)) - middle_info = urllib2.urlopen(middle_url).read().split('|') - middle_part_1 = middle_info[0] - download_url = '%s%s?key=%s' % (middle_info[0], su[i], middle_info[3]) - info = { + webpage = self._download_webpage(url, video_id) + raw_title = self._html_search_regex(r'(?s)(.+?)', + webpage, u'video title') + title = raw_title.partition('-')[0].strip() + + vid = self._html_search_regex(r'var vid="(\d+)"', webpage, + u'video path') + data = _fetch_data(vid) + + QUALITIES = ('ori', 'super', 'high', 'nor') + vid_ids = [data['data'][q + 'Vid'] + for q in QUALITIES + if data['data'][q + 'Vid'] != 0] + if not vid_ids: + raise ExtractorError(u'No formats available for this video') + + # For now, we just pick the highest available quality + vid_id = vid_ids[-1] + + format_data = data if vid == vid_id else _fetch_data(vid_id) + part_count = format_data['data']['totalBlocks'] + allot = format_data['allot'] + prot = format_data['prot'] + clipsURL = format_data['data']['clipsURL'] + su = format_data['data']['su'] + + playlist = [] + for i in range(part_count): + part_url = ('http://%s/?prot=%s&file=%s&new=%s' % + (allot, prot, clipsURL[i], su[i])) + part_str = self._download_webpage( + part_url, video_id, + note=u'Downloading part %d of %d' % (i+1, part_count)) + + part_info = part_str.split('|') + video_url = '%s%s?key=%s' % (part_info[0], su[i], part_info[3]) + + video_info = { 'id': '%s_part%02d' % (video_id, i + 1), 'title': title, - 'url': download_url, + 'url': video_url, 'ext': 'mp4', } - files_info.append(info) - time.sleep(1) - if num_of_parts == 1: - info = files_info[0] + playlist.append(video_info) + + if len(playlist) == 1: + info = playlist[0] info['id'] = video_id - return info - return files_info + else: + info = { + '_type': 'playlist', + 'entries': playlist, + 'id': video_id, + } + + return info From 48ea9cea77e7ea24ee867027f03ca37dd1b935d8 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Wed, 28 Aug 2013 14:28:55 +0200 Subject: [PATCH 061/113] Allow changes to run under Python 3 --- youtube_dl/aes.py | 18 ++++++++++-------- youtube_dl/extractor/youporn.py | 12 ++++++++---- youtube_dl/utils.py | 10 ++++++++++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/youtube_dl/aes.py b/youtube_dl/aes.py index 2fa9238e3..278f8bb82 100644 --- a/youtube_dl/aes.py +++ b/youtube_dl/aes.py @@ -3,6 +3,8 @@ import base64 from math import ceil +from .utils import bytes_to_intlist + BLOCK_SIZE_BYTES = 16 def aes_ctr_decrypt(data, key, counter): @@ -16,7 +18,7 @@ def aes_ctr_decrypt(data, key, counter): @returns {int[]} decrypted data """ expanded_key = key_expansion(key) - block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES)) + block_count = int(ceil(float(len(data)) // BLOCK_SIZE_BYTES)) decrypted_data=[] for i in range(block_count): @@ -40,7 +42,7 @@ def key_expansion(data): data = data[:] # copy rcon_iteration = 1 key_size_bytes = len(data) - expanded_key_size_bytes = (key_size_bytes/4 + 7) * BLOCK_SIZE_BYTES + expanded_key_size_bytes = (key_size_bytes // 4 + 7) * BLOCK_SIZE_BYTES while len(data) < expanded_key_size_bytes: temp = data[-4:] @@ -72,7 +74,7 @@ def aes_encrypt(data, expanded_key): @param {int[]} expanded_key 176/208/240-Byte expanded key @returns {int[]} 16-Byte cipher """ - rounds = len(expanded_key) / BLOCK_SIZE_BYTES - 1 + rounds = len(expanded_key) // BLOCK_SIZE_BYTES - 1 data = xor(data, expanded_key[:BLOCK_SIZE_BYTES]) for i in range(1, rounds+1): @@ -99,11 +101,11 @@ def aes_decrypt_text(data, password, key_size_bytes): """ NONCE_LENGTH_BYTES = 8 - data = map(lambda c: ord(c), base64.b64decode(data)) - password = map(lambda c: ord(c), password.encode('utf-8')) + data = bytes_to_intlist(base64.b64decode(data)) + password = bytes_to_intlist(password.encode('utf-8')) key = password[:key_size_bytes] + [0]*(key_size_bytes - len(password)) - key = aes_encrypt(key[:BLOCK_SIZE_BYTES], key_expansion(key)) * (key_size_bytes / BLOCK_SIZE_BYTES) + key = aes_encrypt(key[:BLOCK_SIZE_BYTES], key_expansion(key)) * (key_size_bytes // BLOCK_SIZE_BYTES) nonce = data[:NONCE_LENGTH_BYTES] cipher = data[NONCE_LENGTH_BYTES:] @@ -143,7 +145,7 @@ def next_value(self): (3,1,1,2)) def sub_bytes(data): - return map(lambda x: SBOX[x], data) + return [SBOX[x] for x in data] def rotate(data): return data[1:] + [data[0]] @@ -156,7 +158,7 @@ def key_schedule_core(data, rcon_iteration): return data def xor(data1, data2): - return map(lambda (x,y): x^y, zip(data1, data2)) + return [x^y for x, y in zip(data1, data2)] def mix_column(data): data_mixed = [] diff --git a/youtube_dl/extractor/youporn.py b/youtube_dl/extractor/youporn.py index cc9c37027..19360e273 100644 --- a/youtube_dl/extractor/youporn.py +++ b/youtube_dl/extractor/youporn.py @@ -5,6 +5,7 @@ from .common import InfoExtractor from ..utils import ( + compat_str, compat_urllib_parse_urlparse, compat_urllib_request, @@ -79,13 +80,16 @@ def _real_extract(self, url): links = re.findall(LINK_RE, download_list_html) # Get link of hd video - encrypted_video_url = self._html_search_regex(r'var encryptedURL = \'(?P[a-zA-Z0-9+/]+={0,2})\';', + encrypted_video_url = self._html_search_regex( + r'var encrypted(?:Quality[0-9]+)?URL = \'(?P[a-zA-Z0-9+/]+={0,2})\';', webpage, u'encrypted_video_url') - video_url = unicode( aes_decrypt_text(encrypted_video_url, video_title, 32), 'utf-8') + video_url = aes_decrypt_text(encrypted_video_url, video_title, 32) + print(video_url) + assert isinstance(video_url, compat_str) if video_url.split('/')[6].split('_')[0] == u'720p': # only add if 720p to avoid duplicates links = [video_url] + links - if(len(links) == 0): + if not links: raise ExtractorError(u'ERROR: no known formats available for video') self.to_screen(u'Links found: %d' % len(links)) @@ -122,7 +126,7 @@ def _real_extract(self, url): self._print_formats(formats) return - req_format = self._downloader.params.get('format', None) + req_format = self._downloader.params.get('format', 'best') self.to_screen(u'Format: %s' % req_format) if req_format is None or req_format == 'best': diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 59eeaf4a8..07b40da6c 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -708,3 +708,13 @@ def __contains__(self, date): return self.start <= date <= self.end def __str__(self): return '%s - %s' % ( self.start.isoformat(), self.end.isoformat()) + + +def bytes_to_intlist(bs): + if not bs: + return [] + if isinstance(bs[0], int): # Python 3 + return list(bs) + else: + return [ord(c) for c in bs] + From 920ef0779b6bcd5131e237e5c2ca28361f6d45d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Sat, 20 Jul 2013 12:49:24 +0200 Subject: [PATCH 062/113] Hide the password and username in verbose mode (closes #1089) --- youtube_dl/__init__.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index b33a18a26..431460c57 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -100,6 +100,16 @@ def _find_term_columns(): pass return None + def _hide_login_info(opts): + opts = list(opts) + for private_opt in ['-p', '--password', '-u', '--username']: + try: + i = opts.index(private_opt) + opts[i+1] = '' + except ValueError: + pass + return opts + max_width = 80 max_help_position = 80 @@ -358,9 +368,9 @@ def _find_term_columns(): argv = systemConf + userConf + commandLineConf opts, args = parser.parse_args(argv) if opts.verbose: - sys.stderr.write(u'[debug] System config: ' + repr(systemConf) + '\n') - sys.stderr.write(u'[debug] User config: ' + repr(userConf) + '\n') - sys.stderr.write(u'[debug] Command-line args: ' + repr(commandLineConf) + '\n') + sys.stderr.write(u'[debug] System config: ' + repr(_hide_login_info(systemConf)) + '\n') + sys.stderr.write(u'[debug] User config: ' + repr(_hide_login_info(userConf)) + '\n') + sys.stderr.write(u'[debug] Command-line args: ' + repr(_hide_login_info(commandLineConf)) + '\n') return parser, opts, args From cba892fa1fd6a7f1278e637c338921c5ae236840 Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Wed, 28 Aug 2013 15:59:07 +0200 Subject: [PATCH 063/113] Add intlist_to_bytes to utils.py --- youtube_dl/utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index 07b40da6c..ee8df6a5b 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -718,3 +718,10 @@ def bytes_to_intlist(bs): else: return [ord(c) for c in bs] +def intlist_to_bytes(xs): + if not xs: + return b'' + if isinstance(chr(0), bytes): # Python 2 + return ''.join([chr(x) for x in xs]) + else: + return bytes(xs) From 6e74bc41ca07bda56107cfff9ceb98d6f8d28e53 Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Wed, 28 Aug 2013 16:01:43 +0200 Subject: [PATCH 064/113] Fix division bug in aes.py --- youtube_dl/aes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/aes.py b/youtube_dl/aes.py index 278f8bb82..9913d59a4 100644 --- a/youtube_dl/aes.py +++ b/youtube_dl/aes.py @@ -18,7 +18,7 @@ def aes_ctr_decrypt(data, key, counter): @returns {int[]} decrypted data """ expanded_key = key_expansion(key) - block_count = int(ceil(float(len(data)) // BLOCK_SIZE_BYTES)) + block_count = int(ceil(float(len(data)) / BLOCK_SIZE_BYTES)) decrypted_data=[] for i in range(block_count): From 0012690aae977d76e9162e2334989498366a8e94 Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Wed, 28 Aug 2013 16:03:35 +0200 Subject: [PATCH 065/113] Let aes_decrypt_text return bytes instead of unicode --- youtube_dl/aes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/youtube_dl/aes.py b/youtube_dl/aes.py index 9913d59a4..9a0c93fa6 100644 --- a/youtube_dl/aes.py +++ b/youtube_dl/aes.py @@ -3,7 +3,7 @@ import base64 from math import ceil -from .utils import bytes_to_intlist +from .utils import bytes_to_intlist, intlist_to_bytes BLOCK_SIZE_BYTES = 16 @@ -118,7 +118,7 @@ def next_value(self): return temp decrypted_data = aes_ctr_decrypt(cipher, key, Counter()) - plaintext = ''.join(map(lambda x: chr(x), decrypted_data)) + plaintext = intlist_to_bytes(decrypted_data) return plaintext From 878e83c5a4c84c7abbf3484366e76fbe906c8947 Mon Sep 17 00:00:00 2001 From: rzhxeo Date: Wed, 28 Aug 2013 16:04:48 +0200 Subject: [PATCH 066/113] YoupornIE: Clean up extraction of hd video --- youtube_dl/extractor/youporn.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/youtube_dl/extractor/youporn.py b/youtube_dl/extractor/youporn.py index 19360e273..c85fd4b5a 100644 --- a/youtube_dl/extractor/youporn.py +++ b/youtube_dl/extractor/youporn.py @@ -5,7 +5,6 @@ from .common import InfoExtractor from ..utils import ( - compat_str, compat_urllib_parse_urlparse, compat_urllib_request, @@ -79,14 +78,11 @@ def _real_extract(self, url): LINK_RE = r'(?s)' links = re.findall(LINK_RE, download_list_html) - # Get link of hd video - encrypted_video_url = self._html_search_regex( - r'var encrypted(?:Quality[0-9]+)?URL = \'(?P[a-zA-Z0-9+/]+={0,2})\';', - webpage, u'encrypted_video_url') - video_url = aes_decrypt_text(encrypted_video_url, video_title, 32) - print(video_url) - assert isinstance(video_url, compat_str) - if video_url.split('/')[6].split('_')[0] == u'720p': # only add if 720p to avoid duplicates + # Get link of hd video if available + mobj = re.search(r'var encryptedQuality720URL = \'(?P[a-zA-Z0-9+/]+={0,2})\';', webpage) + if mobj != None: + encrypted_video_url = mobj.group(u'encrypted_video_url') + video_url = aes_decrypt_text(encrypted_video_url, video_title, 32).decode('utf-8') links = [video_url] + links if not links: From 2891932bf0a01acc025246438f890dca57f91c6b Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Wed, 28 Aug 2013 19:00:17 +0200 Subject: [PATCH 067/113] release 2013.08.28.1 --- youtube_dl/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 0b56e48dc..2ba75258d 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.08.28' +__version__ = '2013.08.28.1' From b5ba7b9dcfed5ded96c841a0ebbbf12132de838f Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Wed, 28 Aug 2013 14:00:59 -0500 Subject: [PATCH 068/113] Fix MIT extractor for Python 2.6 The HTML for the MIT page does not parse cleanly for Python 2.6 due to script tags within an actual script element. The offending piece is inside a comment block, so removing all such comment blocks fixes the parsing. --- youtube_dl/extractor/mit.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/youtube_dl/extractor/mit.py b/youtube_dl/extractor/mit.py index d09d03e36..52be9232f 100644 --- a/youtube_dl/extractor/mit.py +++ b/youtube_dl/extractor/mit.py @@ -25,23 +25,21 @@ class TechTVMITIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) video_id = mobj.group('id') - webpage = self._download_webpage( + raw_page = self._download_webpage( 'http://techtv.mit.edu/videos/%s' % video_id, video_id) - embed_page = self._download_webpage( - 'http://techtv.mit.edu/embeds/%s/' % video_id, video_id, - note=u'Downloading embed page') + clean_page = re.compile(u'', re.S).sub(u'', raw_page) base_url = self._search_regex(r'ipadUrl: \'(.+?cloudfront.net/)', - embed_page, u'base url') - formats_json = self._search_regex(r'bitrates: (\[.+?\])', embed_page, + raw_page, u'base url') + formats_json = self._search_regex(r'bitrates: (\[.+?\])', raw_page, u'video formats') formats = json.loads(formats_json) formats = sorted(formats, key=lambda f: f['bitrate']) - title = get_element_by_id('edit-title', webpage) - description = clean_html(get_element_by_id('edit-description', webpage)) + title = get_element_by_id('edit-title', clean_page) + description = clean_html(get_element_by_id('edit-description', clean_page)) thumbnail = self._search_regex(r'playlist:.*?url: \'(.+?)\'', - embed_page, u'thumbnail', flags=re.DOTALL) + raw_page, u'thumbnail', flags=re.DOTALL) return {'id': video_id, 'title': title, From 0d75ae2ce313c5738b2bdd9602ab3cc15e78810d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 29 Aug 2013 11:35:15 +0200 Subject: [PATCH 069/113] Fix detection of the webpage charset if it's declared using ' instead of " Like in "" --- youtube_dl/extractor/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index a2986cebe..77726ee24 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -150,7 +150,7 @@ def _download_webpage_handle(self, url_or_request, video_id, note=None, errnote= if m: encoding = m.group(1) else: - m = re.search(br']+charset="?([^"]+)[ /">]', + m = re.search(br']+charset=[\'"]?([^\'")]+)[ /\'">]', webpage_bytes[:1024]) if m: encoding = m.group(1).decode('ascii') From b7052e508787e49aa1e141a15f16284bbf1f634b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 29 Aug 2013 12:15:45 +0200 Subject: [PATCH 070/113] Also print the field that fails if it is a md5 checksum --- test/test_download.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/test/test_download.py b/test/test_download.py index 21cb2e694..23a66254d 100644 --- a/test/test_download.py +++ b/test/test_download.py @@ -127,12 +127,11 @@ def _hook(status): info_dict = json.load(infof) for (info_field, expected) in tc.get('info_dict', {}).items(): if isinstance(expected, compat_str) and expected.startswith('md5:'): - self.assertEqual(expected, 'md5:' + md5(info_dict.get(info_field))) + got = 'md5:' + md5(info_dict.get(info_field)) else: got = info_dict.get(info_field) - self.assertEqual( - expected, got, - u'invalid value for field %s, expected %r, got %r' % (info_field, expected, got)) + self.assertEqual(expected, got, + u'invalid value for field %s, expected %r, got %r' % (info_field, expected, got)) # If checkable fields are missing from the test case, print the info_dict test_info_dict = dict((key, value if not isinstance(value, compat_str) or len(value) < 250 else 'md5:' + md5(value)) From c7bf7366bc0d4d1c4fc9c81ee5d33bf3c3512aa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 29 Aug 2013 13:41:59 +0200 Subject: [PATCH 071/113] Update descriptions checksum for some test for Unistra and Youtube --- youtube_dl/extractor/unistra.py | 2 +- youtube_dl/extractor/youtube.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/youtube_dl/extractor/unistra.py b/youtube_dl/extractor/unistra.py index 5ba0a9061..516e18914 100644 --- a/youtube_dl/extractor/unistra.py +++ b/youtube_dl/extractor/unistra.py @@ -11,7 +11,7 @@ class UnistraIE(InfoExtractor): u'md5': u'736f605cfdc96724d55bb543ab3ced24', u'info_dict': { u'title': u'M!ss Yella', - u'description': u'md5:75e8439a3e2981cd5d4b6db232e8fdfc', + u'description': u'md5:104892c71bd48e55d70b902736b81bbf', }, } diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 8e486afd0..4038af256 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -335,7 +335,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): 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:b085c9804f5ab69f4adea963a2dceb3c", + u"description": u"md5:3e2666e0a55044490499ea45fe9037b7", u"uploader": u"Icona Pop", u"uploader_id": u"IconaPop" } From 545434670b7b055a7f0ff82b76ee7acbb3d07dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 29 Aug 2013 19:16:07 +0200 Subject: [PATCH 072/113] Add an extractor for orf.at (closes #1346) Make find_xpath_attr also accept numbers in the value --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/orf.py | 65 ++++++++++++++++++++++++++++++++ youtube_dl/utils.py | 2 +- 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 youtube_dl/extractor/orf.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 6b5037c8c..90f1a4418 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -59,6 +59,7 @@ from .nba import NBAIE from .nbc import NBCNewsIE from .ooyala import OoyalaIE +from .orf import ORFIE from .pbs import PBSIE from .photobucket import PhotobucketIE from .pornotube import PornotubeIE diff --git a/youtube_dl/extractor/orf.py b/youtube_dl/extractor/orf.py new file mode 100644 index 000000000..8da0a2c8e --- /dev/null +++ b/youtube_dl/extractor/orf.py @@ -0,0 +1,65 @@ +import re +import xml.etree.ElementTree +import json + +from .common import InfoExtractor +from ..utils import ( + compat_urlparse, + ExtractorError, + find_xpath_attr, +) + +class ORFIE(InfoExtractor): + _VALID_URL = r'https?://tvthek.orf.at/(programs/.+?/episodes|topics/.+?)/(?P\d+)' + + _TEST = { + u'url': u'http://tvthek.orf.at/programs/1171769-Wetter-ZIB/episodes/6557323-Wetter', + u'file': u'6566957.flv', + u'info_dict': { + u'title': u'Wetter', + u'description': u'Christa Kummer, Marcus Wadsak und Kollegen präsentieren abwechselnd ihre täglichen Wetterprognosen für Österreich.\r \r Mehr Wetter unter wetter.ORF.at', + }, + u'params': { + # It uses rtmp + u'skip_download': True, + } + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + playlist_id = mobj.group('id') + webpage = self._download_webpage(url, playlist_id) + + flash_xml = self._search_regex('ORF.flashXML = \'(.+?)\'', webpage, u'flash xml') + flash_xml = compat_urlparse.parse_qs('xml='+flash_xml)['xml'][0] + flash_config = xml.etree.ElementTree.fromstring(flash_xml.encode('utf-8')) + playlist_json = self._search_regex(r'playlist\': \'(\[.*?\])\'', webpage, u'playlist').replace(r'\"','"') + playlist = json.loads(playlist_json) + + videos = [] + ns = '{http://tempuri.org/XMLSchema.xsd}' + xpath = '%(ns)sPlaylist/%(ns)sItems/%(ns)sItem' % {'ns': ns} + webpage_description = self._og_search_description(webpage) + for (i, (item, info)) in enumerate(zip(flash_config.findall(xpath), playlist), 1): + # Get best quality url + rtmp_url = None + for q in ['Q6A', 'Q4A', 'Q1A']: + video_url = find_xpath_attr(item, '%sVideoUrl' % ns, 'quality', q) + if video_url is not None: + rtmp_url = video_url.text + break + if rtmp_url is None: + raise ExtractorError(u'Couldn\'t get video url: %s' % info['id']) + description = self._html_search_regex( + r'id="playlist_entry_%s".*?

(.*?)

' % i, webpage, + u'description', default=webpage_description, flags=re.DOTALL) + videos.append({ + '_type': 'video', + 'id': info['id'], + 'title': info['title'], + 'url': rtmp_url, + 'ext': 'flv', + 'description': description, + }) + + return videos diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index b3d0f64ea..201802cee 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -213,7 +213,7 @@ def write_json_file(obj, fn): def find_xpath_attr(node, xpath, key, val): """ Find the xpath xpath[@key=val] """ assert re.match(r'^[a-zA-Z]+$', key) - assert re.match(r'^[a-zA-Z@\s]*$', val) + assert re.match(r'^[a-zA-Z0-9@\s]*$', val) expr = xpath + u"[@%s='%s']" % (key, val) return node.find(expr) else: From 8928491074095ec4da84be9c7d5ff4f1c0f98400 Mon Sep 17 00:00:00 2001 From: Jeff Smith Date: Thu, 29 Aug 2013 12:51:38 -0500 Subject: [PATCH 073/113] Fix orf.at extractor by adding file coding mark --- youtube_dl/extractor/orf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/youtube_dl/extractor/orf.py b/youtube_dl/extractor/orf.py index 8da0a2c8e..41ef8e992 100644 --- a/youtube_dl/extractor/orf.py +++ b/youtube_dl/extractor/orf.py @@ -1,3 +1,5 @@ +# coding: utf-8 + import re import xml.etree.ElementTree import json From f1fb2d12b32910c641f27096e585513c5f97f9ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 29 Aug 2013 21:39:36 +0200 Subject: [PATCH 074/113] [ign] extract videos from articles pages --- youtube_dl/extractor/ign.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/youtube_dl/extractor/ign.py b/youtube_dl/extractor/ign.py index 62abab655..263959716 100644 --- a/youtube_dl/extractor/ign.py +++ b/youtube_dl/extractor/ign.py @@ -13,7 +13,7 @@ class IGNIE(InfoExtractor): Some videos of it.ign.com are also supported """ - _VALID_URL = r'https?://.+?\.ign\.com/(?:videos|show_videos)(/.+)?/(?P.+)' + _VALID_URL = r'https?://.+?\.ign\.com/(?Pvideos|show_videos|articles)(/.+)?/(?P.+)' IE_NAME = u'ign.com' _CONFIG_URL_TEMPLATE = 'http://www.ign.com/videos/configs/id/%s.config' @@ -41,7 +41,11 @@ def _find_video_id(self, webpage): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) name_or_id = mobj.group('name_or_id') + page_type = mobj.group('type') webpage = self._download_webpage(url, name_or_id) + if page_type == 'articles': + video_url = self._search_regex(r'var videoUrl = "(.+?)"', webpage, u'video url') + return self.url_result(video_url, ie='IGN') video_id = self._find_video_id(webpage) result = self._get_video_info(video_id) description = self._html_search_regex(self._DESCRIPTION_RE, From ee80d66727d7b194e595fa7e0c19c40cc4adb408 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 29 Aug 2013 21:51:09 +0200 Subject: [PATCH 075/113] [ign] update 1up extractor to work with the updated IGNIE --- youtube_dl/extractor/ign.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/extractor/ign.py b/youtube_dl/extractor/ign.py index 263959716..b1c84278a 100644 --- a/youtube_dl/extractor/ign.py +++ b/youtube_dl/extractor/ign.py @@ -72,7 +72,7 @@ def _get_video_info(self, video_id): class OneUPIE(IGNIE): """Extractor for 1up.com, it uses the ign videos system.""" - _VALID_URL = r'https?://gamevideos.1up.com/video/id/(?P.+)' + _VALID_URL = r'https?://gamevideos.1up.com/(?Pvideo)/id/(?P.+)' IE_NAME = '1up.com' _DESCRIPTION_RE = r'
(.+?)
' From 52e1eea18bae4771137abd888830036c40b6eaa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 29 Aug 2013 22:33:58 +0200 Subject: [PATCH 076/113] [youtube] update algo for length 86 (fixes #1349) --- devscripts/youtube_genalgo.py | 4 ++-- youtube_dl/extractor/youtube.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/devscripts/youtube_genalgo.py b/devscripts/youtube_genalgo.py index 917e8f79d..b06416e93 100644 --- a/devscripts/youtube_genalgo.py +++ b/devscripts/youtube_genalgo.py @@ -20,9 +20,9 @@ # 87 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<", "uioplkjhgfdsazxcvbnm1t34567890QWE2TYUIOPLKJHGFDSAZXCVeNM!@#$^&*()_-+={[]}|:;?/>.<"), - # 86 - vflh9ybst 2013/08/23 + # 86 - vflg0g8PQ 2013/08/29 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<", - "yuioplkjhgfdsazxcvbnm1234567890QWERrYUIOPLKqHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<"), + ">/?;}|[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWq0987654321mnbvcxzasdfghjklpoiuytr"), # 85 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<", ".>/?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWQ0q876543r1mnbvcx9asdfghjklpoiuyt2"), diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 4038af256..3a07df027 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -423,7 +423,7 @@ def _decrypt_signature(self, s): elif len(s) == 87: return s[6:27] + s[4] + s[28:39] + s[27] + s[40:59] + s[2] + s[60:] elif len(s) == 86: - return s[5:40] + s[3] + s[41:48] + s[0] + s[49:86] + return s[83:36:-1] + s[0] + s[35:2:-1] elif len(s) == 85: return s[83:34:-1] + s[0] + s[33:27:-1] + s[3] + s[26:19:-1] + s[34] + s[18:3:-1] + s[27] elif len(s) == 84: From 23b00bc0e4ae7d85876409fad59d95ce29b00d82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 29 Aug 2013 22:44:29 +0200 Subject: [PATCH 077/113] [youtube] update algo for length 84 Only appears sometimes, nearly identical to length 86. --- devscripts/youtube_genalgo.py | 4 ++-- youtube_dl/extractor/youtube.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/devscripts/youtube_genalgo.py b/devscripts/youtube_genalgo.py index b06416e93..13df535c7 100644 --- a/devscripts/youtube_genalgo.py +++ b/devscripts/youtube_genalgo.py @@ -26,9 +26,9 @@ # 85 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<", ".>/?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWQ0q876543r1mnbvcx9asdfghjklpoiuyt2"), - # 84 - vflh9ybst 2013/08/23 (sporadic) + # 84 - vflg0g8PQ 2013/08/29 (sporadic) ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?>.<", - "yuioplkjhgfdsazxcvbnm1234567890QWERrYUIOPLKqHGFDSAZXCVBNM!@#$%^&*()_-+={[};?>.<"), + ">?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWq0987654321mnbvcxzasdfghjklpoiuytr"), # 83 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!#$%^&*()_+={[};?/>.<", ".>/?;}[{=+_)(*&^%<#!MNBVCXZASPFGHJKLwOIUYTREWQ0987654321mnbvcxzasdfghjklpoiuytreq"), diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 3a07df027..9e2373bd5 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -427,7 +427,7 @@ def _decrypt_signature(self, s): elif len(s) == 85: return s[83:34:-1] + s[0] + s[33:27:-1] + s[3] + s[26:19:-1] + s[34] + s[18:3:-1] + s[27] elif len(s) == 84: - return s[5:40] + s[3] + s[41:48] + s[0] + s[49:84] + return s[81:36:-1] + s[0] + s[35:2:-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: From 3243d0f7b669128c91c64816a9ca3502ae4e4094 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Thu, 29 Aug 2013 23:29:34 +0200 Subject: [PATCH 078/113] release 2013.08.29 --- youtube_dl/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/version.py b/youtube_dl/version.py index 2ba75258d..c28320181 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.08.28.1' +__version__ = '2013.08.29' From 9193c1eededf996378307a0c60bb1e7eeaa1b9da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Fri, 30 Aug 2013 20:11:53 +0200 Subject: [PATCH 079/113] Add youtube keywords to the bash completion script --- devscripts/bash-completion.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/devscripts/bash-completion.in b/devscripts/bash-completion.in index 3b99a9614..bd10f63c2 100644 --- a/devscripts/bash-completion.in +++ b/devscripts/bash-completion.in @@ -4,8 +4,12 @@ __youtube-dl() COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" opts="{{flags}}" + keywords=":ytfavorites :ytrecommended :ytsubscriptions :ytwatchlater" - if [[ ${cur} == * ]] ; then + if [[ ${cur} =~ : ]]; then + COMPREPLY=( $(compgen -W "${keywords}" -- ${cur}) ) + return 0 + elif [[ ${cur} == * ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) return 0 fi From c7a7750d3b825e3f7aa9cd3617a76d2f56c1387d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Fri, 30 Aug 2013 20:13:05 +0200 Subject: [PATCH 080/113] [youtube] Fix typo in the _VALID_URL for YoutubeFavouritesIE, it was intended to also match :ytfavourites --- youtube_dl/extractor/youtube.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 9e2373bd5..00e2b320a 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -1161,7 +1161,7 @@ class YoutubeWatchLaterIE(YoutubeFeedsInfoExtractor): class YoutubeFavouritesIE(YoutubeBaseInfoExtractor): IE_NAME = u'youtube:favorites' IE_DESC = u'YouTube.com favourite videos, "ytfav" keyword (requires authentication)' - _VALID_URL = r'https?://www\.youtube\.com/my_favorites|:ytfav(?:o?rites)?' + _VALID_URL = r'https?://www\.youtube\.com/my_favorites|:ytfav(?:ou?rites)?' _LOGIN_REQUIRED = True def _real_extract(self, url): From 2e756879f156139c68c3557bc65a7ab1ac31137d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Fri, 30 Aug 2013 20:49:51 +0200 Subject: [PATCH 081/113] [youtube] update algo for length 86 --- devscripts/youtube_genalgo.py | 4 ++-- youtube_dl/extractor/youtube.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/devscripts/youtube_genalgo.py b/devscripts/youtube_genalgo.py index 13df535c7..97a0d7290 100644 --- a/devscripts/youtube_genalgo.py +++ b/devscripts/youtube_genalgo.py @@ -20,9 +20,9 @@ # 87 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$^&*()_-+={[]}|:;?/>.<", "uioplkjhgfdsazxcvbnm1t34567890QWE2TYUIOPLKJHGFDSAZXCVeNM!@#$^&*()_-+={[]}|:;?/>.<"), - # 86 - vflg0g8PQ 2013/08/29 + # 86 - vflHOr_nV 2013/08/30 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[|};?/>.<", - ">/?;}|[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWq0987654321mnbvcxzasdfghjklpoiuytr"), + "?;}|[{=+._)(*&^%$#@!MNBqCXZASDFGHJKLPOIUYTREWQ<987654321mnbvcxzasdfghjklpoiuytrew"), # 85 ("qwertyuioplkjhgfdsazxcvbnm1234567890QWERTYUIOPLKJHGFDSAZXCVBNM!@#$%^&*()_-+={[};?/>.<", ".>/?;}[{=+-_)(*&^%$#@!MNBVCXZASDFGHJKLPOIUYTREWQ0q876543r1mnbvcx9asdfghjklpoiuyt2"), diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 00e2b320a..810ce6f5d 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -423,7 +423,7 @@ def _decrypt_signature(self, s): elif len(s) == 87: return s[6:27] + s[4] + s[28:39] + s[27] + s[40:59] + s[2] + s[60:] elif len(s) == 86: - return s[83:36:-1] + s[0] + s[35:2:-1] + return s[81:73:-1] + s[84] + s[72:58:-1] + s[0] + s[57:35:-1] + s[85] + s[34:0:-1] elif len(s) == 85: return s[83:34:-1] + s[0] + s[33:27:-1] + s[3] + s[26:19:-1] + s[34] + s[18:3:-1] + s[27] elif len(s) == 84: From 10f5c016ec6262e5d29327e97fe4f3d1127ccdff Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Fri, 30 Aug 2013 21:02:07 +0200 Subject: [PATCH 082/113] release 2013.08.30 --- youtube_dl/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/version.py b/youtube_dl/version.py index c28320181..b6284c6d6 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.08.29' +__version__ = '2013.08.30' From bdc6b3fc64a03045b8130cdc824ee3f6c15eeff1 Mon Sep 17 00:00:00 2001 From: Allan Zhou Date: Fri, 30 Aug 2013 17:51:50 -0700 Subject: [PATCH 083/113] add support for "-f mp4" for YouTube --- youtube_dl/__init__.py | 2 +- youtube_dl/extractor/youtube.py | 37 ++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index 431460c57..b6b12683f 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -192,7 +192,7 @@ def _hide_login_info(opts): video_format.add_option('-f', '--format', action='store', dest='format', metavar='FORMAT', - help='video format code, specifiy the order of preference using slashes: "-f 22/17/18"') + help='video format code, specifiy the order of preference using slashes: "-f 22/17/18". "-f mp4" and "-f flv" are also supported') video_format.add_option('--all-formats', action='store_const', dest='format', help='download all available video formats', const='all') video_format.add_option('--prefer-free-formats', diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index 8e486afd0..bd2b986ce 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -153,8 +153,9 @@ class YoutubeIE(YoutubeBaseInfoExtractor): $""" _NEXT_URL_RE = r'[\?&]next_url=([^&]+)' # Listed in order of quality - _available_formats = ['38', '37', '46', '22', '45', '35', '44', '34', '18', '43', '6', '5', '17', '13', - '95', '94', '93', '92', '132', '151', + _available_formats = ['38', '37', '46', '22', '45', '35', '44', '34', '18', '43', '6', '5', '36', '17', '13', + # AHLS + '96', '95', '94', '93', '92', '132', '151', # 3D '85', '84', '102', '83', '101', '82', '100', # Dash video @@ -163,8 +164,10 @@ class YoutubeIE(YoutubeBaseInfoExtractor): # Dash audio '141', '172', '140', '171', '139', ] - _available_formats_prefer_free = ['38', '46', '37', '45', '22', '44', '35', '43', '34', '18', '6', '5', '17', '13', - '95', '94', '93', '92', '132', '151', + _available_formats_prefer_free = ['38', '46', '37', '45', '22', '44', '35', '43', '34', '18', '6', '5', '36', '17', '13', + # AHLS + '96', '95', '94', '93', '92', '132', '151', + # 3D '85', '102', '84', '101', '83', '100', '82', # Dash video '138', '248', '137', '247', '136', '246', '245', @@ -172,11 +175,18 @@ class YoutubeIE(YoutubeBaseInfoExtractor): # Dash audio '172', '141', '171', '140', '139', ] + _video_formats_map = { + 'flv': ['35', '34', '6', '5'], + '3gp': ['36', '17', '13'], + 'mp4': ['38', '37', '22', '18'], + 'webm': ['46', '45', '44', '43'], + } _video_extensions = { '13': '3gp', - '17': 'mp4', + '17': '3gp', '18': 'mp4', '22': 'mp4', + '36': '3gp', '37': 'mp4', '38': 'mp4', '43': 'webm', @@ -193,7 +203,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): '101': 'webm', '102': 'webm', - # videos that use m3u8 + # AHLS '92': 'mp4', '93': 'mp4', '94': 'mp4', @@ -234,6 +244,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): '22': '720x1280', '34': '360x640', '35': '480x854', + '36': '240x320', '37': '1080x1920', '38': '3072x4096', '43': '360x640', @@ -597,13 +608,25 @@ def _get_video_url_list(self, url_map): video_url_list = [(f, url_map[f]) for f in existing_formats] # All formats else: # Specific formats. We pick the first in a slash-delimeted sequence. - # For example, if '1/2/3/4' is requested and '2' and '4' are available, we pick '2'. + # Format can be specified as itag or 'mp4' or 'flv' etc. We pick the highest quality + # available in the specified format. For example, + # if '1/2/3/4' is requested and '2' and '4' are available, we pick '2'. + # if '1/mp4/3/4' is requested and '1' and '5' (is a mp4) are available, we pick '1'. + # if '1/mp4/3/4' is requested and '4' and '5' (is a mp4) are available, we pick '5'. req_formats = req_format.split('/') video_url_list = None for rf in req_formats: if rf in url_map: video_url_list = [(rf, url_map[rf])] break + if rf in self._video_formats_map: + for srf in self._video_formats_map[rf]: + if srf in url_map: + video_url_list = [(srf, url_map[srf])] + break + else: + continue + break if video_url_list is None: raise ExtractorError(u'requested format not available') return video_url_list From 691008087b902fa731a8f4f840c1821c93505840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Sat, 31 Aug 2013 15:05:59 +0200 Subject: [PATCH 084/113] Add an automatic page generator for the supported sites (related #156) They are listed in the "supportedsites.html" page. --- devscripts/gh-pages/update-sites.py | 33 +++++++++++++++++++++++++++++ devscripts/release.sh | 1 + 2 files changed, 34 insertions(+) create mode 100755 devscripts/gh-pages/update-sites.py diff --git a/devscripts/gh-pages/update-sites.py b/devscripts/gh-pages/update-sites.py new file mode 100755 index 000000000..fa4bb2beb --- /dev/null +++ b/devscripts/gh-pages/update-sites.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +import sys +import os +import textwrap + +# We must be able to import youtube_dl +sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) + +import youtube_dl + +def main(): + with open('supportedsites.html.in', 'r', encoding='utf-8') as tmplf: + template = tmplf.read() + + ie_htmls = [] + for ie in sorted(youtube_dl.gen_extractors(), key=lambda i: i.IE_NAME): + ie_html = '{}'.format(ie.IE_NAME) + try: + ie_html += ': {}'.format(ie.IE_DESC) + except AttributeError: + pass + if ie.working() == False: + ie_html += ' (Currently broken)' + ie_htmls.append('
  • {}
  • '.format(ie_html)) + + template = template.replace('@SITES@', textwrap.indent('\n'.join(ie_htmls), '\t')) + + with open('supportedsites.html', 'w', encoding='utf-8') as sitesf: + sitesf.write(template) + +if __name__ == '__main__': + main() diff --git a/devscripts/release.sh b/devscripts/release.sh index 24c9ad8d8..62c68a6cf 100755 --- a/devscripts/release.sh +++ b/devscripts/release.sh @@ -85,6 +85,7 @@ ROOT=$(pwd) "$ROOT/devscripts/gh-pages/sign-versions.py" < "$ROOT/updates_key.pem" "$ROOT/devscripts/gh-pages/generate-download.py" "$ROOT/devscripts/gh-pages/update-copyright.py" + "$ROOT/devscripts/gh-pages/update-sites.py" git add *.html *.html.in update git commit -m "release $version" git show HEAD From 6c758d79de48956b90d9e78aec695ee0b10b00d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Sat, 31 Aug 2013 22:35:39 +0200 Subject: [PATCH 085/113] [metacafe] Add more cases for detecting the uploader detection (reported in #1343) --- youtube_dl/extractor/metacafe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/youtube_dl/extractor/metacafe.py b/youtube_dl/extractor/metacafe.py index e38dc98b4..e537648ff 100644 --- a/youtube_dl/extractor/metacafe.py +++ b/youtube_dl/extractor/metacafe.py @@ -122,7 +122,7 @@ def _real_extract(self, url): video_title = self._html_search_regex(r'(?im)(.*) - Video', webpage, u'title') description = self._og_search_description(webpage) video_uploader = self._html_search_regex( - r'submitter=(.*?);|googletag\.pubads\(\)\.setTargeting\("channel","([^"]+)"\);', + r'submitter=(.*?);|googletag\.pubads\(\)\.setTargeting\("(?:channel|submiter)","([^"]+)"\);', webpage, u'uploader nickname', fatal=False) return { From 8e4e89f1c236e1bec38c5363c1c341930056211e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Mon, 2 Sep 2013 11:54:09 +0200 Subject: [PATCH 086/113] Add an extractor for VeeHD (closes #1359) --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/veehd.py | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 youtube_dl/extractor/veehd.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 90f1a4418..9f56e427c 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -89,6 +89,7 @@ from .unistra import UnistraIE from .ustream import UstreamIE from .vbox7 import Vbox7IE +from .veehd import VeeHDIE from .veoh import VeohIE from .vevo import VevoIE from .videofyme import VideofyMeIE diff --git a/youtube_dl/extractor/veehd.py b/youtube_dl/extractor/veehd.py new file mode 100644 index 000000000..3a99a29c6 --- /dev/null +++ b/youtube_dl/extractor/veehd.py @@ -0,0 +1,56 @@ +import re +import json + +from .common import InfoExtractor +from ..utils import ( + compat_urlparse, + get_element_by_id, + clean_html, +) + +class VeeHDIE(InfoExtractor): + _VALID_URL = r'https?://veehd.com/video/(?P\d+)' + + _TEST = { + u'url': u'http://veehd.com/video/4686958', + u'file': u'4686958.mp4', + u'info_dict': { + u'title': u'Time Lapse View from Space ( ISS)', + u'uploader_id': u'spotted', + u'description': u'md5:f0094c4cf3a72e22bc4e4239ef767ad7', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group('id') + + webpage = self._download_webpage(url, video_id) + player_path = self._search_regex(r'\$\("#playeriframe"\).attr\({src : "(.+?)"', + webpage, u'player path') + player_url = compat_urlparse.urljoin(url, player_path) + player_page = self._download_webpage(player_url, video_id, + u'Downloading player page') + config_json = self._search_regex(r'value=\'config=({.+?})\'', + player_page, u'config json') + config = json.loads(config_json) + + video_url = compat_urlparse.unquote(config['clip']['url']) + title = clean_html(get_element_by_id('videoName', webpage).rpartition('|')[0]) + uploader_id = self._html_search_regex(r'
    (.+?)', + webpage, u'uploader') + thumbnail = self._search_regex(r'(.*?) Date: Tue, 3 Sep 2013 01:51:17 +0200 Subject: [PATCH 087/113] Extractor for defense.gouv.fr --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/defense.py | 37 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 youtube_dl/extractor/defense.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 9f56e427c..a96b62d37 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -21,6 +21,7 @@ from .depositfiles import DepositFilesIE from .dotsub import DotsubIE from .dreisat import DreiSatIE +from .defense import DefenseGouvFrIE from .ehow import EHowIE from .eighttracks import EightTracksIE from .escapist import EscapistIE diff --git a/youtube_dl/extractor/defense.py b/youtube_dl/extractor/defense.py new file mode 100644 index 000000000..963fb897f --- /dev/null +++ b/youtube_dl/extractor/defense.py @@ -0,0 +1,37 @@ +# coding: utf-8 +'''Extractor for defense.gouv.fr''' +import re +import json + +from .common import InfoExtractor + + +class DefenseGouvFrIE(InfoExtractor): + '''Extractor for defense.gouv.fr''' + _IE_NAME = 'defense.gouv.fr' + _VALID_URL = (r'http://.*?\.defense\.gouv\.fr/layout/set/' + 'ligthboxvideo/base-de-medias/webtv/(.*)') + + _TEST = { + u'url': (u'http://www.defense.gouv.fr/layout/set/ligthboxvideo/', + 'base-de-medias/webtv/attaque-chimique-syrienne-du-21-aout-2013-1') + } + + def _real_extract(self, url): + title = re.match(self._VALID_URL, url).group(1) + webpage = self._download_webpage(url, title) + video_id = self._search_regex( + r"flashvars.pvg_id=\"(\d+)\";", + webpage, 'ID') + + json_url = ('http://static.videos.gouv.fr/brightcovehub/export/json/' + + video_id) + info = self._download_webpage(json_url, title, + 'Downloading JSON config') + video_url = json.loads(info)['renditions'][0]['url'] + + return {'id': video_id, + 'ext': 'mp4', + 'url': video_url, + 'title': title, + } From aa32314d09cf0ab3fad1efc2c5657e6704a7e47b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Tue, 3 Sep 2013 10:48:56 +0200 Subject: [PATCH 088/113] [vimeo] add support for videos that embed the download url in the player page (fixes #1364) --- youtube_dl/extractor/vimeo.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/youtube_dl/extractor/vimeo.py b/youtube_dl/extractor/vimeo.py index 512e06e2a..dee4175ef 100644 --- a/youtube_dl/extractor/vimeo.py +++ b/youtube_dl/extractor/vimeo.py @@ -44,6 +44,16 @@ class VimeoIE(InfoExtractor): u'title': u'Andy Allan - Putting the Carto into OpenStreetMap Cartography', }, }, + { + u'url': u'http://player.vimeo.com/video/54469442', + u'file': u'54469442.mp4', + u'md5': u'619b811a4417aa4abe78dc653becf511', + u'note': u'Videos that embed the url in the player page', + u'info_dict': { + u'title': u'Kathy Sierra: Building the minimum Badass User, Business of Software', + u'uploader': u'The BLN & Business of Software', + }, + }, ] def _login(self): @@ -112,7 +122,8 @@ def _real_extract(self, url, new_video=True): # Extract the config JSON try: - config = webpage.split(' = {config:')[1].split(',assets:')[0] + config = self._search_regex([r' = {config:({.+?}),assets:', r'c=({.+?);'], + webpage, u'info section', flags=re.DOTALL) config = json.loads(config) except: if re.search('The creator of this video has not given you permission to embed it on this domain.', webpage): @@ -132,7 +143,9 @@ def _real_extract(self, url, new_video=True): video_uploader_id = config["video"]["owner"]["url"].split('/')[-1] if config["video"]["owner"]["url"] else None # Extract video thumbnail - video_thumbnail = config["video"]["thumbnail"] + video_thumbnail = config["video"].get("thumbnail") + if video_thumbnail is None: + _, video_thumbnail = sorted((int(width), t_url) for (width, t_url) in config["video"]["thumbs"].items())[-1] # Extract video description video_description = get_element_by_attribute("itemprop", "description", webpage) @@ -154,14 +167,15 @@ def _real_extract(self, url, new_video=True): # TODO bind to format param codecs = [('h264', 'mp4'), ('vp8', 'flv'), ('vp6', 'flv')] files = { 'hd': [], 'sd': [], 'other': []} + config_files = config["video"].get("files") or config["request"].get("files") for codec_name, codec_extension in codecs: - if codec_name in config["video"]["files"]: - if 'hd' in config["video"]["files"][codec_name]: + if codec_name in config_files: + if 'hd' in config_files[codec_name]: files['hd'].append((codec_name, codec_extension, 'hd')) - elif 'sd' in config["video"]["files"][codec_name]: + elif 'sd' in config_files[codec_name]: files['sd'].append((codec_name, codec_extension, 'sd')) else: - files['other'].append((codec_name, codec_extension, config["video"]["files"][codec_name][0])) + files['other'].append((codec_name, codec_extension, config_files[codec_name][0])) for quality in ('hd', 'sd', 'other'): if len(files[quality]) > 0: @@ -173,8 +187,12 @@ def _real_extract(self, url, new_video=True): else: raise ExtractorError(u'No known codec found') - video_url = "http://player.vimeo.com/play_redirect?clip_id=%s&sig=%s&time=%s&quality=%s&codecs=%s&type=moogaloop_local&embed_location=" \ - %(video_id, sig, timestamp, video_quality, video_codec.upper()) + video_url = None + if isinstance(config_files[video_codec], dict): + video_url = config_files[video_codec][video_quality].get("url") + if video_url is None: + video_url = "http://player.vimeo.com/play_redirect?clip_id=%s&sig=%s&time=%s&quality=%s&codecs=%s&type=moogaloop_local&embed_location=" \ + %(video_id, sig, timestamp, video_quality, video_codec.upper()) return [{ 'id': video_id, From 9c2ade40de53bae865c5267642651c81d16e48a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Tue, 3 Sep 2013 11:11:36 +0200 Subject: [PATCH 089/113] [vimeo] Handle Assertions Error when trying to get the description In some pages the html tags are not closed, python 2.6 cannot handle it. --- youtube_dl/extractor/vimeo.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/youtube_dl/extractor/vimeo.py b/youtube_dl/extractor/vimeo.py index dee4175ef..4a7d82b7a 100644 --- a/youtube_dl/extractor/vimeo.py +++ b/youtube_dl/extractor/vimeo.py @@ -148,9 +148,17 @@ def _real_extract(self, url, new_video=True): _, video_thumbnail = sorted((int(width), t_url) for (width, t_url) in config["video"]["thumbs"].items())[-1] # Extract video description - video_description = get_element_by_attribute("itemprop", "description", webpage) - if video_description: video_description = clean_html(video_description) - else: video_description = u'' + video_description = None + try: + video_description = get_element_by_attribute("itemprop", "description", webpage) + if video_description: video_description = clean_html(video_description) + except AssertionError as err: + # On some pages like (http://player.vimeo.com/video/54469442) the + # html tags are not closed, python 2.6 cannot handle it + if err.args[0] == 'we should not get here!': + pass + else: + raise # Extract upload date video_upload_date = None From 4ff7a0f1f6e6b1ad1743330d318dfe85806923b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Tue, 3 Sep 2013 11:33:59 +0200 Subject: [PATCH 090/113] [dailymotion] improve the regex for extracting the video info --- youtube_dl/extractor/dailymotion.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/youtube_dl/extractor/dailymotion.py b/youtube_dl/extractor/dailymotion.py index 1ea449ca8..439033d23 100644 --- a/youtube_dl/extractor/dailymotion.py +++ b/youtube_dl/extractor/dailymotion.py @@ -55,7 +55,8 @@ def _real_extract(self, url): embed_url = 'http://www.dailymotion.com/embed/video/%s' % video_id embed_page = self._download_webpage(embed_url, video_id, u'Downloading embed page') - info = self._search_regex(r'var info = ({.*?}),', embed_page, 'video info') + info = self._search_regex(r'var info = ({.*?}),$', embed_page, + 'video info', flags=re.MULTILINE) info = json.loads(info) # TODO: support choosing qualities From c8dbccde30d9ca06d4c9305329a9aacd10420276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Tue, 3 Sep 2013 11:51:01 +0200 Subject: [PATCH 091/113] [orf] Remove the test video, they seem to expire in one week --- youtube_dl/extractor/orf.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/youtube_dl/extractor/orf.py b/youtube_dl/extractor/orf.py index 41ef8e992..cfca2a063 100644 --- a/youtube_dl/extractor/orf.py +++ b/youtube_dl/extractor/orf.py @@ -14,19 +14,6 @@ class ORFIE(InfoExtractor): _VALID_URL = r'https?://tvthek.orf.at/(programs/.+?/episodes|topics/.+?)/(?P\d+)' - _TEST = { - u'url': u'http://tvthek.orf.at/programs/1171769-Wetter-ZIB/episodes/6557323-Wetter', - u'file': u'6566957.flv', - u'info_dict': { - u'title': u'Wetter', - u'description': u'Christa Kummer, Marcus Wadsak und Kollegen präsentieren abwechselnd ihre täglichen Wetterprognosen für Österreich.\r \r Mehr Wetter unter wetter.ORF.at', - }, - u'params': { - # It uses rtmp - u'skip_download': True, - } - } - def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) playlist_id = mobj.group('id') From 025171c47641a47cc2a4e4ed52c7a04b465e0e5d Mon Sep 17 00:00:00 2001 From: Pierre Rudloff Date: Tue, 3 Sep 2013 12:03:19 +0200 Subject: [PATCH 092/113] Suggested by @phihag --- youtube_dl/extractor/defense.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/youtube_dl/extractor/defense.py b/youtube_dl/extractor/defense.py index 963fb897f..424d960da 100644 --- a/youtube_dl/extractor/defense.py +++ b/youtube_dl/extractor/defense.py @@ -1,5 +1,3 @@ -# coding: utf-8 -'''Extractor for defense.gouv.fr''' import re import json @@ -7,14 +5,18 @@ class DefenseGouvFrIE(InfoExtractor): - '''Extractor for defense.gouv.fr''' _IE_NAME = 'defense.gouv.fr' _VALID_URL = (r'http://.*?\.defense\.gouv\.fr/layout/set/' - 'ligthboxvideo/base-de-medias/webtv/(.*)') + r'ligthboxvideo/base-de-medias/webtv/(.*)') _TEST = { - u'url': (u'http://www.defense.gouv.fr/layout/set/ligthboxvideo/', - 'base-de-medias/webtv/attaque-chimique-syrienne-du-21-aout-2013-1') + u'url': (u'http://www.defense.gouv.fr/layout/set/ligthboxvideo/' + u'base-de-medias/webtv/attaque-chimique-syrienne-du-21-aout-2013-1'), + u'file': u'11213.mp4', + u'md5': u'75bba6124da7e63d2d60b5244ec9430c', + "info_dict": { + "title": "attaque-chimique-syrienne-du-21-aout-2013-1" + } } def _real_extract(self, url): From 96fb5605b29c5029ab2894b5722c0937e320a3c0 Mon Sep 17 00:00:00 2001 From: Allan Zhou Date: Tue, 3 Sep 2013 18:49:35 -0700 Subject: [PATCH 093/113] AHLS -> Apple HTTP Live Streaming --- youtube_dl/extractor/youtube.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/youtube_dl/extractor/youtube.py b/youtube_dl/extractor/youtube.py index d331aa01b..01265ca28 100644 --- a/youtube_dl/extractor/youtube.py +++ b/youtube_dl/extractor/youtube.py @@ -154,7 +154,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): _NEXT_URL_RE = r'[\?&]next_url=([^&]+)' # Listed in order of quality _available_formats = ['38', '37', '46', '22', '45', '35', '44', '34', '18', '43', '6', '5', '36', '17', '13', - # AHLS + # Apple HTTP Live Streaming '96', '95', '94', '93', '92', '132', '151', # 3D '85', '84', '102', '83', '101', '82', '100', @@ -165,7 +165,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): '141', '172', '140', '171', '139', ] _available_formats_prefer_free = ['38', '46', '37', '45', '22', '44', '35', '43', '34', '18', '6', '5', '36', '17', '13', - # AHLS + # Apple HTTP Live Streaming '96', '95', '94', '93', '92', '132', '151', # 3D '85', '102', '84', '101', '83', '100', '82', @@ -203,7 +203,7 @@ class YoutubeIE(YoutubeBaseInfoExtractor): '101': 'webm', '102': 'webm', - # AHLS + # Apple HTTP Live Streaming '92': 'mp4', '93': 'mp4', '94': 'mp4', From 08523ee20a57e7ac28d895165f3b759b311e8495 Mon Sep 17 00:00:00 2001 From: Philipp Hagemeister Date: Wed, 4 Sep 2013 14:33:32 +0200 Subject: [PATCH 094/113] release 2013.09.04 --- README.md | 3 ++- youtube_dl/version.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 75068fe56..2776cb3eb 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,8 @@ ## Verbosity / Simulation Options: ## Video Format Options: -f, --format FORMAT video format code, specifiy the order of - preference using slashes: "-f 22/17/18" + preference using slashes: "-f 22/17/18". "-f mp4" + and "-f flv" are also supported --all-formats download all available video formats --prefer-free-formats prefer free video formats unless a specific one is requested diff --git a/youtube_dl/version.py b/youtube_dl/version.py index b6284c6d6..5d7467699 100644 --- a/youtube_dl/version.py +++ b/youtube_dl/version.py @@ -1,2 +1,2 @@ -__version__ = '2013.08.30' +__version__ = '2013.09.04' From 150f20828be552763dddce1c45b9a4e642cff599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Wed, 4 Sep 2013 22:06:50 +0200 Subject: [PATCH 095/113] Add extractor for daum.net (closes #1330) --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/daum.py | 71 ++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 youtube_dl/extractor/daum.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index a96b62d37..caef53b73 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -18,6 +18,7 @@ from .criterion import CriterionIE from .cspan import CSpanIE from .dailymotion import DailymotionIE, DailymotionPlaylistIE +from .daum import DaumIE from .depositfiles import DepositFilesIE from .dotsub import DotsubIE from .dreisat import DreiSatIE diff --git a/youtube_dl/extractor/daum.py b/youtube_dl/extractor/daum.py new file mode 100644 index 000000000..9b4566999 --- /dev/null +++ b/youtube_dl/extractor/daum.py @@ -0,0 +1,71 @@ +# encoding: utf-8 +import re +import xml.etree.ElementTree + +from .common import InfoExtractor +from ..utils import ( + compat_urllib_parse, + determine_ext, +) + + +class DaumIE(InfoExtractor): + _VALID_URL = r'https?://tvpot\.daum\.net/.*?clipid=(?P\d+)' + IE_NAME = u'daum.net' + + _TEST = { + u'url': u'http://tvpot.daum.net/clip/ClipView.do?clipid=52554690', + u'file': u'52554690.mp4', + u'info_dict': { + u'title': u'DOTA 2GETHER 시즌2 6회 - 2부', + u'upload_date': u'20130831', + u'duration': 3868, + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group(1) + webpage = self._download_webpage(url, video_id) + full_id = self._search_regex(r' Date: Wed, 4 Sep 2013 22:09:22 +0200 Subject: [PATCH 096/113] Credit @Huarong for tv.sohu.com --- youtube_dl/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index b6b12683f..4213ec1d5 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -28,6 +28,7 @@ 'Axel Noack', 'Albert Kim', 'Pierre Rudloff', + 'Huarong Huo', ) __license__ = 'Public Domain' From 9363169b67a7837bdd157939a896bd38b350f634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 5 Sep 2013 10:08:17 +0200 Subject: [PATCH 097/113] [daum] Get the video page from a canonical url to extract the full id (fixes #1373) and extract description. --- youtube_dl/extractor/daum.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/youtube_dl/extractor/daum.py b/youtube_dl/extractor/daum.py index 9b4566999..a804e83bd 100644 --- a/youtube_dl/extractor/daum.py +++ b/youtube_dl/extractor/daum.py @@ -18,6 +18,7 @@ class DaumIE(InfoExtractor): u'file': u'52554690.mp4', u'info_dict': { u'title': u'DOTA 2GETHER 시즌2 6회 - 2부', + u'description': u'DOTA 2GETHER 시즌2 6회 - 2부', u'upload_date': u'20130831', u'duration': 3868, }, @@ -26,7 +27,8 @@ class DaumIE(InfoExtractor): def _real_extract(self, url): mobj = re.match(self._VALID_URL, url) video_id = mobj.group(1) - webpage = self._download_webpage(url, video_id) + canonical_url = 'http://tvpot.daum.net/v/%s' % video_id + webpage = self._download_webpage(canonical_url, video_id) full_id = self._search_regex(r' Date: Thu, 5 Sep 2013 10:53:40 +0200 Subject: [PATCH 098/113] Add extractor for tvcast.naver.com (closes #1331) --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/naver.py | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 youtube_dl/extractor/naver.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index caef53b73..70ebd29e2 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -58,6 +58,7 @@ from .muzu import MuzuTVIE from .myspass import MySpassIE from .myvideo import MyVideoIE +from .naver import NaverIE from .nba import NBAIE from .nbc import NBCNewsIE from .ooyala import OoyalaIE diff --git a/youtube_dl/extractor/naver.py b/youtube_dl/extractor/naver.py new file mode 100644 index 000000000..9df236d69 --- /dev/null +++ b/youtube_dl/extractor/naver.py @@ -0,0 +1,73 @@ +# encoding: utf-8 +import re +import xml.etree.ElementTree + +from .common import InfoExtractor +from ..utils import ( + compat_urllib_parse, + ExtractorError, +) + + +class NaverIE(InfoExtractor): + _VALID_URL = r'https?://tvcast\.naver\.com/v/(?P\d+)' + + _TEST = { + u'url': u'http://tvcast.naver.com/v/81652', + u'file': u'81652.mp4', + u'info_dict': { + u'title': u'[9월 모의고사 해설강의][수학_김상희] 수학 A형 16~20번', + u'description': u'합격불변의 법칙 메가스터디 | 메가스터디 수학 김상희 선생님이 9월 모의고사 수학A형 16번에서 20번까지 해설강의를 공개합니다.', + u'upload_date': u'20130903', + }, + } + + def _real_extract(self, url): + mobj = re.match(self._VALID_URL, url) + video_id = mobj.group(1) + webpage = self._download_webpage(url, video_id) + m_id = re.search(r'var rmcPlayer = new nhn.rmcnmv.RMCVideoPlayer\("(.+?)", "(.+?)"', + webpage) + if m_id is None: + raise ExtractorError(u'couldn\'t extract vid and key') + vid = m_id.group(1) + key = m_id.group(2) + query = compat_urllib_parse.urlencode({'vid': vid, 'inKey': key,}) + query_urls = compat_urllib_parse.urlencode({ + 'masterVid': vid, + 'protocol': 'p2p', + 'inKey': key, + }) + info_xml = self._download_webpage( + 'http://serviceapi.rmcnmv.naver.com/flash/videoInfo.nhn?' + query, + video_id, u'Downloading video info') + urls_xml = self._download_webpage( + 'http://serviceapi.rmcnmv.naver.com/flash/playableEncodingOption.nhn?' + query_urls, + video_id, u'Downloading video formats info') + info = xml.etree.ElementTree.fromstring(info_xml.encode('utf-8')) + urls = xml.etree.ElementTree.fromstring(urls_xml.encode('utf-8')) + + formats = [] + for format_el in urls.findall('EncodingOptions/EncodingOption'): + domain = format_el.find('Domain').text + if domain.startswith('rtmp'): + continue + formats.append({ + 'url': domain + format_el.find('uri').text, + 'ext': 'mp4', + 'width': int(format_el.find('width').text), + 'height': int(format_el.find('height').text), + }) + + info = { + 'id': video_id, + 'title': info.find('Subject').text, + 'formats': formats, + 'description': self._og_search_description(webpage), + 'thumbnail': self._og_search_thumbnail(webpage), + 'upload_date': info.find('WriteDate').text.replace('.', ''), + 'view_count': int(info.find('PlayCount').text), + } + # TODO: Remove when #980 has been merged + info.update(formats[-1]) + return info From 08e291b54d8aaa34300c02e70ff86aaa36820a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Marqui=CC=81nez=20Ferra=CC=81ndiz?= Date: Thu, 5 Sep 2013 18:02:17 +0200 Subject: [PATCH 099/113] [generic] Recognize html5 video in the format '