broken feature
This commit is contained in:
@@ -573,7 +573,6 @@ Description
|
||||
* ``subscribestar``
|
||||
* ``tapas``
|
||||
* ``tsumino``
|
||||
* ``twitter``
|
||||
* ``vipergirls``
|
||||
* ``zerochan``
|
||||
|
||||
@@ -6052,19 +6051,6 @@ Description
|
||||
Wait for ``N`` seconds
|
||||
|
||||
|
||||
extractor.twitter.relogin
|
||||
-------------------------
|
||||
Type
|
||||
``bool``
|
||||
Default
|
||||
``true``
|
||||
Description
|
||||
When receiving a "Could not authenticate you" error while logged in with
|
||||
`username & password <extractor.*.username & .password_>`__,
|
||||
refresh the current login session and
|
||||
try to continue from where it left off.
|
||||
|
||||
|
||||
extractor.twitter.locked
|
||||
------------------------
|
||||
Type
|
||||
|
||||
@@ -857,7 +857,6 @@
|
||||
"pinned" : false,
|
||||
"quoted" : false,
|
||||
"ratelimit" : "wait",
|
||||
"relogin" : true,
|
||||
"replies" : true,
|
||||
"retweets" : false,
|
||||
"search-limit": 20,
|
||||
|
||||
@@ -1073,7 +1073,7 @@ Consider all listed sites to potentially be NSFW.
|
||||
<td>Twitter</td>
|
||||
<td>https://x.com/</td>
|
||||
<td>Avatars, Backgrounds, Bookmarks, Communities, Events, Followers, Followed Users, Hashtags, Highlights, Home Feed, individual Images, User Profile Information, Likes, Lists, List Members, Media Timelines, Quotes, Search Results, Timelines, Tweets, User Profiles</td>
|
||||
<td>Supported</td>
|
||||
<td><a href="https://github.com/mikf/gallery-dl#cookies">Cookies</a></td>
|
||||
</tr>
|
||||
<tr id="unsplash" title="unsplash">
|
||||
<td>Unsplash</td>
|
||||
|
||||
@@ -1745,18 +1745,7 @@ class TwitterAPI():
|
||||
retry = True
|
||||
|
||||
elif "Could not authenticate you" in msg:
|
||||
if not self.extractor.config("relogin", True):
|
||||
continue
|
||||
|
||||
username, password = self.extractor._get_auth_info()
|
||||
if not username:
|
||||
continue
|
||||
|
||||
_login_impl.invalidate(username)
|
||||
self.extractor.cookies_update(
|
||||
_login_impl(self.extractor, username, password))
|
||||
self.__init__(self.extractor)
|
||||
retry = True
|
||||
raise exception.AbortExtraction(f"'{msg}'")
|
||||
|
||||
elif msg.lower().startswith("timeout"):
|
||||
retry = True
|
||||
@@ -2195,179 +2184,6 @@ class TwitterAPI():
|
||||
|
||||
@cache(maxage=365*86400, keyarg=1)
|
||||
def _login_impl(extr, username, password):
|
||||
|
||||
def process(data, params=None):
|
||||
response = extr.request(
|
||||
url, params=params, headers=headers, json=data,
|
||||
method="POST", fatal=None)
|
||||
|
||||
# update 'x-csrf-token' header (#5945)
|
||||
if csrf_token := response.cookies.get("ct0"):
|
||||
headers["x-csrf-token"] = csrf_token
|
||||
|
||||
try:
|
||||
data = response.json()
|
||||
except ValueError:
|
||||
data = {"errors": ({"message": "Invalid response"},)}
|
||||
else:
|
||||
if response.status_code < 400:
|
||||
try:
|
||||
return (data["flow_token"],
|
||||
data["subtasks"][0]["subtask_id"])
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
errors = []
|
||||
for error in data.get("errors") or ():
|
||||
msg = error.get("message")
|
||||
errors.append(f'"{msg}"' if msg else "Unknown error")
|
||||
extr.log.debug(response.text)
|
||||
raise exception.AuthenticationError(", ".join(errors))
|
||||
|
||||
cookies = extr.cookies
|
||||
cookies.clear()
|
||||
api = TwitterAPI(extr)
|
||||
api._authenticate_guest()
|
||||
|
||||
url = "https://api.x.com/1.1/onboarding/task.json"
|
||||
params = {"flow_name": "login"}
|
||||
headers = api.headers
|
||||
|
||||
extr.log.info("Logging in as %s", username)
|
||||
|
||||
# init
|
||||
data = {
|
||||
"input_flow_data": {
|
||||
"flow_context": {
|
||||
"debug_overrides": {},
|
||||
"start_location": {"location": "unknown"},
|
||||
},
|
||||
},
|
||||
"subtask_versions": {
|
||||
"action_list": 2,
|
||||
"alert_dialog": 1,
|
||||
"app_download_cta": 1,
|
||||
"check_logged_in_account": 1,
|
||||
"choice_selection": 3,
|
||||
"contacts_live_sync_permission_prompt": 0,
|
||||
"cta": 7,
|
||||
"email_verification": 2,
|
||||
"end_flow": 1,
|
||||
"enter_date": 1,
|
||||
"enter_email": 2,
|
||||
"enter_password": 5,
|
||||
"enter_phone": 2,
|
||||
"enter_recaptcha": 1,
|
||||
"enter_text": 5,
|
||||
"enter_username": 2,
|
||||
"generic_urt": 3,
|
||||
"in_app_notification": 1,
|
||||
"interest_picker": 3,
|
||||
"js_instrumentation": 1,
|
||||
"menu_dialog": 1,
|
||||
"notifications_permission_prompt": 2,
|
||||
"open_account": 2,
|
||||
"open_home_timeline": 1,
|
||||
"open_link": 1,
|
||||
"phone_verification": 4,
|
||||
"privacy_options": 1,
|
||||
"security_key": 3,
|
||||
"select_avatar": 4,
|
||||
"select_banner": 2,
|
||||
"settings_list": 7,
|
||||
"show_code": 1,
|
||||
"sign_up": 2,
|
||||
"sign_up_review": 4,
|
||||
"tweet_selection_urt": 1,
|
||||
"update_users": 1,
|
||||
"upload_media": 1,
|
||||
"user_recommendations_list": 4,
|
||||
"user_recommendations_urt": 1,
|
||||
"wait_spinner": 3,
|
||||
"web_modal": 1,
|
||||
},
|
||||
}
|
||||
|
||||
flow_token, subtask = process(data, params)
|
||||
while not cookies.get("auth_token"):
|
||||
if subtask == "LoginJsInstrumentationSubtask":
|
||||
data = {
|
||||
"js_instrumentation": {
|
||||
"response": "{}",
|
||||
"link": "next_link",
|
||||
},
|
||||
}
|
||||
elif subtask == "LoginEnterUserIdentifierSSO":
|
||||
data = {
|
||||
"settings_list": {
|
||||
"setting_responses": [
|
||||
{
|
||||
"key": "user_identifier",
|
||||
"response_data": {
|
||||
"text_data": {"result": username},
|
||||
},
|
||||
},
|
||||
],
|
||||
"link": "next_link",
|
||||
},
|
||||
}
|
||||
elif subtask == "LoginEnterPassword":
|
||||
data = {
|
||||
"enter_password": {
|
||||
"password": password,
|
||||
"link": "next_link",
|
||||
},
|
||||
}
|
||||
elif subtask == "LoginEnterAlternateIdentifierSubtask":
|
||||
alt = extr.config("username-alt") or extr.input(
|
||||
"Alternate Identifier (username, email, phone number): ")
|
||||
data = {
|
||||
"enter_text": {
|
||||
"text": alt,
|
||||
"link": "next_link",
|
||||
},
|
||||
}
|
||||
elif subtask == "LoginTwoFactorAuthChallenge":
|
||||
data = {
|
||||
"enter_text": {
|
||||
"text": extr.input("2FA Token: "),
|
||||
"link": "next_link",
|
||||
},
|
||||
}
|
||||
elif subtask == "LoginAcid":
|
||||
data = {
|
||||
"enter_text": {
|
||||
"text": extr.input("Email Verification Code: "),
|
||||
"link": "next_link",
|
||||
},
|
||||
}
|
||||
elif subtask == "AccountDuplicationCheck":
|
||||
data = {
|
||||
"check_logged_in_account": {
|
||||
"link": "AccountDuplicationCheck_false",
|
||||
},
|
||||
}
|
||||
elif subtask == "ArkoseLogin":
|
||||
raise exception.AuthenticationError("Login requires CAPTCHA")
|
||||
elif subtask == "DenyLoginSubtask":
|
||||
raise exception.AuthenticationError("Login rejected as suspicious")
|
||||
elif subtask == "LoginSuccessSubtask":
|
||||
raise exception.AuthenticationError(
|
||||
"No 'auth_token' cookie received")
|
||||
else:
|
||||
raise exception.AbortExtraction(f"Unrecognized subtask {subtask}")
|
||||
|
||||
inputs = {"subtask_id": subtask}
|
||||
inputs.update(data)
|
||||
data = {
|
||||
"flow_token": flow_token,
|
||||
"subtask_inputs": [inputs],
|
||||
}
|
||||
|
||||
extr.sleep(random.uniform(1.0, 3.0), f"login ({subtask})")
|
||||
flow_token, subtask = process(data)
|
||||
|
||||
return {
|
||||
cookie.name: cookie.value
|
||||
for cookie in extr.cookies
|
||||
}
|
||||
extr.log.error("Login with username & password is no longer supported. "
|
||||
"Use browser cookies instead.")
|
||||
return {}
|
||||
|
||||
@@ -532,7 +532,7 @@ AUTH_MAP = {
|
||||
"tiktok" : _COOKIES,
|
||||
"tsumino" : "Supported",
|
||||
"tumblr" : _OAUTH,
|
||||
"twitter" : "Supported",
|
||||
"twitter" : _COOKIES,
|
||||
"vipergirls" : "Supported",
|
||||
"wallhaven" : _APIKEY_WH,
|
||||
"weasyl" : _APIKEY_WY,
|
||||
|
||||
Reference in New Issue
Block a user