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