X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=youtube_dl%2Fextractor%2Fdaum.py;h=76f0218923536b29550c9384ce8348baf05289d5;hb=54fc90aabfb71968f28af68dfe3f7a3544cc2f0b;hp=cf158c42d6a04be6fb3c060a2d3f6187aa06f85a;hpb=33cc74eeebe9355f38145d0d6ddc84e5a2dc1af8;p=youtube-dl diff --git a/youtube_dl/extractor/daum.py b/youtube_dl/extractor/daum.py index cf158c42d..76f021892 100644 --- a/youtube_dl/extractor/daum.py +++ b/youtube_dl/extractor/daum.py @@ -1,4 +1,4 @@ -# encoding: utf-8 +# coding: utf-8 from __future__ import unicode_literals @@ -7,8 +7,10 @@ import itertools from .common import InfoExtractor from ..compat import ( - compat_urllib_parse, + compat_parse_qs, compat_urllib_parse_unquote, + compat_urllib_parse_urlencode, + compat_urlparse, ) from ..utils import ( int_or_none, @@ -30,7 +32,7 @@ class DaumIE(InfoExtractor): 'title': '마크 헌트 vs 안토니오 실바', 'description': 'Mark Hunt vs Antonio Silva', 'upload_date': '20131217', - 'thumbnail': 're:^https?://.*\.(?:jpg|png)', + 'thumbnail': r're:^https?://.*\.(?:jpg|png)', 'duration': 2117, 'view_count': int, 'comment_count': int, @@ -40,10 +42,10 @@ class DaumIE(InfoExtractor): 'info_dict': { 'id': '65139429', 'ext': 'mp4', - 'title': 'md5:a100d65d09cec246d8aa9bde7de45aed', + 'title': '1297회, \'아빠 아들로 태어나길 잘 했어\' 민수, 감동의 눈물[아빠 어디가] 20150118', 'description': 'md5:79794514261164ff27e36a21ad229fc5', 'upload_date': '20150604', - 'thumbnail': 're:^https?://.*\.(?:jpg|png)', + 'thumbnail': r're:^https?://.*\.(?:jpg|png)', 'duration': 154, 'view_count': int, 'comment_count': int, @@ -59,32 +61,42 @@ class DaumIE(InfoExtractor): 'title': '01-Korean War ( Trouble on the horizon )', 'description': '\nKorean War 01\nTrouble on the horizon\n전쟁의 먹구름', 'upload_date': '20080223', - 'thumbnail': 're:^https?://.*\.(?:jpg|png)', + 'thumbnail': r're:^https?://.*\.(?:jpg|png)', 'duration': 249, 'view_count': int, 'comment_count': int, }, + }, { + # Requires dte_type=WEB (#9972) + 'url': 'http://tvpot.daum.net/v/s3794Uf1NZeZ1qMpGpeqeRU', + 'md5': 'a8917742069a4dd442516b86e7d66529', + 'info_dict': { + 'id': 's3794Uf1NZeZ1qMpGpeqeRU', + 'ext': 'mp4', + 'title': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny) [쇼! 음악중심] 508회 20160611', + 'description': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny)\n\n[쇼! 음악중심] 20160611, 507회', + 'upload_date': '20160611', + }, }] def _real_extract(self, url): video_id = compat_urllib_parse_unquote(self._match_id(url)) - query = compat_urllib_parse.urlencode({'vid': video_id}) movie_data = self._download_json( - 'http://videofarm.daum.net/controller/api/closed/v1_2/IntegratedMovieData.json?' + query, - video_id, 'Downloading video formats info') + 'http://videofarm.daum.net/controller/api/closed/v1_2/IntegratedMovieData.json', + video_id, 'Downloading video formats info', query={'vid': video_id, 'dte_type': 'WEB'}) # For urls like http://m.tvpot.daum.net/v/65139429, where the video_id is really a clipid if not movie_data.get('output_list', {}).get('output_list') and re.match(r'^\d+$', video_id): return self.url_result('http://tvpot.daum.net/clip/ClipView.do?clipid=%s' % video_id) info = self._download_xml( - 'http://tvpot.daum.net/clip/ClipInfoXml.do?' + query, video_id, - 'Downloading video info') + 'http://tvpot.daum.net/clip/ClipInfoXml.do', video_id, + 'Downloading video info', query={'vid': video_id}) formats = [] for format_el in movie_data['output_list']['output_list']: profile = format_el['profile'] - format_query = compat_urllib_parse.urlencode({ + format_query = compat_urllib_parse_urlencode({ 'vid': video_id, 'profile': profile, }) @@ -117,6 +129,7 @@ class DaumIE(InfoExtractor): class DaumClipIE(InfoExtractor): _VALID_URL = r'https?://(?:m\.)?tvpot\.daum\.net/(?:clip/ClipView.(?:do|tv)|mypot/View.do)\?.*?clipid=(?P\d+)' IE_NAME = 'daum.net:clip' + _URL_TEMPLATE = 'http://tvpot.daum.net/clip/ClipView.do?clipid=%s' _TESTS = [{ 'url': 'http://tvpot.daum.net/clip/ClipView.do?clipid=52554690', @@ -126,7 +139,7 @@ class DaumClipIE(InfoExtractor): 'title': 'DOTA 2GETHER 시즌2 6회 - 2부', 'description': 'DOTA 2GETHER 시즌2 6회 - 2부', 'upload_date': '20130831', - 'thumbnail': 're:^https?://.*\.(?:jpg|png)', + 'thumbnail': r're:^https?://.*\.(?:jpg|png)', 'duration': 3868, 'view_count': int, }, @@ -135,6 +148,10 @@ class DaumClipIE(InfoExtractor): 'only_matching': True, }] + @classmethod + def suitable(cls, url): + return False if DaumPlaylistIE.suitable(url) or DaumUserIE.suitable(url) else super(DaumClipIE, cls).suitable(url) + def _real_extract(self, url): video_id = self._match_id(url) clip_info = self._download_json( @@ -162,8 +179,8 @@ class DaumListIE(InfoExtractor): for pagenum in itertools.count(1): list_info = self._download_json( 'http://tvpot.daum.net/mypot/json/GetClipInfo.do?size=48&init=true&order=date&page=%d&%s=%s' % ( - pagenum, list_id_type, list_id), list_id,'Downloading list info - %s' % pagenum) - + pagenum, list_id_type, list_id), list_id, 'Downloading list info - %s' % pagenum) + entries.extend([ self.url_result( 'http://tvpot.daum.net/v/%s' % clip['vid']) @@ -179,10 +196,21 @@ class DaumListIE(InfoExtractor): return name, entries + def _check_clip(self, url, list_id): + query_dict = compat_parse_qs(compat_urlparse.urlparse(url).query) + if 'clipid' in query_dict: + clip_id = query_dict['clipid'][0] + if self._downloader.params.get('noplaylist'): + self.to_screen('Downloading just video %s because of --no-playlist' % clip_id) + return self.url_result(DaumClipIE._URL_TEMPLATE % clip_id, 'DaumClip') + else: + self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % list_id) + class DaumPlaylistIE(DaumListIE): _VALID_URL = r'https?://(?:m\.)?tvpot\.daum\.net/mypot/(?:View\.do|Top\.tv)\?.*?playlistid=(?P[0-9]+)' IE_NAME = 'daum.net:playlist' + _URL_TEMPLATE = 'http://tvpot.daum.net/mypot/View.do?playlistid=%s' _TESTS = [{ 'note': 'Playlist url with clipid', @@ -207,12 +235,16 @@ class DaumPlaylistIE(DaumListIE): } }] - def _real_extract(self, url): - if DaumClipIE.suitable(url) and self._downloader.params.get('noplaylist'): - return self.url_result(url, 'DaumClip') + @classmethod + def suitable(cls, url): + return False if DaumUserIE.suitable(url) else super(DaumPlaylistIE, cls).suitable(url) + def _real_extract(self, url): list_id = self._match_id(url) - self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % list_id) + + clip_result = self._check_clip(url, list_id) + if clip_result: + return clip_result name, entries = self._get_entries(list_id, 'playlistid') @@ -220,7 +252,7 @@ class DaumPlaylistIE(DaumListIE): class DaumUserIE(DaumListIE): - _VALID_URL = r'https?://(?:m\.)?tvpot\.daum\.net/mypot/(?:View|Top)\.do\?.*?ownerid=(?P[0-9a-zA-Z]+)' + _VALID_URL = r'https?://(?:m\.)?tvpot\.daum\.net/mypot/(?:View|Top)\.(?:do|tv)\?.*?ownerid=(?P[0-9a-zA-Z]+)' IE_NAME = 'daum.net:user' _TESTS = [{ @@ -254,17 +286,23 @@ class DaumUserIE(DaumListIE): }, { 'url': 'http://tvpot.daum.net/mypot/Top.do?ownerid=o2scDLIVbHc0', 'only_matching': True, + }, { + 'url': 'http://m.tvpot.daum.net/mypot/Top.tv?ownerid=45x1okb1If50&playlistid=3569733', + 'only_matching': True, }] def _real_extract(self, url): - if DaumClipIE.suitable(url) and self._downloader.params.get('noplaylist'): - return self.url_result(url, 'DaumClip') + list_id = self._match_id(url) - if DaumPlaylistIE.suitable(url): - return self.url_result(url, 'DaumPlaylist') + clip_result = self._check_clip(url, list_id) + if clip_result: + return clip_result + + query_dict = compat_parse_qs(compat_urlparse.urlparse(url).query) + if 'playlistid' in query_dict: + playlist_id = query_dict['playlistid'][0] + return self.url_result(DaumPlaylistIE._URL_TEMPLATE % playlist_id, 'DaumPlaylist') - list_id = self._match_id(url) - self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % list_id) name, entries = self._get_entries(list_id, 'ownerid') return self.playlist_result(entries, list_id, name)