3 from __future__ 
import unicode_literals
 
   8 from .common 
import InfoExtractor
 
  12     compat_urllib_parse_unquote
, 
  23 class DaumIE(InfoExtractor
): 
  24     _VALID_URL 
= r
'https?://(?:(?:m\.)?tvpot\.daum\.net/v/|videofarm\.daum\.net/controller/player/VodPlayer\.swf\?vid=)(?P<id>[^?#&]+)' 
  28         'url': 'http://tvpot.daum.net/v/vab4dyeDBysyBssyukBUjBz', 
  30             'id': 'vab4dyeDBysyBssyukBUjBz', 
  32             'title': '마크 헌트 vs 안토니오 실바', 
  33             'description': 'Mark Hunt vs Antonio Silva', 
  34             'upload_date': '20131217', 
  35             'thumbnail': 're:^https?://.*\.(?:jpg|png)', 
  41         'url': 'http://m.tvpot.daum.net/v/65139429', 
  45             'title': '1297회, \'아빠 아들로 태어나길 잘 했어\' 민수, 감동의 눈물[아빠 어디가] 20150118', 
  46             'description': 'md5:79794514261164ff27e36a21ad229fc5', 
  47             'upload_date': '20150604', 
  48             'thumbnail': 're:^https?://.*\.(?:jpg|png)', 
  54         'url': 'http://tvpot.daum.net/v/07dXWRka62Y%24', 
  55         'only_matching': True, 
  57         'url': 'http://videofarm.daum.net/controller/player/VodPlayer.swf?vid=vwIpVpCQsT8%24&ref=', 
  61             'title': '01-Korean War ( Trouble on the horizon )', 
  62             'description': '\nKorean War 01\nTrouble on the horizon\n전쟁의 먹구름', 
  63             'upload_date': '20080223', 
  64             'thumbnail': 're:^https?://.*\.(?:jpg|png)', 
  71     def _real_extract(self
, url
): 
  72         video_id 
= compat_urllib_parse_unquote(self
._match
_id
(url
)) 
  73         query 
= compat_urllib_parse
.urlencode({'vid': video_id
}) 
  74         movie_data 
= self
._download
_json
( 
  75             'http://videofarm.daum.net/controller/api/closed/v1_2/IntegratedMovieData.json?' + query
, 
  76             video_id
, 'Downloading video formats info') 
  78         # For urls like http://m.tvpot.daum.net/v/65139429, where the video_id is really a clipid 
  79         if not movie_data
.get('output_list', {}).get('output_list') and re
.match(r
'^\d+$', video_id
): 
  80             return self
.url_result('http://tvpot.daum.net/clip/ClipView.do?clipid=%s' % video_id
) 
  82         info 
= self
._download
_xml
( 
  83             'http://tvpot.daum.net/clip/ClipInfoXml.do?' + query
, video_id
, 
  84             'Downloading video info') 
  87         for format_el 
in movie_data
['output_list']['output_list']: 
  88             profile 
= format_el
['profile'] 
  89             format_query 
