зеркало из
https://github.com/viginum-datalab/twscrape.git
synced 2025-10-30 05:26:20 +02:00
restore login by flow as was in 0.5 (check email first as param)
Этот коммит содержится в:
родитель
95b9a12d47
Коммит
2c1c0cce97
@ -94,6 +94,7 @@ class AccountsPool:
|
|||||||
account.active = True
|
account.active = True
|
||||||
|
|
||||||
await self.save(account)
|
await self.save(account)
|
||||||
|
logger.info(f"Account {username} added successfully (active={account.active})")
|
||||||
|
|
||||||
async def delete_accounts(self, usernames: str | list[str]):
|
async def delete_accounts(self, usernames: str | list[str]):
|
||||||
usernames = usernames if isinstance(usernames, list) else [usernames]
|
usernames = usernames if isinstance(usernames, list) else [usernames]
|
||||||
@ -131,9 +132,9 @@ class AccountsPool:
|
|||||||
"""
|
"""
|
||||||
await execute(self._db_file, qs, data)
|
await execute(self._db_file, qs, data)
|
||||||
|
|
||||||
async def login(self, account: Account):
|
async def login(self, account: Account, email_first: bool = False):
|
||||||
try:
|
try:
|
||||||
await login(account)
|
await login(account, email_first=email_first)
|
||||||
logger.info(f"Logged in to {account.username} successfully")
|
logger.info(f"Logged in to {account.username} successfully")
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -142,7 +143,7 @@ class AccountsPool:
|
|||||||
finally:
|
finally:
|
||||||
await self.save(account)
|
await self.save(account)
|
||||||
|
|
||||||
async def login_all(self):
|
async def login_all(self, email_first=False):
|
||||||
qs = "SELECT * FROM accounts WHERE active = false AND error_msg IS NULL"
|
qs = "SELECT * FROM accounts WHERE active = false AND error_msg IS NULL"
|
||||||
rs = await fetchall(self._db_file, qs)
|
rs = await fetchall(self._db_file, qs)
|
||||||
|
|
||||||
@ -152,11 +153,11 @@ class AccountsPool:
|
|||||||
counter = {"total": len(accounts), "success": 0, "failed": 0}
|
counter = {"total": len(accounts), "success": 0, "failed": 0}
|
||||||
for i, x in enumerate(accounts, start=1):
|
for i, x in enumerate(accounts, start=1):
|
||||||
logger.info(f"[{i}/{len(accounts)}] Logging in {x.username} - {x.email}")
|
logger.info(f"[{i}/{len(accounts)}] Logging in {x.username} - {x.email}")
|
||||||
status = await self.login(x)
|
status = await self.login(x, email_first=email_first)
|
||||||
counter["success" if status else "failed"] += 1
|
counter["success" if status else "failed"] += 1
|
||||||
return counter
|
return counter
|
||||||
|
|
||||||
async def relogin(self, usernames: str | list[str]):
|
async def relogin(self, usernames: str | list[str], email_first=False):
|
||||||
usernames = usernames if isinstance(usernames, list) else [usernames]
|
usernames = usernames if isinstance(usernames, list) else [usernames]
|
||||||
usernames = list(set(usernames))
|
usernames = list(set(usernames))
|
||||||
if not usernames:
|
if not usernames:
|
||||||
@ -176,12 +177,12 @@ class AccountsPool:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
await execute(self._db_file, qs)
|
await execute(self._db_file, qs)
|
||||||
await self.login_all()
|
await self.login_all(email_first=email_first)
|
||||||
|
|
||||||
async def relogin_failed(self):
|
async def relogin_failed(self, email_first=False):
|
||||||
qs = "SELECT username FROM accounts WHERE active = false AND error_msg IS NOT NULL"
|
qs = "SELECT username FROM accounts WHERE active = false AND error_msg IS NOT NULL"
|
||||||
rs = await fetchall(self._db_file, qs)
|
rs = await fetchall(self._db_file, qs)
|
||||||
await self.relogin([x["username"] for x in rs])
|
await self.relogin([x["username"] for x in rs], email_first=email_first)
|
||||||
|
|
||||||
async def reset_locks(self):
|
async def reset_locks(self):
|
||||||
qs = "UPDATE accounts SET locks = json_object()"
|
qs = "UPDATE accounts SET locks = json_object()"
|
||||||
|
|||||||
@ -80,15 +80,16 @@ async def main(args):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if args.command == "login_accounts":
|
if args.command == "login_accounts":
|
||||||
print(await pool.login_all())
|
stats = await pool.login_all(email_first=args.email_first)
|
||||||
|
print(stats)
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.command == "relogin_failed":
|
if args.command == "relogin_failed":
|
||||||
await pool.relogin_failed()
|
await pool.relogin_failed(email_first=args.email_first)
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.command == "relogin":
|
if args.command == "relogin":
|
||||||
await pool.relogin(args.usernames)
|
await pool.relogin(args.usernames, email_first=args.email_first)
|
||||||
return
|
return
|
||||||
|
|
||||||
if args.command == "reset_locks":
|
if args.command == "reset_locks":
|
||||||
@ -164,12 +165,16 @@ def run():
|
|||||||
del_accounts = subparsers.add_parser("del_accounts", help="Delete accounts")
|
del_accounts = subparsers.add_parser("del_accounts", help="Delete accounts")
|
||||||
del_accounts.add_argument("usernames", nargs="+", default=[], help="Usernames to delete")
|
del_accounts.add_argument("usernames", nargs="+", default=[], help="Usernames to delete")
|
||||||
|
|
||||||
subparsers.add_parser("login_accounts", help="Login accounts")
|
login_cmd = subparsers.add_parser("login_accounts", help="Login accounts")
|
||||||
|
login_cmd.add_argument("--email-first", type=bool, default=False, help="Check email first")
|
||||||
|
|
||||||
relogin = subparsers.add_parser("relogin", help="Re-login selected accounts")
|
relogin = subparsers.add_parser("relogin", help="Re-login selected accounts")
|
||||||
relogin.add_argument("usernames", nargs="+", default=[], help="Usernames to re-login")
|
relogin.add_argument("usernames", nargs="+", default=[], help="Usernames to re-login")
|
||||||
|
relogin.add_argument("--email-first", type=bool, default=False, help="Check email first")
|
||||||
|
|
||||||
|
re_failed = subparsers.add_parser("relogin_failed", help="Retry login for failed accounts")
|
||||||
|
re_failed.add_argument("--email-first", type=bool, default=False, help="Check email first")
|
||||||
|
|
||||||
subparsers.add_parser("relogin_failed", help="Retry login for failed accounts")
|
|
||||||
subparsers.add_parser("reset_locks", help="Reset all locks")
|
subparsers.add_parser("reset_locks", help="Reset all locks")
|
||||||
subparsers.add_parser("delete_inactive", help="Delete inactive accounts")
|
subparsers.add_parser("delete_inactive", help="Delete inactive accounts")
|
||||||
|
|
||||||
|
|||||||
@ -33,14 +33,14 @@ def add_imap_mapping(email_domain: str, imap_domain: str):
|
|||||||
IMAP_MAPPING[email_domain] = imap_domain
|
IMAP_MAPPING[email_domain] = imap_domain
|
||||||
|
|
||||||
|
|
||||||
def get_imap_domain(email: str) -> str:
|
def _get_imap_domain(email: str) -> str:
|
||||||
email_domain = email.split("@")[1]
|
email_domain = email.split("@")[1]
|
||||||
if email_domain in IMAP_MAPPING:
|
if email_domain in IMAP_MAPPING:
|
||||||
return IMAP_MAPPING[email_domain]
|
return IMAP_MAPPING[email_domain]
|
||||||
return f"imap.{email_domain}"
|
return f"imap.{email_domain}"
|
||||||
|
|
||||||
|
|
||||||
def search_email_code(imap: imaplib.IMAP4_SSL, count: int, min_t: datetime | None) -> str | None:
|
def _wait_email_code(imap: imaplib.IMAP4_SSL, count: int, min_t: datetime | None) -> str | None:
|
||||||
for i in range(count, 0, -1):
|
for i in range(count, 0, -1):
|
||||||
_, rep = imap.fetch(str(i), "(RFC822)")
|
_, rep = imap.fetch(str(i), "(RFC822)")
|
||||||
for x in rep:
|
for x in rep:
|
||||||
@ -71,7 +71,7 @@ async def imap_get_email_code(
|
|||||||
_, rep = imap.select("INBOX")
|
_, rep = imap.select("INBOX")
|
||||||
now_count = int(rep[0].decode("utf-8")) if len(rep) > 0 and rep[0] is not None else 0
|
now_count = int(rep[0].decode("utf-8")) if len(rep) > 0 and rep[0] is not None else 0
|
||||||
if now_count > was_count:
|
if now_count > was_count:
|
||||||
code = search_email_code(imap, now_count, min_t)
|
code = _wait_email_code(imap, now_count, min_t)
|
||||||
if code is not None:
|
if code is not None:
|
||||||
return code
|
return code
|
||||||
|
|
||||||
@ -87,8 +87,8 @@ async def imap_get_email_code(
|
|||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
|
||||||
async def imap_try_login(email: str, password: str):
|
async def imap_login(email: str, password: str):
|
||||||
domain = get_imap_domain(email)
|
domain = _get_imap_domain(email)
|
||||||
imap = imaplib.IMAP4_SSL(domain)
|
imap = imaplib.IMAP4_SSL(domain)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from httpx import AsyncClient, HTTPStatusError, Response
|
|||||||
|
|
||||||
from .account import Account
|
from .account import Account
|
||||||
from .constants import LOGIN_URL
|
from .constants import LOGIN_URL
|
||||||
from .imap import imap_get_email_code, imap_try_login
|
from .imap import imap_get_email_code, imap_login
|
||||||
from .logger import logger
|
from .logger import logger
|
||||||
from .utils import raise_for_status
|
from .utils import raise_for_status
|
||||||
|
|
||||||
@ -117,6 +117,9 @@ async def login_confirm_email(client: AsyncClient, acc: Account, prev: dict, ima
|
|||||||
|
|
||||||
|
|
||||||
async def login_confirm_email_code(client: AsyncClient, acc: Account, prev: dict, imap):
|
async def login_confirm_email_code(client: AsyncClient, acc: Account, prev: dict, imap):
|
||||||
|
if not imap:
|
||||||
|
imap = await imap_login(acc.email, acc.password)
|
||||||
|
|
||||||
now_time = datetime.now(timezone.utc) - timedelta(seconds=30)
|
now_time = datetime.now(timezone.utc) - timedelta(seconds=30)
|
||||||
value = await imap_get_email_code(imap, acc.email, now_time)
|
value = await imap_get_email_code(imap, acc.email, now_time)
|
||||||
|
|
||||||
@ -181,14 +184,16 @@ async def next_login_task(client: AsyncClient, acc: Account, rep: Response, imap
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def login(acc: Account, fresh=False) -> Account:
|
async def login(acc: Account, email_first=False) -> Account:
|
||||||
log_id = f"{acc.username} - {acc.email}"
|
log_id = f"{acc.username} - {acc.email}"
|
||||||
if acc.active and not fresh:
|
if acc.active:
|
||||||
logger.info(f"account already active {log_id}")
|
logger.info(f"account already active {log_id}")
|
||||||
return acc
|
return acc
|
||||||
|
|
||||||
# check if email is valid first
|
if email_first:
|
||||||
imap = await imap_try_login(acc.email, acc.email_password)
|
imap = await imap_login(acc.email, acc.email_password)
|
||||||
|
else:
|
||||||
|
imap = None
|
||||||
|
|
||||||
client = acc.make_client()
|
client = acc.make_client()
|
||||||
guest_token = await get_guest_token(client)
|
guest_token = await get_guest_token(client)
|
||||||
|
|||||||
Загрузка…
x
Ссылка в новой задаче
Block a user