feat(auth): separate read and write bilibili accounts
This commit is contained in:
1 parent
5c2ab7b187
commit
178ab64b18
17 files changed
+671
-707
No files matched your search
+48
-20
@@ -19,6 +19,7 @@ import sys
|
||||
from pathlib import Path
|
||||
from typing import Sequence
|
||||
|
||||
from .bilibili.auth_flow import AuthService
|
||||
from .bilibili.client import BilibiliClient, Pacer
|
||||
from .config import ConfigError, ConfigStore
|
||||
from .database import Database
|
||||
@@ -58,7 +59,15 @@ def _build_parser() -> argparse.ArgumentParser:
|
||||
snapshot.add_argument(
|
||||
"--force", action="store_true", help="忽略当日完成标记,重新采集"
|
||||
)
|
||||
sub.add_parser("auth-check", parents=[common], help="检查 Cookie 登录态")
|
||||
auth = sub.add_parser("auth", parents=[common], help="扫码授权并更新指定账号 Cookie")
|
||||
auth.add_argument("--account", choices=("read", "write"), default="read",
|
||||
help="要授权的账号角色(默认 read)")
|
||||
auth.add_argument("--no-browser", action="store_true", help="不自动打开二维码图片")
|
||||
auth.add_argument("--timeout", type=int, default=180, metavar="SEC",
|
||||
help="等待扫码的超时时间(默认 180 秒)")
|
||||
auth_check = sub.add_parser("auth-check", parents=[common], help="检查账号登录态")
|
||||
auth_check.add_argument("--account", choices=("read", "write", "all"), default="read",
|
||||
help="要检查的账号角色(默认 read)")
|
||||
run = sub.add_parser("run", parents=[common], help="按配置周期常驻运行同步与快照")
|
||||
run.add_argument(
|
||||
"--once", action="store_true", help="只执行一次到期任务后退出"
|
||||
@@ -82,11 +91,11 @@ def _print(payload) -> None:
|
||||
print(json.dumps(payload, ensure_ascii=False, indent=2), flush=True)
|
||||
|
||||
|
||||
def _client(cfg, logger: JsonLogger, *, pacer=None, retries: int = 3) -> BilibiliClient:
|
||||
def _client(credentials, logger: JsonLogger, *, pacer=None, retries: int = 3) -> BilibiliClient:
|
||||
return BilibiliClient(
|
||||
cookie=cfg.bilibili.cookie,
|
||||
csrf=cfg.bilibili.csrf,
|
||||
mid=cfg.bilibili.mid,
|
||||
cookie=credentials.cookie,
|
||||
csrf=credentials.csrf,
|
||||
mid=credentials.mid,
|
||||
pacer=pacer,
|
||||
retries=retries,
|
||||
logger=logger,
|
||||
@@ -120,7 +129,7 @@ def cmd_sync(args, logger: JsonLogger) -> int:
|
||||
db = _open_db(cfg, logger)
|
||||
try:
|
||||
repo = Repository(db)
|
||||
client = _client(cfg, logger)
|
||||
client = _client(cfg.bilibili.read, logger)
|
||||
service = FolderSyncService(store, repo, client, logger=logger)
|
||||
summary = service.run(full_refresh=args.full)
|
||||
payload = summary.as_dict()
|
||||
@@ -139,7 +148,7 @@ def cmd_snapshot(args, logger: JsonLogger) -> int:
|
||||
try:
|
||||
repo = Repository(db)
|
||||
client = _client(
|
||||
cfg, logger, pacer=Pacer(1.0, 1.6), retries=1
|
||||
cfg.bilibili.read, logger, pacer=Pacer(1.0, 1.6), retries=1
|
||||
)
|
||||
service = SnapshotService(store, repo, client, logger=logger)
|
||||
summary = service.run_if_needed(force=args.force)
|
||||
@@ -153,23 +162,40 @@ def cmd_snapshot(args, logger: JsonLogger) -> int:
|
||||
db.close()
|
||||
|
||||
|
||||
def cmd_auth_check(args, logger: JsonLogger) -> int:
|
||||
store = ConfigStore(args.config, require_auth=False)
|
||||
cfg = store.get()
|
||||
if not cfg.bilibili.cookie:
|
||||
_print({"ok": False, "is_login": False, "message": "未配置 cookie"})
|
||||
return 1
|
||||
client = _client(cfg, logger, retries=1)
|
||||
state = client.check_login()
|
||||
_print({
|
||||
def cmd_auth(args, logger: JsonLogger) -> int:
|
||||
if args.timeout < 1:
|
||||
raise ConfigError("auth --timeout 必须至少为 1 秒")
|
||||
return AuthService(Path(args.config), account=args.account, logger=logger).run(
|
||||
timeout=args.timeout, no_browser=args.no_browser
|
||||
)
|
||||
|
||||
|
||||
def _auth_check(cfg, account: str, logger: JsonLogger) -> dict[str, object]:
|
||||
credentials = getattr(cfg.bilibili, account)
|
||||
if not credentials.cookie:
|
||||
return {"account": account, "ok": False, "is_login": False, "message": "未配置 cookie"}
|
||||
state = _client(credentials, logger, retries=1).check_login()
|
||||
return {
|
||||
"account": account,
|
||||
"ok": state.is_login,
|
||||
"is_login": state.is_login,
|
||||
"mid": state.mid,
|
||||
"uname": state.uname,
|
||||
"code": state.code,
|
||||
"message": state.message,
|
||||
})
|
||||
return 0 if state.is_login else 1
|
||||
}
|
||||
|
||||
|
||||
def cmd_auth_check(args, logger: JsonLogger) -> int:
|
||||
store = ConfigStore(args.config, require_auth=False)
|
||||
cfg = store.get()
|
||||
if args.account != "all":
|
||||
result = _auth_check(cfg, args.account, logger)
|
||||
_print(result)
|
||||
return 0 if result["ok"] else 1
|
||||
results = [_auth_check(cfg, account, logger) for account in ("read", "write")]
|
||||
_print({"ok": all(result["ok"] for result in results), "accounts": results})
|
||||
return 0 if all(result["ok"] for result in results) else 1
|
||||
|
||||
|
||||
def cmd_run(args, logger: JsonLogger) -> int:
|
||||
@@ -179,9 +205,9 @@ def cmd_run(args, logger: JsonLogger) -> int:
|
||||
last: dict[str, object] = {}
|
||||
try:
|
||||
repo = Repository(db)
|
||||
folder_client = _client(cfg, logger)
|
||||
folder_client = _client(cfg.bilibili.read, logger)
|
||||
folder_service = FolderSyncService(store, repo, folder_client, logger=logger)
|
||||
snapshot_client = _client(cfg, logger, pacer=Pacer(1.0, 1.6), retries=1)
|
||||
snapshot_client = _client(cfg.bilibili.read, logger, pacer=Pacer(1.0, 1.6), retries=1)
|
||||
snapshot_service = SnapshotService(store, repo, snapshot_client, logger=logger)
|
||||
|
||||
def run_sync():
|
||||
@@ -284,6 +310,8 @@ def main(argv: Sequence[str] | None = None) -> int:
|
||||
return cmd_sync(args, logger)
|
||||
if args.command == "snapshot":
|
||||
return cmd_snapshot(args, logger)
|
||||
if args.command == "auth":
|
||||
return cmd_auth(args, logger)
|
||||
if args.command == "auth-check":
|
||||
return cmd_auth_check(args, logger)
|
||||
if args.command == "run":
|
||||
|
||||
Reference in new issue
Block a user