= compat_urllib_parse
.urlencode({ 
  93             url_doc 
= self
._download
_xml
( 
  94                 'http://videofarm.daum.net/controller/api/open/v1_2/MovieLocation.apixml?' + format_query
, 
  95                 video_id
, note
='Downloading video data for %s format' % profile
) 
  96             format_url 
= url_doc
.find('result/url').text
 
 100                 'width': int_or_none(format_el
.get('width')), 
 101                 'height': int_or_none(format_el
.get('height')), 
 102                 'filesize': int_or_none(format_el
.get('filesize')), 
 104         self
._sort
_formats
(formats
) 
 108             'title': info
.find('TITLE').text
, 
 110             'thumbnail': xpath_text(info
, 'THUMB_URL'), 
 111             'description': xpath_text(info
, 'CONTENTS'), 
 112             'duration': int_or_none(xpath_text(info
, 'DURATION')), 
 113             'upload_date': info
.find('REGDTTM').text
[:8], 
 114             'view_count': str_to_int(xpath_text(info
, 'PLAY_CNT')), 
 115             'comment_count': str_to_int(xpath_text(info
, 'COMMENT_CNT')), 
 119 class DaumClipIE(InfoExtractor
): 
 120     _VALID_URL 
= r
'https?://(?:m\.)?tvpot\.daum\.net/(?:clip/ClipView.(?:do|tv)|mypot/View.do)\?.*?clipid=(?P<id>\d+)' 
 121     IE_NAME 
= 'daum.net:clip' 
 122     _URL_TEMPLATE 
= 'http://tvpot.daum.net/clip/ClipView.do?clipid=%s' 
 125         'url': 'http://tvpot.daum.net/clip/ClipView.do?clipid=52554690', 
 129             'title': 'DOTA 2GETHER 시즌2 6회 - 2부', 
 130             'description': 'DOTA 2GETHER 시즌2 6회 - 2부', 
 131             'upload_date': '20130831', 
 132             'thumbnail': 're:^https?://.*\.(?:jpg|png)', 
 137         'url': 'http://m.tvpot.daum.net/clip/ClipView.tv?clipid=54999425', 
 138         'only_matching': True, 
 142     def suitable(cls
, url
): 
 143         return False if DaumPlaylistIE
.suitable(url
) or DaumUserIE
.suitable(url
) else super(DaumClipIE
, cls
).suitable(url
) 
 145     def _real_extract(self
, url
): 
 146         video_id 
= self
._match
_id
(url
) 
 147         clip_info 
= self
._download
_json
( 
 148             'http://tvpot.daum.net/mypot/json/GetClipInfo.do?clipid=%s' % video_id
, 
 149             video_id
, 'Downloading clip info')['clip_bean'] 
 152             '_type': 'url_transparent', 
 154             'url': 'http://tvpot.daum.net/v/%s' % clip_info
['vid'], 
 155             'title': unescapeHTML(clip_info
['title']), 
 156             'thumbnail': clip_info
.get('thumb_url'), 
 157             'description': clip_info
.get('contents'), 
 158             'duration': int_or_none(clip_info
.get('duration')), 
 159             'upload_date': clip_info
.get('up_date')[:8], 
 160             'view_count': int_or_none(clip_info
.get('play_count')), 
 165 class DaumListIE(InfoExtractor
): 
 166     def _get_entries(self
, list_id
, list_id_type
): 
 169         for pagenum 
in itertools
.count(1): 
 170             list_info 
= self
._download
_json
( 
 171                 'http://tvpot.daum.net/mypot/json/GetClipInfo.do?size=48&init=true&order=date&page=%d&%s=%s' % ( 
 172                     pagenum
, list_id_type
, list_id
), list_id
, 'Downloading list info - %s' % pagenum
) 
 176                     'http://tvpot.daum.net/v/%s' % clip
['vid']) 
 177                 for clip 
in list_info
['clip_list'] 
 181                 name 
= list_info
.get('playlist_bean', {}).get('name') or \
 
 182                     list_info
.get('potInfo', {}).get('name') 
 184             if not list_info
.get('has_more'): 
 189     def _check_clip(self
, url
, list_id
): 
 190         query_dict 
= compat_parse_qs(compat_urlparse
.urlparse(url
).query
) 
 191         if 'clipid' in query_dict
: 
 192             clip_id 
= query_dict
['clipid'][0] 
 193             if self
._downloader
.params
.get('noplaylist'): 
 194                 self
.to_screen('Downloading just video %s because of --no-playlist' % clip_id
) 
 195                 return self
.url_result(DaumClipIE
._URL
_TEMPLATE 
% clip_id
, 'DaumClip') 
 197                 self
.to_screen('Downloading playlist %s - add --no-playlist to just download video' % list_id
) 
 200 class DaumPlaylistIE(DaumListIE
): 
 201     _VALID_URL 
= r
'https?://(?:m\.)?tvpot\.daum\.net/mypot/(?:View\.do|Top\.tv)\?.*?playlistid=(?P<id>[0-9]+)' 
 202     IE_NAME 
= 'daum.net:playlist' 
 203     _URL_TEMPLATE 
= 'http://tvpot.daum.net/mypot/View.do?playlistid=%s' 
 206         'note': 'Playlist url with clipid', 
 207         'url': 'http://tvpot.daum.net/mypot/View.do?playlistid=6213966&clipid=73806844', 
 210             'title': 'Woorissica Official', 
 212         'playlist_mincount': 181 
 214         'note': 'Playlist url with clipid - noplaylist', 
 215         'url': 'http://tvpot.daum.net/mypot/View.do?playlistid=6213966&clipid=73806844', 
 219             'title': '151017 Airport', 
 220             'upload_date': '20160117', 
 224             'skip_download': True, 
 229     def suitable(cls
, url
): 
 230         return False if DaumUserIE
.suitable(url
) else super(DaumPlaylistIE
, cls
).suitable(url
) 
 232     def _real_extract(self
, url
): 
 233         list_id 
= self
._match
_id
(url
) 
 235         clip_result 
= self
._check
_clip
(url
, list_id
) 
 239         name
, entries 
= self
._get
_entries
(list_id
, 'playlistid') 
 241         return self
.playlist_result(entries
, list_id
, name
) 
 244 class DaumUserIE(DaumListIE
): 
 245     _VALID_URL 
= r
'https?://(?:m\.)?tvpot\.daum\.net/mypot/(?:View|Top)\.(?:do|tv)\?.*?ownerid=(?P<id>[0-9a-zA-Z]+)' 
 246     IE_NAME 
= 'daum.net:user' 
 249         'url': 'http://tvpot.daum.net/mypot/View.do?ownerid=o2scDLIVbHc0', 
 251             'id': 'o2scDLIVbHc0', 
 252             'title': '마이 리틀 텔레비전', 
 254         'playlist_mincount': 213 
 256         'url': 'http://tvpot.daum.net/mypot/View.do?ownerid=o2scDLIVbHc0&clipid=73801156', 
 260             'title': '[미공개] 김구라, 오만석이 부릅니다 \'오케피\' - 마이 리틀 텔레비전 20160116', 
 261             'upload_date': '20160117', 
 262             'description': 'md5:5e91d2d6747f53575badd24bd62b9f36' 
 266             'skip_download': True, 
 269         'note': 'Playlist url has ownerid and playlistid, playlistid takes precedence', 
 270         'url': 'http://tvpot.daum.net/mypot/View.do?ownerid=o2scDLIVbHc0&playlistid=6196631', 
 273             'title': '마이 리틀 텔레비전 - 20160109', 
 277         'url': 'http://tvpot.daum.net/mypot/Top.do?ownerid=o2scDLIVbHc0', 
 278         'only_matching': True, 
 280         'url': 'http://m.tvpot.daum.net/mypot/Top.tv?ownerid=45x1okb1If50&playlistid=3569733', 
 281         'only_matching': True, 
 284     def _real_extract(self
, url
): 
 285         list_id 
= self
._match
_id
(url
) 
 287         clip_result 
= self
._check
_clip
(url
, list_id
) 
 291         query_dict 
= compat_parse_qs(compat_urlparse
.urlparse(url
).query
) 
 292         if 'playlistid' in query_dict
: 
 293             playlist_id 
= query_dict
['playlistid'][0] 
 294             return self
.url_result(DaumPlaylistIE
._URL
_TEMPLATE 
% playlist_id
, 'DaumPlaylist') 
 296         name
, entries 
= self
._get
_entries
(list_id
, 'ownerid') 
 298         return self
.playlist_result(entries
, list_id
, name
)