3 from .common
import InfoExtractor
11 class BrilliantpalaBaseIE(InfoExtractor
):
12 _NETRC_MACHINE
= 'brilliantpala'
13 _DOMAIN
= '{subdomain}.brilliantpala.org'
15 def _initialize_pre_login(self
):
16 self
._HOMEPAGE
= f
'https://{self._DOMAIN}'
17 self
._LOGIN
_API
= f
'{self._HOMEPAGE}/login/'
18 self
._LOGOUT
_DEVICES
_API
= f
'{self._HOMEPAGE}/logout_devices/?next=/'
19 self
._CONTENT
_API
= f
'{self._HOMEPAGE}/api/v2.4/contents/{{content_id}}/'
20 self
._HLS
_AES
_URI
= f
'{self._HOMEPAGE}/api/v2.5/video_contents/{{content_id}}/key/'
22 def _get_logged_in_username(self
, url
, video_id
):
23 webpage
, urlh
= self
._download
_webpage
_handle
(url
, video_id
)
24 if urlh
.url
.startswith(self
._LOGIN
_API
):
25 self
.raise_login_required()
26 return self
._html
_search
_regex
(
27 r
'"username"\s*:\s*"(?P<username>[^"]+)"', webpage
, 'logged-in username')
29 def _perform_login(self
, username
, password
):
30 login_form
= self
._hidden
_inputs
(self
._download
_webpage
(
31 self
._LOGIN
_API
, None, 'Downloading login page'))
36 self
._set
_cookie
(self
._DOMAIN
, 'csrftoken', login_form
['csrfmiddlewaretoken'])
38 logged_page
= self
._download
_webpage
(
39 self
._LOGIN
_API
, None, note
='Logging in', headers
={'Referer': self
._LOGIN
_API
},
40 data
=urlencode_postdata(login_form
))
42 if self
._html
_search
_regex
(
43 r
'(Your username / email and password)', logged_page
, 'auth fail', default
=None):
44 raise ExtractorError('wrong username or password', expected
=True)
46 # the maximum number of logins is one
47 if self
._html
_search
_regex
(
48 r
'(Logout Other Devices)', logged_page
, 'logout devices button', default
=None):
49 logout_device_form
= self
._hidden
_inputs
(logged_page
)
50 self
._download
_webpage
(
51 self
._LOGOUT
_DEVICES
_API
, None, headers
={'Referer': self
._LOGIN
_API
},
52 note
='Logging out other devices', data
=urlencode_postdata(logout_device_form
))
54 def _real_extract(self
, url
):
55 course_id
, content_id
= self
._match
_valid
_url
(url
).group('course_id', 'content_id')
56 video_id
= f
'{course_id}-{content_id}'
58 username
= self
._get
_logged
_in
_username
(url
, video_id
)
60 content_json
= self
._download
_json
(
61 self
._CONTENT
_API
.format(content_id
=content_id
), video_id
,
62 note
='Fetching content info', errnote
='Unable to fetch content info')
65 for stream
in traverse_obj(content_json
, ('video', 'streams', lambda _
, v
: v
['id'] and v
['url'])):
66 formats
= self
._extract
_m
3u8_formats
(stream
['url'], video_id
, fatal
=False)
70 'id': str(stream
['id']),
71 'title': content_json
.get('title'),
73 'hls_aes': {'uri': self
._HLS
_AES
_URI
.format(content_id
=content_id
)},
74 'http_headers': {'X-Key': hashlib
.sha256(username
.encode('ascii')).hexdigest()},
75 'thumbnail': content_json
.get('cover_image'),
78 return self
.playlist_result(
79 entries
, playlist_id
=video_id
, playlist_title
=content_json
.get('title'))
82 class BrilliantpalaElearnIE(BrilliantpalaBaseIE
):
83 IE_NAME
= 'Brilliantpala:Elearn'
84 IE_DESC
= 'VoD on elearn.brilliantpala.org'
85 _VALID_URL
= r
'https?://elearn\.brilliantpala\.org/courses/(?P<course_id>\d+)/contents/(?P<content_id>\d+)/?'
87 'url': 'https://elearn.brilliantpala.org/courses/42/contents/12345/',
88 'only_matching': True,
90 'url': 'https://elearn.brilliantpala.org/courses/98/contents/36683/',
94 'title': 'Physical World, Units and Measurements - 1',
95 'thumbnail': 'https://d1j3vi2u94ebt0.cloudfront.net/institute/brilliantpalalms/chapter_contents/26237/e657f81b90874be19795c7ea081f8d5c.png',
96 'live_status': 'not_live',
99 'skip_download': True,
103 _DOMAIN
= BrilliantpalaBaseIE
._DOMAIN
.format(subdomain
='elearn')
106 class BrilliantpalaClassesIE(BrilliantpalaBaseIE
):
107 IE_NAME
= 'Brilliantpala:Classes'
108 IE_DESC
= 'VoD on classes.brilliantpala.org'
109 _VALID_URL
= r
'https?://classes\.brilliantpala\.org/courses/(?P<course_id>\d+)/contents/(?P<content_id>\d+)/?'
111 'url': 'https://classes.brilliantpala.org/courses/42/contents/12345/',
112 'only_matching': True,
114 'url': 'https://classes.brilliantpala.org/courses/416/contents/25445/',
118 'title': 'Motion in a Straight Line - Class 1',
119 'thumbnail': 'https://d3e4y8hquds3ek.cloudfront.net/institute/brilliantpalaelearn/chapter_contents/ff5ba838d0ec43419f67387fe1a01fa8.png',
120 'live_status': 'not_live',
123 'skip_download': True,
127 _DOMAIN
= BrilliantpalaBaseIE
._DOMAIN
.format(subdomain
='classes')