broken feature
This commit is contained in:
@@ -573,7 +573,6 @@ Description
|
|||||||
* ``subscribestar``
|
* ``subscribestar``
|
||||||
* ``tapas``
|
* ``tapas``
|
||||||
* ``tsumino``
|
* ``tsumino``
|
||||||
* ``twitter``
|
|
||||||
* ``vipergirls``
|
* ``vipergirls``
|
||||||
* ``zerochan``
|
* ``zerochan``
|
||||||
|
|
||||||
@@ -6052,19 +6051,6 @@ Description
|
|||||||
Wait for ``N`` seconds
|
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
|
extractor.twitter.locked
|
||||||
------------------------
|
------------------------
|
||||||
Type
|
Type
|
||||||
|
|||||||
@@ -857,7 +857,6 @@
|
|||||||
"pinned" : false,
|
"pinned" : false,
|
||||||
"quoted" : false,
|
"quoted" : false,
|
||||||
"ratelimit" : "wait",
|
"ratelimit" : "wait",
|
||||||
"relogin" : true,
|
|
||||||
"replies" : true,
|
"replies" : true,
|
||||||
"retweets" : false,
|
"retweets" : false,
|
||||||
"search-limit": 20,
|
"search-limit": 20,
|
||||||
|
|||||||
@@ -1073,7 +1073,7 @@ Consider all listed sites to potentially be NSFW.
|
|||||||
<td>Twitter</td>
|
<td>Twitter</td>
|
||||||
<td>https://x.com/</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>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>
|
||||||
<tr id="unsplash" title="unsplash">
|
<tr id="unsplash" title="unsplash">
|
||||||
<td>Unsplash</td>
|
<td>Unsplash</td>
|
||||||
|
|||||||
@@ -1745,18 +1745,7 @@ class TwitterAPI():
|
|||||||
retry = True
|
retry = True
|
||||||
|
|
||||||
elif "Could not authenticate you" in msg:
|
elif "Could not authenticate you" in msg:
|
||||||
if not self.extractor.config("relogin", True):
|
raise exception.AbortExtraction(f"'{msg}'")
|
||||||
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
|
|
||||||
|
|
||||||
elif msg.lower().startswith("timeout"):
|
elif msg.lower().startswith("timeout"):
|
||||||
retry = True
|
retry = True
|
||||||
@@ -2195,179 +2184,6 @@ class TwitterAPI():
|
|||||||
|
|
||||||
@cache(maxage=365*86400, keyarg=1)
|
@cache(maxage=365*86400, keyarg=1)
|
||||||
def _login_impl(extr, username, password):
|
def _login_impl(extr, username, password):
|
||||||
|
extr.log.error("Login with username & password is no longer supported. "
|
||||||
def process(data, params=None):
|
"Use browser cookies instead.")
|
||||||
response = extr.request(
|
return {}
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -532,7 +532,7 @@ AUTH_MAP = {
|
|||||||
"tiktok" : _COOKIES,
|
"tiktok" : _COOKIES,
|
||||||
"tsumino" : "Supported",
|
"tsumino" : "Supported",
|
||||||
"tumblr" : _OAUTH,
|
"tumblr" : _OAUTH,
|
||||||
"twitter" : "Supported",
|
"twitter" : _COOKIES,
|
||||||
"vipergirls" : "Supported",
|
"vipergirls" : "Supported",
|
||||||
"wallhaven" : _APIKEY_WH,
|
"wallhaven" : _APIKEY_WH,
|
||||||
"weasyl" : _APIKEY_WY,
|
"weasyl" : _APIKEY_WY,
|
||||||
|
|||||||
Reference in New Issue
Block a user