logo

youtube-dl

[mirror] Download/Watch videos from video hostersgit clone https://hacktivis.me/git/mirror/youtube-dl.git

daum.py (9721B)


  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import itertools
  4. from .common import InfoExtractor
  5. from ..compat import (
  6. compat_parse_qs,
  7. compat_urllib_parse_unquote,
  8. compat_urlparse,
  9. )
  10. class DaumBaseIE(InfoExtractor):
  11. _KAKAO_EMBED_BASE = 'http://tv.kakao.com/embed/player/cliplink/'
  12. class DaumIE(DaumBaseIE):
  13. _VALID_URL = r'https?://(?:(?:m\.)?tvpot\.daum\.net/v/|videofarm\.daum\.net/controller/player/VodPlayer\.swf\?vid=)(?P<id>[^?#&]+)'
  14. IE_NAME = 'daum.net'
  15. _TESTS = [{
  16. 'url': 'http://tvpot.daum.net/v/vab4dyeDBysyBssyukBUjBz',
  17. 'info_dict': {
  18. 'id': 'vab4dyeDBysyBssyukBUjBz',
  19. 'ext': 'mp4',
  20. 'title': '마크 헌트 vs 안토니오 실바',
  21. 'description': 'Mark Hunt vs Antonio Silva',
  22. 'upload_date': '20131217',
  23. 'thumbnail': r're:^https?://.*\.(?:jpg|png)',
  24. 'duration': 2117,
  25. 'view_count': int,
  26. 'comment_count': int,
  27. 'uploader_id': 186139,
  28. 'uploader': '콘간지',
  29. 'timestamp': 1387310323,
  30. },
  31. }, {
  32. 'url': 'http://m.tvpot.daum.net/v/65139429',
  33. 'info_dict': {
  34. 'id': '65139429',
  35. 'ext': 'mp4',
  36. 'title': '1297회, \'아빠 아들로 태어나길 잘 했어\' 민수, 감동의 눈물[아빠 어디가] 20150118',
  37. 'description': 'md5:79794514261164ff27e36a21ad229fc5',
  38. 'upload_date': '20150118',
  39. 'thumbnail': r're:^https?://.*\.(?:jpg|png)',
  40. 'duration': 154,
  41. 'view_count': int,
  42. 'comment_count': int,
  43. 'uploader': 'MBC 예능',
  44. 'uploader_id': 132251,
  45. 'timestamp': 1421604228,
  46. },
  47. }, {
  48. 'url': 'http://tvpot.daum.net/v/07dXWRka62Y%24',
  49. 'only_matching': True,
  50. }, {
  51. 'url': 'http://videofarm.daum.net/controller/player/VodPlayer.swf?vid=vwIpVpCQsT8%24&ref=',
  52. 'info_dict': {
  53. 'id': 'vwIpVpCQsT8$',
  54. 'ext': 'flv',
  55. 'title': '01-Korean War ( Trouble on the horizon )',
  56. 'description': 'Korean War 01\r\nTrouble on the horizon\r\n전쟁의 먹구름',
  57. 'upload_date': '20080223',
  58. 'thumbnail': r're:^https?://.*\.(?:jpg|png)',
  59. 'duration': 249,
  60. 'view_count': int,
  61. 'comment_count': int,
  62. 'uploader': '까칠한 墮落始祖 황비홍님의',
  63. 'uploader_id': 560824,
  64. 'timestamp': 1203770745,
  65. },
  66. }, {
  67. # Requires dte_type=WEB (#9972)
  68. 'url': 'http://tvpot.daum.net/v/s3794Uf1NZeZ1qMpGpeqeRU',
  69. 'md5': 'a8917742069a4dd442516b86e7d66529',
  70. 'info_dict': {
  71. 'id': 's3794Uf1NZeZ1qMpGpeqeRU',
  72. 'ext': 'mp4',
  73. 'title': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny)',
  74. 'description': '러블리즈 - Destiny (나의 지구) (Lovelyz - Destiny)\r\n\r\n[쇼! 음악중심] 20160611, 507회',
  75. 'upload_date': '20170129',
  76. 'uploader': '쇼! 음악중심',
  77. 'uploader_id': 2653210,
  78. 'timestamp': 1485684628,
  79. },
  80. }]
  81. def _real_extract(self, url):
  82. video_id = compat_urllib_parse_unquote(self._match_id(url))
  83. if not video_id.isdigit():
  84. video_id += '@my'
  85. return self.url_result(
  86. self._KAKAO_EMBED_BASE + video_id, 'Kakao', video_id)
  87. class DaumClipIE(DaumBaseIE):
  88. _VALID_URL = r'https?://(?:m\.)?tvpot\.daum\.net/(?:clip/ClipView.(?:do|tv)|mypot/View.do)\?.*?clipid=(?P<id>\d+)'
  89. IE_NAME = 'daum.net:clip'
  90. _URL_TEMPLATE = 'http://tvpot.daum.net/clip/ClipView.do?clipid=%s'
  91. _TESTS = [{
  92. 'url': 'http://tvpot.daum.net/clip/ClipView.do?clipid=52554690',
  93. 'info_dict': {
  94. 'id': '52554690',
  95. 'ext': 'mp4',
  96. 'title': 'DOTA 2GETHER 시즌2 6회 - 2부',
  97. 'description': 'DOTA 2GETHER 시즌2 6회 - 2부',
  98. 'upload_date': '20130831',
  99. 'thumbnail': r're:^https?://.*\.(?:jpg|png)',
  100. 'duration': 3868,
  101. 'view_count': int,
  102. 'uploader': 'GOMeXP',
  103. 'uploader_id': 6667,
  104. 'timestamp': 1377911092,
  105. },
  106. }, {
  107. 'url': 'http://m.tvpot.daum.net/clip/ClipView.tv?clipid=54999425',
  108. 'only_matching': True,
  109. }]
  110. @classmethod
  111. def suitable(cls, url):
  112. return False if DaumPlaylistIE.suitable(url) or DaumUserIE.suitable(url) else super(DaumClipIE, cls).suitable(url)
  113. def _real_extract(self, url):
  114. video_id = self._match_id(url)
  115. return self.url_result(
  116. self._KAKAO_EMBED_BASE + video_id, 'Kakao', video_id)
  117. class DaumListIE(InfoExtractor):
  118. def _get_entries(self, list_id, list_id_type):
  119. name = None
  120. entries = []
  121. for pagenum in itertools.count(1):
  122. list_info = self._download_json(
  123. 'http://tvpot.daum.net/mypot/json/GetClipInfo.do?size=48&init=true&order=date&page=%d&%s=%s' % (
  124. pagenum, list_id_type, list_id), list_id, 'Downloading list info - %s' % pagenum)
  125. entries.extend([
  126. self.url_result(
  127. 'http://tvpot.daum.net/v/%s' % clip['vid'])
  128. for clip in list_info['clip_list']
  129. ])
  130. if not name:
  131. name = list_info.get('playlist_bean', {}).get('name') or \
  132. list_info.get('potInfo', {}).get('name')
  133. if not list_info.get('has_more'):
  134. break
  135. return name, entries
  136. def _check_clip(self, url, list_id):
  137. query_dict = compat_parse_qs(compat_urlparse.urlparse(url).query)
  138. if 'clipid' in query_dict:
  139. clip_id = query_dict['clipid'][0]
  140. if self._downloader.params.get('noplaylist'):
  141. self.to_screen('Downloading just video %s because of --no-playlist' % clip_id)
  142. return self.url_result(DaumClipIE._URL_TEMPLATE % clip_id, 'DaumClip')
  143. else:
  144. self.to_screen('Downloading playlist %s - add --no-playlist to just download video' % list_id)
  145. class DaumPlaylistIE(DaumListIE):
  146. _VALID_URL = r'https?://(?:m\.)?tvpot\.daum\.net/mypot/(?:View\.do|Top\.tv)\?.*?playlistid=(?P<id>[0-9]+)'
  147. IE_NAME = 'daum.net:playlist'
  148. _URL_TEMPLATE = 'http://tvpot.daum.net/mypot/View.do?playlistid=%s'
  149. _TESTS = [{
  150. 'note': 'Playlist url with clipid',
  151. 'url': 'http://tvpot.daum.net/mypot/View.do?playlistid=6213966&clipid=73806844',
  152. 'info_dict': {
  153. 'id': '6213966',
  154. 'title': 'Woorissica Official',
  155. },
  156. 'playlist_mincount': 181
  157. }, {
  158. 'note': 'Playlist url with clipid - noplaylist',
  159. 'url': 'http://tvpot.daum.net/mypot/View.do?playlistid=6213966&clipid=73806844',
  160. 'info_dict': {
  161. 'id': '73806844',
  162. 'ext': 'mp4',
  163. 'title': '151017 Airport',
  164. 'upload_date': '20160117',
  165. },
  166. 'params': {
  167. 'noplaylist': True,
  168. 'skip_download': True,
  169. }
  170. }]
  171. @classmethod
  172. def suitable(cls, url):
  173. return False if DaumUserIE.suitable(url) else super(DaumPlaylistIE, cls).suitable(url)
  174. def _real_extract(self, url):
  175. list_id = self._match_id(url)
  176. clip_result = self._check_clip(url, list_id)
  177. if clip_result:
  178. return clip_result
  179. name, entries = self._get_entries(list_id, 'playlistid')
  180. return self.playlist_result(entries, list_id, name)
  181. class DaumUserIE(DaumListIE):
  182. _VALID_URL = r'https?://(?:m\.)?tvpot\.daum\.net/mypot/(?:View|Top)\.(?:do|tv)\?.*?ownerid=(?P<id>[0-9a-zA-Z]+)'
  183. IE_NAME = 'daum.net:user'
  184. _TESTS = [{
  185. 'url': 'http://tvpot.daum.net/mypot/View.do?ownerid=o2scDLIVbHc0',
  186. 'info_dict': {
  187. 'id': 'o2scDLIVbHc0',
  188. 'title': '마이 리틀 텔레비전',
  189. },
  190. 'playlist_mincount': 213
  191. }, {
  192. 'url': 'http://tvpot.daum.net/mypot/View.do?ownerid=o2scDLIVbHc0&clipid=73801156',
  193. 'info_dict': {
  194. 'id': '73801156',
  195. 'ext': 'mp4',
  196. 'title': '[미공개] 김구라, 오만석이 부릅니다 \'오케피\' - 마이 리틀 텔레비전 20160116',
  197. 'upload_date': '20160117',
  198. 'description': 'md5:5e91d2d6747f53575badd24bd62b9f36'
  199. },
  200. 'params': {
  201. 'noplaylist': True,
  202. 'skip_download': True,
  203. }
  204. }, {
  205. 'note': 'Playlist url has ownerid and playlistid, playlistid takes precedence',
  206. 'url': 'http://tvpot.daum.net/mypot/View.do?ownerid=o2scDLIVbHc0&playlistid=6196631',
  207. 'info_dict': {
  208. 'id': '6196631',
  209. 'title': '마이 리틀 텔레비전 - 20160109',
  210. },
  211. 'playlist_count': 11
  212. }, {
  213. 'url': 'http://tvpot.daum.net/mypot/Top.do?ownerid=o2scDLIVbHc0',
  214. 'only_matching': True,
  215. }, {
  216. 'url': 'http://m.tvpot.daum.net/mypot/Top.tv?ownerid=45x1okb1If50&playlistid=3569733',
  217. 'only_matching': True,
  218. }]
  219. def _real_extract(self, url):
  220. list_id = self._match_id(url)
  221. clip_result = self._check_clip(url, list_id)
  222. if clip_result:
  223. return clip_result
  224. query_dict = compat_parse_qs(compat_urlparse.urlparse(url).query)
  225. if 'playlistid' in query_dict:
  226. playlist_id = query_dict['playlistid'][0]
  227. return self.url_result(DaumPlaylistIE._URL_TEMPLATE % playlist_id, 'DaumPlaylist')
  228. name, entries = self._get_entries(list_id, 'ownerid')
  229. return self.playlist_result(entries, list_id, name)