mirror of
https://github.com/yt-dlp/yt-dlp
synced 2024-12-25 21:59:04 +01:00
[extractor] Add _perform_login
function (#2943)
* Adds new functions `_initialize_pre_login` and `_perform_login` as part of the extractor API * Adds `ie.supports_login` to the public API
This commit is contained in:
parent
028f6437f1
commit
52efa4b312
68 changed files with 253 additions and 569 deletions
|
@ -12,11 +12,6 @@ from test.helper import FakeYDL, is_download_test
|
|||
from yt_dlp.extractor import IqiyiIE
|
||||
|
||||
|
||||
class IqiyiIEWithCredentials(IqiyiIE):
|
||||
def _get_login_info(self):
|
||||
return 'foo', 'bar'
|
||||
|
||||
|
||||
class WarningLogger(object):
|
||||
def __init__(self):
|
||||
self.messages = []
|
||||
|
@ -40,8 +35,8 @@ class TestIqiyiSDKInterpreter(unittest.TestCase):
|
|||
If `sign` is incorrect, /validate call throws an HTTP 556 error
|
||||
'''
|
||||
logger = WarningLogger()
|
||||
ie = IqiyiIEWithCredentials(FakeYDL({'logger': logger}))
|
||||
ie._login()
|
||||
ie = IqiyiIE(FakeYDL({'logger': logger}))
|
||||
ie._perform_login('foo', 'bar')
|
||||
self.assertTrue('unable to log in:' in logger.messages[0])
|
||||
|
||||
|
||||
|
|
|
@ -7,18 +7,19 @@ import unittest
|
|||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
|
||||
from yt_dlp.extractor import (
|
||||
gen_extractors,
|
||||
)
|
||||
from yt_dlp.extractor import gen_extractor_classes
|
||||
from yt_dlp.extractor.common import InfoExtractor
|
||||
|
||||
NO_LOGIN = InfoExtractor._perform_login
|
||||
|
||||
|
||||
class TestNetRc(unittest.TestCase):
|
||||
def test_netrc_present(self):
|
||||
for ie in gen_extractors():
|
||||
if not hasattr(ie, '_login'):
|
||||
for ie in gen_extractor_classes():
|
||||
if ie._perform_login is NO_LOGIN:
|
||||
continue
|
||||
self.assertTrue(
|
||||
hasattr(ie, '_NETRC_MACHINE'),
|
||||
ie._NETRC_MACHINE,
|
||||
'Extractor %s supports login, but is missing a _NETRC_MACHINE property' % ie.IE_NAME)
|
||||
|
||||
|
||||
|
|
|
@ -291,15 +291,7 @@ class AbemaTVIE(AbemaTVBaseIE):
|
|||
|
||||
return self._MEDIATOKEN
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
# No authentication to be performed
|
||||
if not username:
|
||||
return True
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
if '@' in username: # don't strictly check if it's email address or not
|
||||
ep, method = 'user/email', 'email'
|
||||
else:
|
||||
|
|
|
@ -126,10 +126,7 @@ Format: Marked,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text'''
|
|||
}])
|
||||
return subtitles
|
||||
|
||||
def _real_initialize(self):
|
||||
username, password = self._get_login_info()
|
||||
if not username:
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
try:
|
||||
access_token = (self._download_json(
|
||||
self._API_BASE_URL + 'authentication/login', None,
|
||||
|
|
|
@ -184,14 +184,7 @@ class AfreecaTVIE(InfoExtractor):
|
|||
video_key['part'] = int(m.group('part'))
|
||||
return video_key
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_form = {
|
||||
'szWork': 'login',
|
||||
'szType': 'json',
|
||||
|
|
|
@ -74,14 +74,7 @@ class AluraIE(InfoExtractor):
|
|||
"formats": formats
|
||||
}
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
pass
|
||||
def _perform_login(self, username, password):
|
||||
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login popup')
|
||||
|
|
|
@ -15,25 +15,21 @@ from ..compat import compat_HTTPError
|
|||
|
||||
|
||||
class AnimeLabBaseIE(InfoExtractor):
|
||||
_LOGIN_REQUIRED = True
|
||||
_LOGIN_URL = 'https://www.animelab.com/login'
|
||||
_NETRC_MACHINE = 'animelab'
|
||||
_LOGGED_IN = False
|
||||
|
||||
def _login(self):
|
||||
def is_logged_in(login_webpage):
|
||||
return 'Sign In' not in login_webpage
|
||||
def _is_logged_in(self, login_page=None):
|
||||
if not self._LOGGED_IN:
|
||||
if not login_page:
|
||||
login_page = self._download_webpage(self._LOGIN_URL, None, 'Downloading login page')
|
||||
AnimeLabBaseIE._LOGGED_IN = 'Sign In' not in login_page
|
||||
return self._LOGGED_IN
|
||||
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login page')
|
||||
|
||||
# Check if already logged in
|
||||
if is_logged_in(login_page):
|
||||
def _perform_login(self, username, password):
|
||||
if self._is_logged_in():
|
||||
return
|
||||
|
||||
(username, password) = self._get_login_info()
|
||||
if username is None and self._LOGIN_REQUIRED:
|
||||
self.raise_login_required('Login is required to access any AnimeLab content')
|
||||
|
||||
login_form = {
|
||||
'email': username,
|
||||
'password': password,
|
||||
|
@ -47,17 +43,14 @@ class AnimeLabBaseIE(InfoExtractor):
|
|||
except ExtractorError as e:
|
||||
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 400:
|
||||
raise ExtractorError('Unable to log in (wrong credentials?)', expected=True)
|
||||
else:
|
||||
raise
|
||||
raise
|
||||
|
||||
# if login was successful
|
||||
if is_logged_in(response):
|
||||
return
|
||||
|
||||
raise ExtractorError('Unable to login (cannot verify if logged in)')
|
||||
if not self._is_logged_in(response):
|
||||
raise ExtractorError('Unable to login (cannot verify if logged in)')
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
if not self._is_logged_in():
|
||||
self.raise_login_required('Login is required to access any AnimeLab content')
|
||||
|
||||
|
||||
class AnimeLabIE(AnimeLabBaseIE):
|
||||
|
|
|
@ -53,11 +53,7 @@ class AnimeOnDemandIE(InfoExtractor):
|
|||
'only_matching': True,
|
||||
}]
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login page')
|
||||
|
||||
|
@ -93,9 +89,6 @@ class AnimeOnDemandIE(InfoExtractor):
|
|||
raise ExtractorError('Unable to login: %s' % error, expected=True)
|
||||
raise ExtractorError('Unable to log in')
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _real_extract(self, url):
|
||||
anime_id = self._match_id(url)
|
||||
|
||||
|
|
|
@ -37,9 +37,6 @@ class AtresPlayerIE(InfoExtractor):
|
|||
]
|
||||
_API_BASE = 'https://api.atresplayer.com/'
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _handle_error(self, e, code):
|
||||
if isinstance(e.cause, compat_HTTPError) and e.cause.code == code:
|
||||
error = self._parse_json(e.cause.read(), None)
|
||||
|
@ -48,11 +45,7 @@ class AtresPlayerIE(InfoExtractor):
|
|||
raise ExtractorError(error['error_description'], expected=True)
|
||||
raise
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
self._request_webpage(
|
||||
self._API_BASE + 'login', None, 'Downloading login page')
|
||||
|
||||
|
|
|
@ -264,11 +264,7 @@ class BBCCoUkIE(InfoExtractor):
|
|||
'only_matching': True,
|
||||
}]
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading signin page')
|
||||
|
||||
|
@ -294,9 +290,6 @@ class BBCCoUkIE(InfoExtractor):
|
|||
'Unable to login: %s' % error, expected=True)
|
||||
raise ExtractorError('Unable to log in')
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
class MediaSelectionError(Exception):
|
||||
def __init__(self, id):
|
||||
self.id = id
|
||||
|
|
|
@ -821,11 +821,7 @@ class BiliIntlBaseIE(InfoExtractor):
|
|||
'extractor_key': BiliIntlIE.ie_key(),
|
||||
}
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
try:
|
||||
from Cryptodome.PublicKey import RSA
|
||||
from Cryptodome.Cipher import PKCS1_v1_5
|
||||
|
@ -856,9 +852,6 @@ class BiliIntlBaseIE(InfoExtractor):
|
|||
else:
|
||||
raise ExtractorError('Unable to log in')
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
|
||||
class BiliIntlIE(BiliIntlBaseIE):
|
||||
_VALID_URL = r'https?://(?:www\.)?bili(?:bili\.tv|intl\.com)/(?:[a-z]{2}/)?play/(?P<season_id>\d+)/(?P<id>\d+)'
|
||||
|
|
|
@ -274,14 +274,7 @@ class VrtNUIE(GigyaBaseIE):
|
|||
_APIKEY = '3_0Z2HujMtiWq_pkAjgnS2Md2E11a1AwZjYiBETtwNE-EoEHDINgtnvcAOpNgmrVGy'
|
||||
_CONTEXT_ID = 'R3595707040'
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
auth_info = self._gigya_login({
|
||||
'APIKey': self._APIKEY,
|
||||
'targetEnv': 'jssdk',
|
||||
|
|
|
@ -432,7 +432,15 @@ class InfoExtractor(object):
|
|||
|
||||
Subclasses may also override suitable() if necessary, but ensure the function
|
||||
signature is preserved and that this function imports everything it needs
|
||||
(except other extractors), so that lazy_extractors works correctly
|
||||
(except other extractors), so that lazy_extractors works correctly.
|
||||
|
||||
To support username + password (or netrc) login, the extractor must define a
|
||||
_NETRC_MACHINE and re-define _perform_login(username, password) and
|
||||
(optionally) _initialize_pre_login() methods. The _perform_login method will
|
||||
be called between _initialize_pre_login and _real_initialize if credentials
|
||||
are passed by the user. In cases where it is necessary to have the login
|
||||
process as part of the extraction rather than initialization, _perform_login
|
||||
can be left undefined.
|
||||
|
||||
_GEO_BYPASS attribute may be set to False in order to disable
|
||||
geo restriction bypass mechanisms for a particular extractor.
|
||||
|
@ -460,9 +468,10 @@ class InfoExtractor(object):
|
|||
_GEO_COUNTRIES = None
|
||||
_GEO_IP_BLOCKS = None
|
||||
_WORKING = True
|
||||
_NETRC_MACHINE = None
|
||||
|
||||
_LOGIN_HINTS = {
|
||||
'any': 'Use --cookies, --username and --password, or --netrc to provide account credentials',
|
||||
'any': 'Use --cookies, --cookies-from-browser, --username and --password, or --netrc to provide account credentials',
|
||||
'cookies': (
|
||||
'Use --cookies-from-browser or --cookies for the authentication. '
|
||||
'See https://github.com/ytdl-org/youtube-dl#how-do-i-pass-cookies-to-youtube-dl for how to manually pass cookies'),
|
||||
|
@ -512,6 +521,10 @@ class InfoExtractor(object):
|
|||
"""Getter method for _WORKING."""
|
||||
return cls._WORKING
|
||||
|
||||
@classmethod
|
||||
def supports_login(cls):
|
||||
return bool(cls._NETRC_MACHINE)
|
||||
|
||||
def initialize(self):
|
||||
"""Initializes an instance (authentication, etc)."""
|
||||
self._printed_messages = set()
|
||||
|
@ -520,6 +533,13 @@ class InfoExtractor(object):
|
|||
'ip_blocks': self._GEO_IP_BLOCKS,
|
||||
})
|
||||
if not self._ready:
|
||||
self._initialize_pre_login()
|
||||
if self.supports_login():
|
||||
username, password = self._get_login_info()
|
||||
if username:
|
||||
self._perform_login(username, password)
|
||||
elif self.get_param('username') and False not in (self.IE_DESC, self._NETRC_MACHINE):
|
||||
self.report_warning(f'Login with password is not supported for this website. {self._LOGIN_HINTS["cookies"]}')
|
||||
self._real_initialize()
|
||||
self._ready = True
|
||||
|
||||
|
@ -665,6 +685,14 @@ class InfoExtractor(object):
|
|||
"""Sets a YoutubeDL instance as the downloader for this IE."""
|
||||
self._downloader = downloader
|
||||
|
||||
def _initialize_pre_login(self):
|
||||
""" Intialization before login. Redefine in subclasses."""
|
||||
pass
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
""" Login with username and password. Redefine in subclasses."""
|
||||
pass
|
||||
|
||||
def _real_initialize(self):
|
||||
"""Real initialization process. Redefine in subclasses."""
|
||||
pass
|
||||
|
@ -1098,12 +1126,15 @@ class InfoExtractor(object):
|
|||
|
||||
def raise_login_required(
|
||||
self, msg='This video is only available for registered users',
|
||||
metadata_available=False, method='any'):
|
||||
metadata_available=False, method=NO_DEFAULT):
|
||||
if metadata_available and (
|
||||
self.get_param('ignore_no_formats_error') or self.get_param('wait_for_video')):
|
||||
self.report_warning(msg)
|
||||
return
|
||||
if method is NO_DEFAULT:
|
||||
method = 'any' if self.supports_login() else 'cookies'
|
||||
if method is not None:
|
||||
assert method in self._LOGIN_HINTS, 'Invalid login method'
|
||||
msg = '%s. %s' % (msg, self._LOGIN_HINTS[method])
|
||||
raise ExtractorError(msg, expected=True)
|
||||
|
||||
|
@ -3680,9 +3711,8 @@ class InfoExtractor(object):
|
|||
def mark_watched(self, *args, **kwargs):
|
||||
if not self.get_param('mark_watched', False):
|
||||
return
|
||||
if (hasattr(self, '_NETRC_MACHINE') and self._get_login_info()[0] is not None
|
||||
or self.get_param('cookiefile')
|
||||
or self.get_param('cookiesfrombrowser')):
|
||||
if (self.supports_login() and self._get_login_info()[0] is not None
|
||||
or self.get_param('cookiefile') or self.get_param('cookiesfrombrowser')):
|
||||
self._mark_watched(*args, **kwargs)
|
||||
|
||||
def _mark_watched(self, *args, **kwargs):
|
||||
|
|
|
@ -57,10 +57,7 @@ class CrunchyrollBaseIE(InfoExtractor):
|
|||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
})
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
if self._get_cookies(self._LOGIN_URL).get('etp_rt'):
|
||||
return
|
||||
|
||||
|
@ -89,9 +86,6 @@ class CrunchyrollBaseIE(InfoExtractor):
|
|||
if not self._get_cookies(self._LOGIN_URL).get('etp_rt'):
|
||||
raise ExtractorError('Login succeeded but did not set etp_rt cookie')
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
@staticmethod
|
||||
def _add_skip_wall(url):
|
||||
parsed_url = compat_urlparse.urlparse(url)
|
||||
|
|
|
@ -33,14 +33,11 @@ class CuriosityStreamBaseIE(InfoExtractor):
|
|||
self._handle_errors(result)
|
||||
return result['data']
|
||||
|
||||
def _real_initialize(self):
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
result = self._download_json(
|
||||
'https://api.curiositystream.com/v1/login', None,
|
||||
note='Logging in', data=urlencode_postdata({
|
||||
'email': email,
|
||||
'email': username,
|
||||
'password': password,
|
||||
}))
|
||||
self._handle_errors(result)
|
||||
|
|
|
@ -45,10 +45,7 @@ class DigitalConcertHallIE(InfoExtractor):
|
|||
'playlist_count': 3,
|
||||
}]
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if not username:
|
||||
self.raise_login_required()
|
||||
def _perform_login(self, username, password):
|
||||
token_response = self._download_json(
|
||||
self._OAUTH_URL,
|
||||
None, 'Obtaining token', errnote='Unable to obtain token', data=urlencode_postdata({
|
||||
|
@ -78,7 +75,8 @@ class DigitalConcertHallIE(InfoExtractor):
|
|||
self.raise_login_required(msg='Login info incorrect')
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
if not self._ACCESS_TOKEN:
|
||||
self.raise_login_required(method='password')
|
||||
|
||||
def _entries(self, items, language, **kwargs):
|
||||
for item in items:
|
||||
|
|
|
@ -39,11 +39,7 @@ class EroProfileIE(InfoExtractor):
|
|||
'skip': 'Requires login',
|
||||
}]
|
||||
|
||||
def _login(self):
|
||||
(username, password) = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
query = compat_urllib_parse_urlencode({
|
||||
'username': username,
|
||||
'password': password,
|
||||
|
@ -62,9 +58,6 @@ class EroProfileIE(InfoExtractor):
|
|||
r'<script[^>]+?src="([^"]+)"', login_page, 'login redirect url')
|
||||
self._download_webpage(redirect_url, None, False)
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _real_extract(self, url):
|
||||
display_id = self._match_id(url)
|
||||
|
||||
|
|
|
@ -329,11 +329,7 @@ class FacebookIE(InfoExtractor):
|
|||
urls.append(mobj.group('url'))
|
||||
return urls
|
||||
|
||||
def _login(self):
|
||||
useremail, password = self._get_login_info()
|
||||
if useremail is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_page_req = sanitized_Request(self._LOGIN_URL)
|
||||
self._set_cookie('facebook.com', 'locale', 'en_US')
|
||||
login_page = self._download_webpage(login_page_req, None,
|
||||
|
@ -345,7 +341,7 @@ class FacebookIE(InfoExtractor):
|
|||
lgnrnd = self._search_regex(r'name="lgnrnd" value="([^"]*?)"', login_page, 'lgnrnd')
|
||||
|
||||
login_form = {
|
||||
'email': useremail,
|
||||
'email': username,
|
||||
'pass': password,
|
||||
'lsd': lsd,
|
||||
'lgnrnd': lgnrnd,
|
||||
|
@ -392,9 +388,6 @@ class FacebookIE(InfoExtractor):
|
|||
self.report_warning('unable to log in: %s' % error_to_compat_str(err))
|
||||
return
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _extract_from_url(self, url, video_id):
|
||||
webpage = self._download_webpage(
|
||||
url.replace('://m.facebook.com/', '://www.facebook.com/'), video_id)
|
||||
|
|
|
@ -49,30 +49,26 @@ class FancodeVodIE(InfoExtractor):
|
|||
'referer': 'https://fancode.com',
|
||||
}
|
||||
|
||||
def _login(self):
|
||||
def _perform_login(self, username, password):
|
||||
# Access tokens are shortlived, so get them using the refresh token.
|
||||
username, password = self._get_login_info()
|
||||
if username == 'refresh' and password is not None:
|
||||
self.report_login()
|
||||
data = '''{
|
||||
"query":"mutation RefreshToken($refreshToken: String\\u0021) { refreshToken(refreshToken: $refreshToken) { accessToken }}",
|
||||
"variables":{
|
||||
"refreshToken":"%s"
|
||||
},
|
||||
"operationName":"RefreshToken"
|
||||
}''' % password
|
||||
|
||||
token_json = self.download_gql('refresh token', data, "Getting the Access token")
|
||||
self._ACCESS_TOKEN = try_get(token_json, lambda x: x['data']['refreshToken']['accessToken'])
|
||||
if self._ACCESS_TOKEN is None:
|
||||
self.report_warning('Failed to get Access token')
|
||||
else:
|
||||
self.headers.update({'Authorization': 'Bearer %s' % self._ACCESS_TOKEN})
|
||||
elif username is not None:
|
||||
if username != 'refresh':
|
||||
self.report_warning(f'Login using username and password is not currently supported. {self._LOGIN_HINT}')
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
self.report_login()
|
||||
data = '''{
|
||||
"query":"mutation RefreshToken($refreshToken: String\\u0021) { refreshToken(refreshToken: $refreshToken) { accessToken }}",
|
||||
"variables":{
|
||||
"refreshToken":"%s"
|
||||
},
|
||||
"operationName":"RefreshToken"
|
||||
}''' % password
|
||||
|
||||
token_json = self.download_gql('refresh token', data, "Getting the Access token")
|
||||
self._ACCESS_TOKEN = try_get(token_json, lambda x: x['data']['refreshToken']['accessToken'])
|
||||
if self._ACCESS_TOKEN is None:
|
||||
self.report_warning('Failed to get Access token')
|
||||
else:
|
||||
self.headers.update({'Authorization': 'Bearer %s' % self._ACCESS_TOKEN})
|
||||
|
||||
def _check_login_required(self, is_available, is_premium):
|
||||
msg = None
|
||||
|
|
|
@ -28,14 +28,7 @@ class FrontendMastersBaseIE(InfoExtractor):
|
|||
'high': {'width': 1920, 'height': 1080}
|
||||
}
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
(username, password) = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login page')
|
||||
|
||||
|
|
|
@ -36,9 +36,8 @@ class FunimationBaseIE(InfoExtractor):
|
|||
note='Checking geo-location', errnote='Unable to fetch geo-location information'),
|
||||
'region') or 'US'
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
def _perform_login(self, username, password):
|
||||
if self._TOKEN:
|
||||
return
|
||||
try:
|
||||
data = self._download_json(
|
||||
|
@ -47,7 +46,7 @@ class FunimationBaseIE(InfoExtractor):
|
|||
'username': username,
|
||||
'password': password,
|
||||
}))
|
||||
return data['token']
|
||||
FunimationBaseIE._TOKEN = data['token']
|
||||
except ExtractorError as e:
|
||||
if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401:
|
||||
error = self._parse_json(e.cause.read().decode(), None)['error']
|
||||
|
@ -90,8 +89,6 @@ class FunimationPageIE(FunimationBaseIE):
|
|||
def _real_initialize(self):
|
||||
if not self._REGION:
|
||||
FunimationBaseIE._REGION = self._get_region()
|
||||
if not self._TOKEN:
|
||||
FunimationBaseIE._TOKEN = self._login()
|
||||
|
||||
def _real_extract(self, url):
|
||||
locale, show, episode = self._match_valid_url(url).group('lang', 'show', 'episode')
|
||||
|
@ -154,10 +151,6 @@ class FunimationIE(FunimationBaseIE):
|
|||
},
|
||||
}]
|
||||
|
||||
def _real_initialize(self):
|
||||
if not self._TOKEN:
|
||||
FunimationBaseIE._TOKEN = self._login()
|
||||
|
||||
@staticmethod
|
||||
def _get_experiences(episode):
|
||||
for lang, lang_data in episode.get('languages', {}).items():
|
||||
|
|
|
@ -56,24 +56,22 @@ class GaiaIE(InfoExtractor):
|
|||
def _real_initialize(self):
|
||||
auth = self._get_cookies('https://www.gaia.com/').get('auth')
|
||||
if auth:
|
||||
auth = self._parse_json(
|
||||
compat_urllib_parse_unquote(auth.value),
|
||||
None, fatal=False)
|
||||
if not auth:
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
auth = self._download_json(
|
||||
'https://auth.gaia.com/v1/login',
|
||||
None, data=urlencode_postdata({
|
||||
'username': username,
|
||||
'password': password
|
||||
}))
|
||||
if auth.get('success') is False:
|
||||
raise ExtractorError(', '.join(auth['messages']), expected=True)
|
||||
if auth:
|
||||
auth = self._parse_json(compat_urllib_parse_unquote(auth.value), None, fatal=False)
|
||||
self._jwt = auth.get('jwt')
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
if self._jwt:
|
||||
return
|
||||
auth = self._download_json(
|
||||
'https://auth.gaia.com/v1/login',
|
||||
None, data=urlencode_postdata({
|
||||
'username': username,
|
||||
'password': password
|
||||
}))
|
||||
if auth.get('success') is False:
|
||||
raise ExtractorError(', '.join(auth['messages']), expected=True)
|
||||
self._jwt = auth.get('jwt')
|
||||
|
||||
def _real_extract(self, url):
|
||||
display_id, vtype = self._match_valid_url(url).groups()
|
||||
node_id = self._download_json(
|
||||
|
|
|
@ -153,6 +153,7 @@ class GenericIE(InfoExtractor):
|
|||
IE_DESC = 'Generic downloader that works on some sites'
|
||||
_VALID_URL = r'.*'
|
||||
IE_NAME = 'generic'
|
||||
_NETRC_MACHINE = False # Supress username warning
|
||||
_TESTS = [
|
||||
# Direct link to a video
|
||||
{
|
||||
|
|
|
@ -35,18 +35,14 @@ class HiDiveIE(InfoExtractor):
|
|||
'skip': 'Requires Authentication',
|
||||
}]
|
||||
|
||||
def _real_initialize(self):
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
webpage = self._download_webpage(self._LOGIN_URL, None)
|
||||
form = self._search_regex(
|
||||
r'(?s)<form[^>]+action="/account/login"[^>]*>(.+?)</form>',
|
||||
webpage, 'login form')
|
||||
data = self._hidden_inputs(form)
|
||||
data.update({
|
||||
'Email': email,
|
||||
'Email': username,
|
||||
'Password': password,
|
||||
})
|
||||
self._download_webpage(
|
||||
|
|
|
@ -27,8 +27,9 @@ class HRTiBaseIE(InfoExtractor):
|
|||
_APP_VERSION = '1.1'
|
||||
_APP_PUBLICATION_ID = 'all_in_one'
|
||||
_API_URL = 'http://clientapi.hrt.hr/client_api.php/config/identify/format/json'
|
||||
_token = None
|
||||
|
||||
def _initialize_api(self):
|
||||
def _initialize_pre_login(self):
|
||||
init_data = {
|
||||
'application_publication_id': self._APP_PUBLICATION_ID
|
||||
}
|
||||
|
@ -64,12 +65,7 @@ class HRTiBaseIE(InfoExtractor):
|
|||
|
||||
self._logout_url = modules['user']['resources']['logout']['uri']
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
# TODO: figure out authentication with cookies
|
||||
if username is None or password is None:
|
||||
self.raise_login_required()
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
auth_data = {
|
||||
'username': username,
|
||||
'password': password,
|
||||
|
@ -94,8 +90,9 @@ class HRTiBaseIE(InfoExtractor):
|
|||
self._token = auth_info['secure_streaming_token']
|
||||
|
||||
def _real_initialize(self):
|
||||
self._initialize_api()
|
||||
self._login()
|
||||
if not self._token:
|
||||
# TODO: figure out authentication with cookies
|
||||
self.raise_login_required(method='password')
|
||||
|
||||
|
||||
class HRTiIE(HRTiBaseIE):
|
||||
|
|
|
@ -21,25 +21,26 @@ class ImgGamingBaseIE(InfoExtractor):
|
|||
_REALM = None
|
||||
_VALID_URL_TEMPL = r'https?://(?P<domain>%s)/(?P<type>live|playlist|video)/(?P<id>\d+)(?:\?.*?\bplaylistId=(?P<playlist_id>\d+))?'
|
||||
|
||||
def _real_initialize(self):
|
||||
def _initialize_pre_login(self):
|
||||
self._HEADERS = {
|
||||
'Realm': 'dce.' + self._REALM,
|
||||
'x-api-key': self._API_KEY,
|
||||
}
|
||||
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
self.raise_login_required()
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
p_headers = self._HEADERS.copy()
|
||||
p_headers['Content-Type'] = 'application/json'
|
||||
self._HEADERS['Authorization'] = 'Bearer ' + self._download_json(
|
||||
self._API_BASE + 'login',
|
||||
None, 'Logging in', data=json.dumps({
|
||||
'id': email,
|
||||
'id': username,
|
||||
'secret': password,
|
||||
}).encode(), headers=p_headers)['authorisationToken']
|
||||
|
||||
def _real_initialize(self):
|
||||
if not self._HEADERS.get('Authorization'):
|
||||
self.raise_login_required(method='password')
|
||||
|
||||
def _call_api(self, path, media_id):
|
||||
return self._download_json(
|
||||
self._API_BASE + path + media_id, media_id, headers=self._HEADERS)
|
||||
|
|
|
@ -29,9 +29,8 @@ class InstagramBaseIE(InfoExtractor):
|
|||
_NETRC_MACHINE = 'instagram'
|
||||
_IS_LOGGED_IN = False
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None or self._IS_LOGGED_IN:
|
||||
def _perform_login(self, username, password):
|
||||
if self._IS_LOGGED_IN:
|
||||
return
|
||||
|
||||
login_webpage = self._download_webpage(
|
||||
|
@ -72,9 +71,6 @@ class InstagramBaseIE(InfoExtractor):
|
|||
raise ExtractorError('Unable to login')
|
||||
InstagramBaseIE._IS_LOGGED_IN = True
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _get_count(self, media, kind, *keys):
|
||||
return traverse_obj(
|
||||
media, (kind, 'count'), *((f'edge_media_{key}', 'count') for key in keys),
|
||||
|
|
|
@ -65,11 +65,9 @@ class IPrimaIE(InfoExtractor):
|
|||
'only_matching': True,
|
||||
}]
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
|
||||
if username is None or password is None:
|
||||
self.raise_login_required('Login is required to access any iPrima content', method='password')
|
||||
def _perform_login(self, username, password):
|
||||
if self.access_token:
|
||||
return
|
||||
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, note='Downloading login page',
|
||||
|
@ -105,16 +103,16 @@ class IPrimaIE(InfoExtractor):
|
|||
if self.access_token is None:
|
||||
raise ExtractorError('Getting token failed', expected=True)
|
||||
|
||||
def _real_initialize(self):
|
||||
if not self.access_token:
|
||||
self.raise_login_required('Login is required to access any iPrima content', method='password')
|
||||
|
||||
def _raise_access_error(self, error_code):
|
||||
if error_code == 'PLAY_GEOIP_DENIED':
|
||||
self.raise_geo_restricted(countries=['CZ'], metadata_available=True)
|
||||
elif error_code is not None:
|
||||
self.raise_no_formats('Access to stream infos forbidden', expected=True)
|
||||
|
||||
def _real_initialize(self):
|
||||
if not self.access_token:
|
||||
self._login()
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
|
||||
|
|
|
@ -241,9 +241,6 @@ class IqiyiIE(InfoExtractor):
|
|||
'18': 7, # 1080p
|
||||
}
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
@staticmethod
|
||||
def _rsa_fun(data):
|
||||
# public key extracted from http://static.iqiyi.com/js/qiyiV2/20160129180840/jobs/i18n/i18nIndex.js
|
||||
|
@ -252,12 +249,7 @@ class IqiyiIE(InfoExtractor):
|
|||
|
||||
return ohdave_rsa_encrypt(data, e, N)
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
|
||||
# No authentication to be performed
|
||||
if not username:
|
||||
return True
|
||||
def _perform_login(self, username, password):
|
||||
|
||||
data = self._download_json(
|
||||
'http://kylin.iqiyi.com/get_token', None,
|
||||
|
|
|
@ -22,14 +22,7 @@ class LecturioBaseIE(InfoExtractor):
|
|||
_LOGIN_URL = 'https://app.lecturio.com/en/login'
|
||||
_NETRC_MACHINE = 'lecturio'
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
# Sets some cookies
|
||||
_, urlh = self._download_webpage_handle(
|
||||
self._LOGIN_URL, None, 'Downloading login popup')
|
||||
|
|
|
@ -25,12 +25,9 @@ class LinkedInBaseIE(InfoExtractor):
|
|||
_NETRC_MACHINE = 'linkedin'
|
||||
_logged_in = False
|
||||
|
||||
def _real_initialize(self):
|
||||
def _perform_login(self, username, password):
|
||||
if self._logged_in:
|
||||
return
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
return
|
||||
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login page')
|
||||
|
@ -39,7 +36,7 @@ class LinkedInBaseIE(InfoExtractor):
|
|||
default='https://www.linkedin.com/uas/login-submit', group='url'))
|
||||
data = self._hidden_inputs(login_page)
|
||||
data.update({
|
||||
'session_key': email,
|
||||
'session_key': username,
|
||||
'session_password': password,
|
||||
})
|
||||
login_submit_page = self._download_webpage(
|
||||
|
|
|
@ -75,14 +75,7 @@ class LinuxAcademyIE(InfoExtractor):
|
|||
_CLIENT_ID = 'KaWxNn1C2Gc7n83W9OFeXltd8Utb5vvx'
|
||||
_NETRC_MACHINE = 'linuxacademy'
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
def random_string():
|
||||
return ''.join([
|
||||
random.choice('0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._~')
|
||||
|
|
|
@ -21,9 +21,6 @@ class LyndaBaseIE(InfoExtractor):
|
|||
_ACCOUNT_CREDENTIALS_HINT = 'Use --username and --password options to provide lynda.com account credentials.'
|
||||
_NETRC_MACHINE = 'lynda'
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
@staticmethod
|
||||
def _check_error(json_string, key_or_keys):
|
||||
keys = [key_or_keys] if isinstance(key_or_keys, compat_str) else key_or_keys
|
||||
|
@ -32,7 +29,7 @@ class LyndaBaseIE(InfoExtractor):
|
|||
if error:
|
||||
raise ExtractorError('Unable to login: %s' % error, expected=True)
|
||||
|
||||
def _login_step(self, form_html, fallback_action_url, extra_form_data, note, referrer_url):
|
||||
def _perform_login_step(self, form_html, fallback_action_url, extra_form_data, note, referrer_url):
|
||||
action_url = self._search_regex(
|
||||
r'<form[^>]+action=(["\'])(?P<url>.+?)\1', form_html,
|
||||
'post url', default=fallback_action_url, group='url')
|
||||
|
@ -55,11 +52,7 @@ class LyndaBaseIE(InfoExtractor):
|
|||
|
||||
return response, action_url
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
# Step 1: download signin page
|
||||
signin_page = self._download_webpage(
|
||||
self._SIGNIN_URL, None, 'Downloading signin page')
|
||||
|
|
|
@ -148,14 +148,12 @@ class NebulaBaseIE(InfoExtractor):
|
|||
'creator': episode['channel_title'],
|
||||
}
|
||||
|
||||
def _login(self):
|
||||
def _perform_login(self, username=None, password=None):
|
||||
# FIXME: username should be passed from here to inner functions
|
||||
self._nebula_api_token = self._retrieve_nebula_api_token()
|
||||
self._nebula_bearer_token = self._fetch_nebula_bearer_token()
|
||||
self._zype_access_token = self._fetch_zype_access_token()
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
|
||||
class NebulaIE(NebulaBaseIE):
|
||||
_VALID_URL = r'https?://(?:www\.)?(?:watchnebula\.com|nebula\.app)/videos/(?P<id>[-\w]+)'
|
||||
|
|
|
@ -183,16 +183,7 @@ class NiconicoIE(InfoExtractor):
|
|||
'Origin': 'https://www.nicovideo.jp',
|
||||
}
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
# No authentication to be performed
|
||||
if not username:
|
||||
return True
|
||||
|
||||
# Log in
|
||||
def _perform_login(self, username, password):
|
||||
login_ok = True
|
||||
login_form_strs = {
|
||||
'mail_tel': username,
|
||||
|
|
|
@ -43,15 +43,7 @@ class NJPWWorldIE(InfoExtractor):
|
|||
|
||||
_LOGIN_URL = 'https://front.njpwworld.com/auth/login'
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
# No authentication to be performed
|
||||
if not username:
|
||||
return True
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
# Setup session (will set necessary cookies)
|
||||
self._request_webpage(
|
||||
'https://njpwworld.com/', None, note='Setting up session')
|
||||
|
|
|
@ -61,14 +61,7 @@ class NocoIE(InfoExtractor):
|
|||
}
|
||||
]
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login = self._download_json(
|
||||
self._LOGIN_URL, None, 'Logging in',
|
||||
data=urlencode_postdata({
|
||||
|
|
|
@ -47,10 +47,7 @@ class PacktPubIE(PacktPubBaseIE):
|
|||
_NETRC_MACHINE = 'packtpub'
|
||||
_TOKEN = None
|
||||
|
||||
def _real_initialize(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
try:
|
||||
self._TOKEN = self._download_json(
|
||||
'https://services.packtpub.com/auth-v1/users/tokens', None,
|
||||
|
|
|
@ -88,11 +88,7 @@ class PatreonIE(InfoExtractor):
|
|||
# Currently Patreon exposes download URL via hidden CSS, so login is not
|
||||
# needed. Keeping this commented for when this inevitably changes.
|
||||
'''
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_form = {
|
||||
'redirectUrl': 'http://www.patreon.com/',
|
||||
'email': username,
|
||||
|
@ -108,8 +104,6 @@ class PatreonIE(InfoExtractor):
|
|||
if re.search(r'onLoginFailed', login_page):
|
||||
raise ExtractorError('Unable to login, incorrect username and/or password', expected=True)
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
'''
|
||||
|
||||
def _real_extract(self, url):
|
||||
|
|
|
@ -29,13 +29,9 @@ class PiaproIE(InfoExtractor):
|
|||
}
|
||||
}]
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login_status = self._login()
|
||||
_login_status = False
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if not username:
|
||||
return False
|
||||
def _perform_login(self, username, password):
|
||||
login_ok = True
|
||||
login_form_strs = {
|
||||
'_username': username,
|
||||
|
@ -57,7 +53,7 @@ class PiaproIE(InfoExtractor):
|
|||
if not login_ok:
|
||||
self.report_warning(
|
||||
'unable to log in: bad username or password')
|
||||
return login_ok
|
||||
self._login_status = login_ok
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
|
|
|
@ -22,14 +22,7 @@ class PlatziBaseIE(InfoExtractor):
|
|||
_LOGIN_URL = 'https://platzi.com/login/'
|
||||
_NETRC_MACHINE = 'platzi'
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login page')
|
||||
|
||||
|
|
|
@ -38,14 +38,10 @@ class PlayPlusTVIE(InfoExtractor):
|
|||
'Authorization': 'Bearer ' + self._token,
|
||||
}, query=query)
|
||||
|
||||
def _real_initialize(self):
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
self.raise_login_required()
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
req = PUTRequest(
|
||||
'https://api.playplus.tv/api/web/login', json.dumps({
|
||||
'email': email,
|
||||
'email': username,
|
||||
'password': password,
|
||||
}).encode(), {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
|
@ -61,6 +57,10 @@ class PlayPlusTVIE(InfoExtractor):
|
|||
|
||||
self._profile = self._call_api('Profiles')['list'][0]['_id']
|
||||
|
||||
def _real_initialize(self):
|
||||
if not self._token:
|
||||
self.raise_login_required(method='password')
|
||||
|
||||
def _real_extract(self, url):
|
||||
project_id, media_id = self._match_valid_url(url).groups()
|
||||
media = self._call_api(
|
||||
|
|
|
@ -162,14 +162,7 @@ query viewClip {
|
|||
}
|
||||
}'''
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login page')
|
||||
|
||||
|
|
|
@ -15,11 +15,9 @@ class PokerGoBaseIE(InfoExtractor):
|
|||
_AUTH_TOKEN = None
|
||||
_PROPERTY_ID = '1dfb3940-7d53-4980-b0b0-f28b369a000d'
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if not username:
|
||||
self.raise_login_required(method='password')
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
if self._AUTH_TOKEN:
|
||||
return
|
||||
self.report_login()
|
||||
PokerGoBaseIE._AUTH_TOKEN = self._download_json(
|
||||
f'https://subscription.pokergo.com/properties/{self._PROPERTY_ID}/sign-in', None,
|
||||
|
@ -30,7 +28,7 @@ class PokerGoBaseIE(InfoExtractor):
|
|||
|
||||
def _real_initialize(self):
|
||||
if not self._AUTH_TOKEN:
|
||||
self._login()
|
||||
self.raise_login_required(method='password')
|
||||
|
||||
|
||||
class PokerGoIE(PokerGoBaseIE):
|
||||
|
|
|
@ -21,10 +21,7 @@ class RoosterTeethBaseIE(InfoExtractor):
|
|||
_API_BASE = 'https://svod-be.roosterteeth.com'
|
||||
_API_BASE_URL = f'{_API_BASE}/api/v1'
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
if self._get_cookies(self._API_BASE_URL).get('rt_access_token'):
|
||||
return
|
||||
|
||||
|
@ -47,9 +44,6 @@ class RoosterTeethBaseIE(InfoExtractor):
|
|||
msg += ': ' + error
|
||||
self.report_warning(msg)
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _extract_video_info(self, data):
|
||||
thumbnails = []
|
||||
for image in traverse_obj(data, ('included', 'images')):
|
||||
|
|
|
@ -25,14 +25,7 @@ class SafariBaseIE(InfoExtractor):
|
|||
|
||||
LOGGED_IN = False
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
_, urlh = self._download_webpage_handle(
|
||||
'https://learning.oreilly.com/accounts/login-check/', None,
|
||||
'Downloading login page')
|
||||
|
|
|
@ -14,14 +14,7 @@ class SCTEBaseIE(InfoExtractor):
|
|||
_LOGIN_URL = 'https://www.scte.org/SCTE/Sign_In.aspx'
|
||||
_NETRC_MACHINE = 'scte'
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_popup = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login popup')
|
||||
|
||||
|
|
|
@ -79,16 +79,12 @@ class ShahidIE(ShahidBaseIE):
|
|||
'only_matching': True
|
||||
}]
|
||||
|
||||
def _real_initialize(self):
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
try:
|
||||
user_data = self._download_json(
|
||||
'https://shahid.mbc.net/wd/service/users/login',
|
||||
None, 'Logging in', data=json.dumps({
|
||||
'email': email,
|
||||
'email': username,
|
||||
'password': password,
|
||||
'basic': 'false',
|
||||
}).encode('utf-8'), headers={
|
||||
|
|
|
@ -75,9 +75,12 @@ class SonyLIVIE(InfoExtractor):
|
|||
t[i] = '{:x}'.format(3 & n | 8)
|
||||
return ''.join(t) + '-' + str(int(time.time() * 1000))
|
||||
|
||||
def _login(self, username, password):
|
||||
def _perform_login(self, username, password):
|
||||
self._HEADERS['device_id'] = self._get_device_id()
|
||||
self._HEADERS['content-type'] = 'application/json'
|
||||
|
||||
if username.lower() == 'token' and len(password) > 1198:
|
||||
return password
|
||||
self._HEADERS['authorization'] = password
|
||||
elif len(username) != 10 or not username.isdigit():
|
||||
raise ExtractorError(f'Invalid username/password; {self._LOGIN_HINT}')
|
||||
|
||||
|
@ -99,7 +102,7 @@ class SonyLIVIE(InfoExtractor):
|
|||
None, note='Verifying OTP', data=data.encode(), headers=self._HEADERS)
|
||||
if otp_verify_json['resultCode'] == 'KO':
|
||||
raise ExtractorError(otp_request_json['message'], expected=True)
|
||||
return otp_verify_json['resultObj']['accessToken']
|
||||
self._HEADERS['authorization'] = otp_verify_json['resultObj']['accessToken']
|
||||
|
||||
def _call_api(self, version, path, video_id):
|
||||
try:
|
||||
|
@ -118,13 +121,8 @@ class SonyLIVIE(InfoExtractor):
|
|||
raise ExtractorError(message)
|
||||
raise
|
||||
|
||||
def _real_initialize(self):
|
||||
def _initialize_pre_login(self):
|
||||
self._HEADERS['security_token'] = self._call_api('1.4', 'ALL/GETTOKEN', None)
|
||||
username, password = self._get_login_info()
|
||||
if username:
|
||||
self._HEADERS['device_id'] = self._get_device_id()
|
||||
self._HEADERS['content-type'] = 'application/json'
|
||||
self._HEADERS['authorization'] = self._login(username, password)
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
|
|
|
@ -107,30 +107,24 @@ class SoundcloudBaseIE(InfoExtractor):
|
|||
return False
|
||||
raise
|
||||
|
||||
def _real_initialize(self):
|
||||
def _initialize_pre_login(self):
|
||||
self._CLIENT_ID = self._downloader.cache.load('soundcloud', 'client_id') or 'a3e059563d7fd3372b49b37f00a00bcf'
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
if username == 'oauth' and password is not None:
|
||||
self._access_token = password
|
||||
query = self._API_AUTH_QUERY_TEMPLATE % self._CLIENT_ID
|
||||
payload = {'session': {'access_token': self._access_token}}
|
||||
token_verification = sanitized_Request(self._API_VERIFY_AUTH_TOKEN % query, json.dumps(payload).encode('utf-8'))
|
||||
response = self._download_json(token_verification, None, note='Verifying login token...', fatal=False)
|
||||
if response is not False:
|
||||
self._HEADERS = {'Authorization': 'OAuth ' + self._access_token}
|
||||
self.report_login()
|
||||
else:
|
||||
self.report_warning('Provided authorization token seems to be invalid. Continue as guest')
|
||||
elif username is not None:
|
||||
def _perform_login(self, username, password):
|
||||
if username != 'oauth':
|
||||
self.report_warning(
|
||||
'Login using username and password is not currently supported. '
|
||||
'Use "--username oauth --password <oauth_token>" to login using an oauth token')
|
||||
self._access_token = password
|
||||
query = self._API_AUTH_QUERY_TEMPLATE % self._CLIENT_ID
|
||||
payload = {'session': {'access_token': self._access_token}}
|
||||
token_verification = sanitized_Request(self._API_VERIFY_AUTH_TOKEN % query, json.dumps(payload).encode('utf-8'))
|
||||
response = self._download_json(token_verification, None, note='Verifying login token...', fatal=False)
|
||||
if response is not False:
|
||||
self._HEADERS = {'Authorization': 'OAuth ' + self._access_token}
|
||||
self.report_login()
|
||||
else:
|
||||
self.report_warning('Provided authorization token seems to be invalid. Continue as guest')
|
||||
|
||||
r'''
|
||||
def genDevId():
|
||||
|
|
|
@ -40,8 +40,7 @@ class TeachableBaseIE(InfoExtractor):
|
|||
if self._logged_in:
|
||||
return
|
||||
|
||||
username, password = self._get_login_info(
|
||||
netrc_machine=self._SITES.get(site, site))
|
||||
username, password = self._get_login_info(netrc_machine=self._SITES.get(site, site))
|
||||
if username is None:
|
||||
return
|
||||
|
||||
|
|
|
@ -51,17 +51,14 @@ class TeamTreeHouseIE(InfoExtractor):
|
|||
}]
|
||||
_NETRC_MACHINE = 'teamtreehouse'
|
||||
|
||||
def _real_initialize(self):
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
|
||||
signin_page = self._download_webpage(
|
||||
'https://teamtreehouse.com/signin',
|
||||
None, 'Downloading signin page')
|
||||
data = self._form_hidden_inputs('new_user_session', signin_page)
|
||||
data.update({
|
||||
'user_session[email]': email,
|
||||
'user_session[email]': username,
|
||||
'user_session[password]': password,
|
||||
})
|
||||
error_message = get_element_by_class('error-message', self._download_webpage(
|
||||
|
|
|
@ -30,11 +30,9 @@ class TennisTVIE(InfoExtractor):
|
|||
'skip': 'Requires email and password of a subscribed account',
|
||||
}
|
||||
_NETRC_MACHINE = 'tennistv'
|
||||
_session_token = None
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if not username or not password:
|
||||
raise ExtractorError('No login info available, needed for using %s.' % self.IE_NAME, expected=True)
|
||||
def _perform_login(self, username, password):
|
||||
|
||||
login_form = {
|
||||
'Email': username,
|
||||
|
@ -63,7 +61,8 @@ class TennisTVIE(InfoExtractor):
|
|||
self._session_token = login_result['sessionToken']
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
if not self._session_token:
|
||||
raise self.raise_login_required('Login info is needed for this website', method='password')
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
|
|
|
@ -40,17 +40,14 @@ class TouTvIE(RadioCanadaIE):
|
|||
}]
|
||||
_CLIENT_KEY = '90505c8d-9c34-4f34-8da1-3a85bdc6d4f4'
|
||||
|
||||
def _real_initialize(self):
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
try:
|
||||
self._access_token = self._download_json(
|
||||
'https://services.radio-canada.ca/toutv/profiling/accounts/login',
|
||||
None, 'Logging in', data=json.dumps({
|
||||
'ClientId': self._CLIENT_KEY,
|
||||
'ClientSecret': '34026772-244b-49b6-8b06-317b30ac9a20',
|
||||
'Email': email,
|
||||
'Email': username,
|
||||
'Password': password,
|
||||
'Scope': 'id.write media-validation.read',
|
||||
}).encode(), headers={
|
||||
|
|
|
@ -54,10 +54,7 @@ class TubiTvIE(InfoExtractor):
|
|||
},
|
||||
}]
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
self.report_login()
|
||||
form_data = {
|
||||
'username': username,
|
||||
|
@ -72,9 +69,6 @@ class TubiTvIE(InfoExtractor):
|
|||
raise ExtractorError(
|
||||
'Login failed (invalid username/password)', expected=True)
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id = self._match_id(url)
|
||||
video_data = self._download_json(
|
||||
|
|
|
@ -247,11 +247,7 @@ class TumblrIE(InfoExtractor):
|
|||
|
||||
_ACCESS_TOKEN = None
|
||||
|
||||
def _real_initialize(self):
|
||||
self.get_access_token()
|
||||
self._login()
|
||||
|
||||
def get_access_token(self):
|
||||
def _initialize_pre_login(self):
|
||||
login_page = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login page', fatal=False)
|
||||
if login_page:
|
||||
|
@ -260,11 +256,7 @@ class TumblrIE(InfoExtractor):
|
|||
if not self._ACCESS_TOKEN:
|
||||
self.report_warning('Failed to get access token; metadata will be missing and some videos may not work')
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if not username:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
if not self._ACCESS_TOKEN:
|
||||
return
|
||||
|
||||
|
|
|
@ -57,14 +57,7 @@ class TwitchBaseIE(InfoExtractor):
|
|||
'VideoPlayer_ChapterSelectButtonVideo': '8d2793384aac3773beab5e59bd5d6f585aedb923d292800119e03d40cd0f9b41',
|
||||
}
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
def fail(message):
|
||||
raise ExtractorError(
|
||||
'Unable to login. Twitch said: %s' % message, expected=True)
|
||||
|
|
|
@ -168,14 +168,7 @@ class UdemyIE(InfoExtractor):
|
|||
self._handle_error(response)
|
||||
return response
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_popup = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login popup')
|
||||
|
||||
|
|
|
@ -23,11 +23,7 @@ class VidioBaseIE(InfoExtractor):
|
|||
_LOGIN_URL = 'https://www.vidio.com/users/login'
|
||||
_NETRC_MACHINE = 'vidio'
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
def is_logged_in():
|
||||
res = self._download_json(
|
||||
'https://www.vidio.com/interactions.json', None, 'Checking if logged in', fatal=False) or {}
|
||||
|
@ -63,10 +59,9 @@ class VidioBaseIE(InfoExtractor):
|
|||
'Unable to log in: %s. %s' % (reason, clean_html(subreason)), expected=True)
|
||||
raise ExtractorError('Unable to log in')
|
||||
|
||||
def _real_initialize(self):
|
||||
def _initialize_pre_login(self):
|
||||
self._api_key = self._download_json(
|
||||
'https://www.vidio.com/auth', None, data=b'')['api_key']
|
||||
self._login()
|
||||
|
||||
def _call_api(self, url, video_id, note=None):
|
||||
return self._download_json(url, video_id, note=note, headers={
|
||||
|
|
|
@ -36,9 +36,6 @@ class ViewLiftBaseIE(InfoExtractor):
|
|||
def _fetch_token(self, site, url):
|
||||
if self._TOKENS.get(site):
|
||||
return
|
||||
email, password = self._get_login_info(netrc_machine=site)
|
||||
if email:
|
||||
self.report_warning('Logging in using username and password is broken. %s' % self._LOGIN_HINTS['cookies'])
|
||||
|
||||
cookies = self._get_cookies(url)
|
||||
if cookies and cookies.get('token'):
|
||||
|
|
|
@ -99,14 +99,7 @@ class VikiBaseIE(InfoExtractor):
|
|||
self.raise_login_required(message)
|
||||
self._raise_error(message)
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
self._token = self._call_api(
|
||||
'sessions.json', None, 'Logging in', fatal=False,
|
||||
data={'username': username, 'password': password}).get('token')
|
||||
|
|
|
@ -44,12 +44,7 @@ class VimeoBaseInfoExtractor(InfoExtractor):
|
|||
_LOGIN_REQUIRED = False
|
||||
_LOGIN_URL = 'https://vimeo.com/log_in'
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
if self._LOGIN_REQUIRED:
|
||||
raise ExtractorError('No login info available, needed for using %s.' % self.IE_NAME, expected=True)
|
||||
return
|
||||
def _perform_login(self, username, password):
|
||||
webpage = self._download_webpage(
|
||||
self._LOGIN_URL, None, 'Downloading login page')
|
||||
token, vuid = self._extract_xsrft_and_vuid(webpage)
|
||||
|
@ -75,6 +70,10 @@ class VimeoBaseInfoExtractor(InfoExtractor):
|
|||
expected=True)
|
||||
raise ExtractorError('Unable to log in')
|
||||
|
||||
def _real_initialize(self):
|
||||
if self._LOGIN_REQUIRED and not self._get_cookies('https://vimeo.com').get('vuid'):
|
||||
self._raise_login_required()
|
||||
|
||||
def _get_video_password(self):
|
||||
password = self.get_param('videopassword')
|
||||
if password is None:
|
||||
|
@ -701,9 +700,6 @@ class VimeoIE(VimeoBaseInfoExtractor):
|
|||
raise ExtractorError('Wrong video password', expected=True)
|
||||
return checked
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _extract_from_api(self, video_id, unlisted_hash=None):
|
||||
token = self._download_json(
|
||||
'https://vimeo.com/_rv/jwt', video_id, headers={
|
||||
|
@ -1231,9 +1227,6 @@ class VimeoReviewIE(VimeoBaseInfoExtractor):
|
|||
'skip': 'video gone',
|
||||
}]
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _real_extract(self, url):
|
||||
page_url, video_id = self._match_valid_url(url).groups()
|
||||
data = self._download_json(
|
||||
|
@ -1275,9 +1268,6 @@ class VimeoWatchLaterIE(VimeoChannelIE):
|
|||
'only_matching': True,
|
||||
}]
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _page_url(self, base_url, pagenum):
|
||||
url = '%s/page:%d/' % (base_url, pagenum)
|
||||
request = sanitized_Request(url)
|
||||
|
|
|
@ -29,11 +29,7 @@ from .youtube import YoutubeIE
|
|||
class VKBaseIE(InfoExtractor):
|
||||
_NETRC_MACHINE = 'vk'
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
login_page, url_handle = self._download_webpage_handle(
|
||||
'https://vk.com', None, 'Downloading login page')
|
||||
|
||||
|
@ -57,9 +53,6 @@ class VKBaseIE(InfoExtractor):
|
|||
raise ExtractorError(
|
||||
'Unable to login, incorrect username and/or password', expected=True)
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
|
||||
def _download_payload(self, path, video_id, data, fatal=True):
|
||||
data['al'] = 1
|
||||
code, payload = self._download_json(
|
||||
|
|
|
@ -26,22 +26,16 @@ class VLiveBaseIE(NaverBaseIE):
|
|||
_NETRC_MACHINE = 'vlive'
|
||||
_logged_in = False
|
||||
|
||||
def _real_initialize(self):
|
||||
if not self._logged_in:
|
||||
VLiveBaseIE._logged_in = self._login()
|
||||
|
||||
def _login(self):
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
return False
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
if self._logged_in:
|
||||
return
|
||||
LOGIN_URL = 'https://www.vlive.tv/auth/email/login'
|
||||
self._request_webpage(
|
||||
LOGIN_URL, None, note='Downloading login cookies')
|
||||
|
||||
self._download_webpage(
|
||||
LOGIN_URL, None, note='Logging in',
|
||||
data=urlencode_postdata({'email': email, 'pwd': password}),
|
||||
data=urlencode_postdata({'email': username, 'pwd': password}),
|
||||
headers={
|
||||
'Referer': LOGIN_URL,
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
|
@ -54,7 +48,7 @@ class VLiveBaseIE(NaverBaseIE):
|
|||
|
||||
if not try_get(login_info, lambda x: x['message']['login'], bool):
|
||||
raise ExtractorError('Unable to log in', expected=True)
|
||||
return True
|
||||
VLiveBaseIE._logged_in = True
|
||||
|
||||
def _call_api(self, path_template, video_id, fields=None, query_add={}, note=None):
|
||||
if note is None:
|
||||
|
|
|
@ -85,7 +85,7 @@ class VRVBaseIE(InfoExtractor):
|
|||
'resource_key': resource_key,
|
||||
})['__links__']['cms_resource']['href']
|
||||
|
||||
def _real_initialize(self):
|
||||
def _initialize_pre_login(self):
|
||||
webpage = self._download_webpage(
|
||||
'https://vrv.co/', None, headers=self.geo_verification_headers())
|
||||
self._API_PARAMS = self._parse_json(self._search_regex(
|
||||
|
@ -124,16 +124,10 @@ class VRVIE(VRVBaseIE):
|
|||
}]
|
||||
_NETRC_MACHINE = 'vrv'
|
||||
|
||||
def _real_initialize(self):
|
||||
super(VRVIE, self)._real_initialize()
|
||||
|
||||
email, password = self._get_login_info()
|
||||
if email is None:
|
||||
return
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
token_credentials = self._call_api(
|
||||
'authenticate/by:credentials', None, 'Token Credentials', data={
|
||||
'email': email,
|
||||
'email': username,
|
||||
'password': password,
|
||||
})
|
||||
self._TOKEN = token_credentials['oauth_token']
|
||||
|
|
|
@ -263,7 +263,7 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
|
|||
|
||||
_PLAYLIST_ID_RE = r'(?:(?:PL|LL|EC|UU|FL|RD|UL|TL|PU|OLAK5uy_)[0-9A-Za-z-_]{10,}|RDMM|WL|LL|LM)'
|
||||
|
||||
_NETRC_MACHINE = 'youtube'
|
||||
# _NETRC_MACHINE = 'youtube'
|
||||
|
||||
# If True it will raise an error if no login info is provided
|
||||
_LOGIN_REQUIRED = False
|
||||
|
@ -334,21 +334,6 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
|
|||
r'(?:www\.)?hpniueoejy4opn7bc4ftgazyqjoeqwlvh2uiku2xqku6zpoa4bf5ruid\.onion',
|
||||
)
|
||||
|
||||
def _login(self):
|
||||
"""
|
||||
Attempt to log in to YouTube.
|
||||
If _LOGIN_REQUIRED is set and no authentication was provided, an error is raised.
|
||||
"""
|
||||
|
||||
if (self._LOGIN_REQUIRED
|
||||
and self.get_param('cookiefile') is None
|
||||
and self.get_param('cookiesfrombrowser') is None):
|
||||
self.raise_login_required(
|
||||
'Login details are needed to download this content', method='cookies')
|
||||
username, password = self._get_login_info()
|
||||
if username:
|
||||
self.report_warning(f'Cannot login to YouTube using username and password. {self._LOGIN_HINTS["cookies"]}')
|
||||
|
||||
def _initialize_consent(self):
|
||||
cookies = self._get_cookies('https://www.youtube.com/')
|
||||
if cookies.get('__Secure-3PSID'):
|
||||
|
@ -379,7 +364,10 @@ class YoutubeBaseInfoExtractor(InfoExtractor):
|
|||
def _real_initialize(self):
|
||||
self._initialize_pref()
|
||||
self._initialize_consent()
|
||||
self._login()
|
||||
if (self._LOGIN_REQUIRED
|
||||
and self.get_param('cookiefile') is None
|
||||
and self.get_param('cookiesfrombrowser') is None):
|
||||
self.raise_login_required('Login details are needed to download this content', method='cookies')
|
||||
|
||||
_YT_INITIAL_DATA_RE = r'(?:window\s*\[\s*["\']ytInitialData["\']\s*\]|ytInitialData)\s*=\s*({.+?})\s*;'
|
||||
_YT_INITIAL_PLAYER_RESPONSE_RE = r'ytInitialPlayerResponse\s*=\s*({.+?})\s*;'
|
||||
|
@ -3928,6 +3916,7 @@ class YoutubeTabBaseInfoExtractor(YoutubeBaseInfoExtractor):
|
|||
if entry:
|
||||
yield entry
|
||||
'''
|
||||
|
||||
def _extract_entries(self, parent_renderer, continuation_list):
|
||||
# continuation_list is modified in-place with continuation_list = [continuation_token]
|
||||
continuation_list[:] = [None]
|
||||
|
|
|
@ -25,13 +25,11 @@ class ZattooPlatformBaseIE(InfoExtractor):
|
|||
def _host_url(self):
|
||||
return 'https://%s' % (self._API_HOST if hasattr(self, '_API_HOST') else self._HOST)
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if not username or not password:
|
||||
self.raise_login_required(
|
||||
'A valid %s account is needed to access this media.'
|
||||
% self._NETRC_MACHINE)
|
||||
def _real_initialize(self):
|
||||
if not self._power_guide_hash:
|
||||
self.raise_login_required('An account is needed to access this media', method='password')
|
||||
|
||||
def _perform_login(self, username, password):
|
||||
try:
|
||||
data = self._download_json(
|
||||
'%s/zapi/v2/account/login' % self._host_url(), None, 'Logging in',
|
||||
|
@ -52,7 +50,7 @@ class ZattooPlatformBaseIE(InfoExtractor):
|
|||
|
||||
self._power_guide_hash = data['session']['power_guide_hash']
|
||||
|
||||
def _real_initialize(self):
|
||||
def _initialize_pre_login(self):
|
||||
webpage = self._download_webpage(
|
||||
self._host_url(), None, 'Downloading app token')
|
||||
app_token = self._html_search_regex(
|
||||
|
@ -72,8 +70,6 @@ class ZattooPlatformBaseIE(InfoExtractor):
|
|||
'format': 'json',
|
||||
}))
|
||||
|
||||
self._login()
|
||||
|
||||
def _extract_cid(self, video_id, channel_name):
|
||||
channel_groups = self._download_json(
|
||||
'%s/zapi/v2/cached/channels/%s' % (self._host_url(),
|
||||
|
|
|
@ -93,32 +93,27 @@ class Zee5IE(InfoExtractor):
|
|||
_NETRC_MACHINE = 'zee5'
|
||||
_GEO_COUNTRIES = ['IN']
|
||||
|
||||
def _login(self):
|
||||
username, password = self._get_login_info()
|
||||
if username:
|
||||
if len(username) == 10 and username.isdigit() and self._USER_TOKEN is None:
|
||||
self.report_login()
|
||||
otp_request_json = self._download_json('https://b2bapi.zee5.com/device/sendotp_v1.php?phoneno=91{}'.format(username),
|
||||
None, note='Sending OTP')
|
||||
if otp_request_json['code'] == 0:
|
||||
self.to_screen(otp_request_json['message'])
|
||||
else:
|
||||
raise ExtractorError(otp_request_json['message'], expected=True)
|
||||
otp_code = self._get_tfa_info('OTP')
|
||||
otp_verify_json = self._download_json('https://b2bapi.zee5.com/device/verifyotp_v1.php?phoneno=91{}&otp={}&guest_token={}&platform=web'.format(username, otp_code, self._DEVICE_ID),
|
||||
None, note='Verifying OTP', fatal=False)
|
||||
if not otp_verify_json:
|
||||
raise ExtractorError('Unable to verify OTP.', expected=True)
|
||||
self._USER_TOKEN = otp_verify_json.get('token')
|
||||
if not self._USER_TOKEN:
|
||||
raise ExtractorError(otp_request_json['message'], expected=True)
|
||||
elif username.lower() == 'token' and len(password) > 1198:
|
||||
self._USER_TOKEN = password
|
||||
def _perform_login(self, username, password):
|
||||
if len(username) == 10 and username.isdigit() and self._USER_TOKEN is None:
|
||||
self.report_login()
|
||||
otp_request_json = self._download_json('https://b2bapi.zee5.com/device/sendotp_v1.php?phoneno=91{}'.format(username),
|
||||
None, note='Sending OTP')
|
||||
if otp_request_json['code'] == 0:
|
||||
self.to_screen(otp_request_json['message'])
|
||||
else:
|
||||
raise ExtractorError(self._LOGIN_HINT, expected=True)
|
||||
|
||||
def _real_initialize(self):
|
||||
self._login()
|
||||
raise ExtractorError(otp_request_json['message'], expected=True)
|
||||
otp_code = self._get_tfa_info('OTP')
|
||||
otp_verify_json = self._download_json('https://b2bapi.zee5.com/device/verifyotp_v1.php?phoneno=91{}&otp={}&guest_token={}&platform=web'.format(username, otp_code, self._DEVICE_ID),
|
||||
None, note='Verifying OTP', fatal=False)
|
||||
if not otp_verify_json:
|
||||
raise ExtractorError('Unable to verify OTP.', expected=True)
|
||||
self._USER_TOKEN = otp_verify_json.get('token')
|
||||
if not self._USER_TOKEN:
|
||||
raise ExtractorError(otp_request_json['message'], expected=True)
|
||||
elif username.lower() == 'token' and len(password) > 1198:
|
||||
self._USER_TOKEN = password
|
||||
else:
|
||||
raise ExtractorError(self._LOGIN_HINT, expected=True)
|
||||
|
||||
def _real_extract(self, url):
|
||||
video_id, display_id = self._match_valid_url(url).group('id', 'display_id')
|
||||
|
|
Loading…
Reference in a new issue