]> Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/curiositystream.py
Update changelog
[youtubedl] / youtube_dl / extractor / curiositystream.py
1 # coding: utf-8
2 from __future__ import unicode_literals
3
4 from .common import InfoExtractor
5 from ..utils import (
6 int_or_none,
7 urlencode_postdata,
8 compat_str,
9 ExtractorError,
10 )
11
12
13 class CuriosityStreamBaseIE(InfoExtractor):
14 _NETRC_MACHINE = 'curiositystream'
15 _auth_token = None
16 _API_BASE_URL = 'https://api.curiositystream.com/v1/'
17
18 def _handle_errors(self, result):
19 error = result.get('error', {}).get('message')
20 if error:
21 if isinstance(error, dict):
22 error = ', '.join(error.values())
23 raise ExtractorError(
24 '%s said: %s' % (self.IE_NAME, error), expected=True)
25
26 def _call_api(self, path, video_id):
27 headers = {}
28 if self._auth_token:
29 headers['X-Auth-Token'] = self._auth_token
30 result = self._download_json(
31 self._API_BASE_URL + path, video_id, headers=headers)
32 self._handle_errors(result)
33 return result['data']
34
35 def _real_initialize(self):
36 (email, password) = self._get_login_info()
37 if email is None:
38 return
39 result = self._download_json(
40 self._API_BASE_URL + 'login', None, data=urlencode_postdata({
41 'email': email,
42 'password': password,
43 }))
44 self._handle_errors(result)
45 self._auth_token = result['message']['auth_token']
46
47 def _extract_media_info(self, media):
48 video_id = compat_str(media['id'])
49 limelight_media_id = media['limelight_media_id']
50 title = media['title']
51
52 subtitles = {}
53 for closed_caption in media.get('closed_captions', []):
54 sub_url = closed_caption.get('file')
55 if not sub_url:
56 continue
57 lang = closed_caption.get('code') or closed_caption.get('language') or 'en'
58 subtitles.setdefault(lang, []).append({
59 'url': sub_url,
60 })
61
62 return {
63 '_type': 'url_transparent',
64 'id': video_id,
65 'url': 'limelight:media:' + limelight_media_id,
66 'title': title,
67 'description': media.get('description'),
68 'thumbnail': media.get('image_large') or media.get('image_medium') or media.get('image_small'),
69 'duration': int_or_none(media.get('duration')),
70 'tags': media.get('tags'),
71 'subtitles': subtitles,
72 'ie_key': 'LimelightMedia',
73 }
74
75
76 class CuriosityStreamIE(CuriosityStreamBaseIE):
77 IE_NAME = 'curiositystream'
78 _VALID_URL = r'https?://app\.curiositystream\.com/video/(?P<id>\d+)'
79 _TEST = {
80 'url': 'https://app.curiositystream.com/video/2',
81 'md5': 'a0074c190e6cddaf86900b28d3e9ee7a',
82 'info_dict': {
83 'id': '2',
84 'ext': 'mp4',
85 'title': 'How Did You Develop The Internet?',
86 'description': 'Vint Cerf, Google\'s Chief Internet Evangelist, describes how he and Bob Kahn created the internet.',
87 'timestamp': 1448388615,
88 'upload_date': '20151124',
89 }
90 }
91
92 def _real_extract(self, url):
93 video_id = self._match_id(url)
94 media = self._call_api('media/' + video_id, video_id)
95 return self._extract_media_info(media)
96
97
98 class CuriosityStreamCollectionIE(CuriosityStreamBaseIE):
99 IE_NAME = 'curiositystream:collection'
100 _VALID_URL = r'https?://app\.curiositystream\.com/collection/(?P<id>\d+)'
101 _TEST = {
102 'url': 'https://app.curiositystream.com/collection/2',
103 'info_dict': {
104 'id': '2',
105 'title': 'Curious Minds: The Internet',
106 'description': 'How is the internet shaping our lives in the 21st Century?',
107 },
108 'playlist_mincount': 17,
109 }
110
111 def _real_extract(self, url):
112 collection_id = self._match_id(url)
113 collection = self._call_api(
114 'collections/' + collection_id, collection_id)
115 entries = []
116 for media in collection.get('media', []):
117 entries.append(self._extract_media_info(media))
118 return self.playlist_result(
119 entries, collection_id,
120 collection.get('title'), collection.get('description'))