style: 统一 Ruff 代码格式

This commit is contained in:
yml2213
2026-08-30 21:04:52 +08:00
parent c891ac982e
commit 47e19ed7b2
90 changed files with 5574 additions and 2350 deletions
+82 -26
View File
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
"""应用宝 QQ 二维码登录(纯 Python,无浏览器自动化)。"""
from __future__ import annotations
import argparse
@@ -15,7 +16,12 @@ from http.cookiejar import CookieJar
from pathlib import Path
from urllib.error import HTTPError
from urllib.parse import urlencode
from urllib.request import HTTPRedirectHandler, HTTPCookieProcessor, Request, build_opener
from urllib.request import (
HTTPRedirectHandler,
HTTPCookieProcessor,
Request,
build_opener,
)
ROOT = Path(__file__).resolve().parent.parent
OPEN_APPID = "102033112"
@@ -60,8 +66,15 @@ class Client:
self.jar = CookieJar()
self.opener = build_opener(NoRedirect, HTTPCookieProcessor(self.jar))
def request(self, url: str, *, method: str = "GET", body: bytes | None = None,
referer: str = "", headers: dict[str, str] | None = None) -> Response:
def request(
self,
url: str,
*,
method: str = "GET",
body: bytes | None = None,
referer: str = "",
headers: dict[str, str] | None = None,
) -> Response:
request_headers = {"User-Agent": USER_AGENT, "Accept": "*/*"}
if referer:
request_headers["Referer"] = referer
@@ -155,7 +168,9 @@ def write_session(path: Path, cookies: dict[str, str]) -> None:
document["login_type"] = cookies.get("logintype", "QC")
document["login_updated_at"] = int(time.time())
path.parent.mkdir(parents=True, exist_ok=True)
fd, temporary = tempfile.mkstemp(prefix=".mall-session-", suffix=".tmp", dir=path.parent)
fd, temporary = tempfile.mkstemp(
prefix=".mall-session-", suffix=".tmp", dir=path.parent
)
try:
with os.fdopen(fd, "w", encoding="utf-8") as handle:
json.dump(document, handle, ensure_ascii=False, indent=2)
@@ -172,7 +187,9 @@ def write_session(path: Path, cookies: dict[str, str]) -> None:
def main() -> int:
parser = argparse.ArgumentParser(description="应用宝 QQ 扫码登录(纯 Python)")
parser.add_argument("--session", type=Path, default=ROOT / "config/mall-session.json")
parser.add_argument(
"--session", type=Path, default=ROOT / "config/mall-session.json"
)
parser.add_argument("--qr", type=Path, default=ROOT / "config/qq-login.jpg")
parser.add_argument("--timeout", type=float, default=300, help="二维码等待秒数")
parser.add_argument("--interval", type=float, default=3, help="轮询间隔秒数")
@@ -183,8 +200,12 @@ def main() -> int:
client = Client()
state = secrets.token_urlsafe(14)
show_query = {
"which": "Login", "display": "pc", "response_type": "code", "client_id": OPEN_APPID,
"redirect_uri": CALLBACK, "state": state,
"which": "Login",
"display": "pc",
"response_type": "code",
"client_id": OPEN_APPID,
"redirect_uri": CALLBACK,
"state": state,
}
show_url = f"{GRAPH_SHOW}?{urlencode(show_query)}"
show = client.request(show_url, referer="https://m.yyb.qq.com/")
@@ -192,11 +213,18 @@ def main() -> int:
raise RuntimeError(f"QQ OAuth 页面请求失败: HTTP {show.status}")
xlogin_query = {
"appid": PT_APPID, "daid": PT_DAID, "style": "33", "login_text": "登录",
"hide_title_bar": "1", "hide_border": "1", "target": "self", "s_url": LOGIN_JUMP,
"appid": PT_APPID,
"daid": PT_DAID,
"style": "33",
"login_text": "登录",
"hide_title_bar": "1",
"hide_border": "1",
"target": "self",
"s_url": LOGIN_JUMP,
"pt_3rd_aid": OPEN_APPID,
"pt_feedback_link": f"https://support.qq.com/products/77942?customInfo=.appid{OPEN_APPID}",
"theme": "2", "verify_theme": "",
"theme": "2",
"verify_theme": "",
}
xlogin_url = f"{XLOGIN}?{urlencode(xlogin_query)}"
xlogin = client.request(xlogin_url, referer=show_url)
@@ -207,9 +235,16 @@ def main() -> int:
raise RuntimeError("QQ 登录页未写入 pt_login_sig")
qr_query = {
"appid": PT_APPID, "e": "2", "l": "M", "s": "3", "d": "72", "v": "4",
"t": str(secrets.randbelow(1_000_000) / 1_000_000), "daid": PT_DAID,
"pt_3rd_aid": OPEN_APPID, "u1": LOGIN_JUMP,
"appid": PT_APPID,
"e": "2",
"l": "M",
"s": "3",
"d": "72",
"v": "4",
"t": str(secrets.randbelow(1_000_000) / 1_000_000),
"daid": PT_DAID,
"pt_3rd_aid": OPEN_APPID,
"u1": LOGIN_JUMP,
}
qr_url = f"{QR_SHOW}?{urlencode(qr_query)}"
image = client.request(qr_url, referer=xlogin_url)
@@ -228,10 +263,23 @@ def main() -> int:
o1v_id = secrets.token_hex(16)
while time.monotonic() < deadline:
poll_query = {
"u1": LOGIN_JUMP, "ptqrtoken": str(ptqr_token(qrsig)), "ptredirect": "0", "h": "1", "t": "1",
"g": "1", "from_ui": "1", "ptlang": "2052", "action": f"0-0-{int(time.time() * 1000)}",
"js_ver": "26071711", "js_type": "1", "login_sig": login_sig, "pt_uistyle": "40",
"aid": PT_APPID, "daid": PT_DAID, "pt_3rd_aid": OPEN_APPID, "o1vId": o1v_id,
"u1": LOGIN_JUMP,
"ptqrtoken": str(ptqr_token(qrsig)),
"ptredirect": "0",
"h": "1",
"t": "1",
"g": "1",
"from_ui": "1",
"ptlang": "2052",
"action": f"0-0-{int(time.time() * 1000)}",
"js_ver": "26071711",
"js_type": "1",
"login_sig": login_sig,
"pt_uistyle": "40",
"aid": PT_APPID,
"daid": PT_DAID,
"pt_3rd_aid": OPEN_APPID,
"o1vId": o1v_id,
"pt_js_version": "c1987b96",
}
poll = client.request(f"{QR_POLL}?{urlencode(poll_query)}", referer=xlogin_url)
@@ -252,7 +300,9 @@ def main() -> int:
check_sig = client.request(callback, referer=xlogin_url)
login_jump = check_sig.location()
if check_sig.status != 302 or not login_jump.startswith("https://graph.qq.com/oauth2.0/login_jump"):
if check_sig.status != 302 or not login_jump.startswith(
"https://graph.qq.com/oauth2.0/login_jump"
):
raise RuntimeError("QQ check_sig 未跳转到 OAuth login_jump")
jump = client.request(login_jump, referer=callback)
if jump.status != 200:
@@ -262,8 +312,10 @@ def main() -> int:
if not p_skey:
raise RuntimeError("QQ check_sig 未写入 p_skey")
authorize = client.request(
"https://graph.qq.com/oauth2.0/authorize", method="POST",
body=urlencode(authorize_params(state, p_skey)).encode("utf-8"), referer=login_jump,
"https://graph.qq.com/oauth2.0/authorize",
method="POST",
body=urlencode(authorize_params(state, p_skey)).encode("utf-8"),
referer=login_jump,
headers={"Content-Type": "application/x-www-form-urlencoded"},
)
oauth_callback = authorize.location()
@@ -276,12 +328,16 @@ def main() -> int:
if not cookies.get("openid") or not cookies.get("accesstoken"):
raise RuntimeError("YYB QQ OAuth 回调未写入 openid/accesstoken")
login_type = cookies.get("logintype", "QC")
info = client.request(USER_INFO, headers={
"Ual-Access-Login-Type": login_type_header(login_type),
"Ual-Access-Access-Token": cookies["accesstoken"],
"Ual-Access-Openid": cookies["openid"],
"Origin": "https://m.yyb.qq.com", "Referer": "https://m.yyb.qq.com/",
})
info = client.request(
USER_INFO,
headers={
"Ual-Access-Login-Type": login_type_header(login_type),
"Ual-Access-Access-Token": cookies["accesstoken"],
"Ual-Access-Openid": cookies["openid"],
"Origin": "https://m.yyb.qq.com",
"Referer": "https://m.yyb.qq.com/",
},
)
if info.status != 200:
raise RuntimeError(f"YYB QQ 登录态校验失败: HTTP {info.status}")
try: