- pyrightconfig.json 钉死 Python 3.12 虚拟环境,消除由于查找系统 Python 3.9 带来的假性报错 - 修复 huya/login.py 引用不存在函数的问题并补充单元测试 - 修复 browser_harvest.py 对 set 下标访问的错误并提升报错信息质量 - 虎牙 6 个子路由显式导入依赖,消除 import * 带来的未定义变量报警 - 规范化 Pydantic Field(default=...) 默认值声明 - 完善 solver.py / app_login.py 等核心路径类型守卫与 @overload 重载 - 在 pyproject.toml 中显式锁定 ruff lint 规则集 (E4, E7, E9, F, B, I, BLE) - 门禁脚本同步增加 ruff check 检查并在 AGENTS.md 补齐实践经验总结
205 lines
7.1 KiB
Python
205 lines
7.1 KiB
Python
"""虎牙自动注册批次与成功流水。"""
|
|
|
|
from fastapi import APIRouter
|
|
|
|
from ._common import (
|
|
Depends,
|
|
HTTPException,
|
|
HuyaAutoRegisterBatchOut,
|
|
HuyaAutoRegisterRequest,
|
|
HuyaAutoRegisterRetryRequest,
|
|
HuyaRegisterSuccessLogOut,
|
|
ProxyConfig,
|
|
Query,
|
|
Session,
|
|
StreamingResponse,
|
|
User,
|
|
_require_huya_perm,
|
|
export_success_logs_text,
|
|
get_current_user,
|
|
get_db,
|
|
huya_register_registry,
|
|
list_success_logs,
|
|
parse_sms_lines,
|
|
threading,
|
|
)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/register/batches", response_model=HuyaAutoRegisterBatchOut)
|
|
def create_auto_register_batch(
|
|
req: HuyaAutoRegisterRequest,
|
|
db: Session = Depends(get_db),
|
|
current: User = Depends(get_current_user),
|
|
):
|
|
"""启动虎牙手机号自动注册批次。"""
|
|
_require_huya_perm(current, "huya:import")
|
|
sms_lines = parse_sms_lines(req.text)
|
|
if not sms_lines:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="没有识别到有效手机号,格式为:手机号----短信查询URL 或 虎牙号----密码----手机号----短信查询URL",
|
|
)
|
|
|
|
proxy_config = db.query(ProxyConfig).first() if req.use_proxy else None
|
|
runner = huya_register_registry.create(
|
|
sms_lines=sms_lines,
|
|
tag=req.tag.strip(),
|
|
created_by=current.id,
|
|
concurrency=req.concurrency,
|
|
wait_seconds=req.wait_seconds,
|
|
poll_interval=req.poll_interval,
|
|
password_prefix=req.password_prefix,
|
|
fixed_password=req.fixed_password,
|
|
use_proxy=req.use_proxy,
|
|
proxy_config=proxy_config,
|
|
)
|
|
runner.mark_running("批次运行中")
|
|
thread = threading.Thread(target=runner.run, daemon=True)
|
|
thread.start()
|
|
return runner.snapshot()
|
|
|
|
|
|
@router.get("/register/batches", response_model=list[HuyaAutoRegisterBatchOut])
|
|
def list_auto_register_batches(
|
|
limit: int = Query(50, ge=1, le=200),
|
|
current: User = Depends(get_current_user),
|
|
):
|
|
"""列出历史自动注册批次(摘要,不含明细)。"""
|
|
_require_huya_perm(current, "huya:import")
|
|
return huya_register_registry.list_summaries(limit=limit)
|
|
|
|
|
|
@router.get("/register/batches/{batch_id}", response_model=HuyaAutoRegisterBatchOut)
|
|
def get_auto_register_batch(
|
|
batch_id: str,
|
|
current: User = Depends(get_current_user),
|
|
):
|
|
"""查询虎牙手机号自动注册批次状态(优先内存,否则读库)。"""
|
|
_require_huya_perm(current, "huya:import")
|
|
snapshot = huya_register_registry.get_snapshot(batch_id)
|
|
if not snapshot:
|
|
raise HTTPException(status_code=404, detail="批次不存在")
|
|
return snapshot
|
|
|
|
|
|
@router.post("/register/batches/{batch_id}/stop")
|
|
def stop_auto_register_batch(
|
|
batch_id: str,
|
|
current: User = Depends(get_current_user),
|
|
):
|
|
"""停止虎牙手机号自动注册批次。"""
|
|
_require_huya_perm(current, "huya:import")
|
|
runner = huya_register_registry.get(batch_id)
|
|
if not runner:
|
|
# 无内存 runner:若 DB 中存在且处于 running/interrupted,标记停止
|
|
snapshot = huya_register_registry.get_snapshot(batch_id)
|
|
if not snapshot:
|
|
raise HTTPException(status_code=404, detail="批次不存在")
|
|
return {"message": "批次未在本进程运行,无需停止", "success": True}
|
|
runner.stop()
|
|
return {"message": "已发送停止信号", "success": True}
|
|
|
|
|
|
@router.post(
|
|
"/register/batches/{batch_id}/retry", response_model=HuyaAutoRegisterBatchOut
|
|
)
|
|
def retry_auto_register_batch(
|
|
batch_id: str,
|
|
req: HuyaAutoRegisterRetryRequest | None = None,
|
|
db: Session = Depends(get_db),
|
|
current: User = Depends(get_current_user),
|
|
):
|
|
"""继续批次:默认从停止处往下跑(跳过成功与已失败);可传 mode 改行为。"""
|
|
_require_huya_perm(current, "huya:import")
|
|
if req is None:
|
|
req = HuyaAutoRegisterRetryRequest.model_construct()
|
|
use_proxy = req.use_proxy
|
|
# 先看历史批次是否用过代理
|
|
snapshot = huya_register_registry.get_snapshot(batch_id)
|
|
if not snapshot:
|
|
raise HTTPException(status_code=404, detail="批次不存在")
|
|
effective_proxy = (
|
|
snapshot.get("use_proxy", False) if use_proxy is None else bool(use_proxy)
|
|
)
|
|
proxy_config = db.query(ProxyConfig).first() if effective_proxy else None
|
|
try:
|
|
runner = huya_register_registry.retry(
|
|
batch_id,
|
|
proxy_config=proxy_config,
|
|
mode=req.mode,
|
|
concurrency=req.concurrency,
|
|
wait_seconds=req.wait_seconds,
|
|
poll_interval=req.poll_interval,
|
|
password_prefix=req.password_prefix,
|
|
fixed_password=req.fixed_password,
|
|
use_proxy=use_proxy,
|
|
)
|
|
except ValueError as exc:
|
|
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
|
except RuntimeError as exc:
|
|
raise HTTPException(status_code=409, detail=str(exc)) from exc
|
|
thread = threading.Thread(target=runner.run, daemon=True)
|
|
thread.start()
|
|
return runner.snapshot()
|
|
|
|
|
|
@router.get("/register/batches/{batch_id}/export")
|
|
def export_auto_register_batch_success(
|
|
batch_id: str,
|
|
current: User = Depends(get_current_user),
|
|
):
|
|
"""导出指定批次的成功账号 txt。"""
|
|
_require_huya_perm(current, "huya:import")
|
|
snapshot = huya_register_registry.get_snapshot(batch_id)
|
|
if not snapshot:
|
|
raise HTTPException(status_code=404, detail="批次不存在")
|
|
content = export_success_logs_text(batch_id=batch_id)
|
|
if not content.strip():
|
|
raise HTTPException(status_code=404, detail="该批次没有可导出的成功记录")
|
|
return StreamingResponse(
|
|
iter([content]),
|
|
media_type="text/plain; charset=utf-8",
|
|
headers={
|
|
"Content-Disposition": f"attachment; filename=huya-register-{batch_id}.txt"
|
|
},
|
|
)
|
|
|
|
|
|
@router.get("/register/success-logs", response_model=list[HuyaRegisterSuccessLogOut])
|
|
def list_register_success_logs(
|
|
batch_id: str | None = Query(None),
|
|
tag: str | None = Query(None),
|
|
limit: int = Query(200, ge=1, le=2000),
|
|
current: User = Depends(get_current_user),
|
|
):
|
|
"""列出注册成功流水(换电脑也可查看)。"""
|
|
_require_huya_perm(current, "huya:import")
|
|
return list_success_logs(batch_id=batch_id, tag=tag, limit=limit)
|
|
|
|
|
|
@router.get("/register/success-logs/export")
|
|
def export_register_success_logs(
|
|
batch_id: str | None = Query(None),
|
|
tag: str | None = Query(None),
|
|
limit: int = Query(5000, ge=1, le=20000),
|
|
current: User = Depends(get_current_user),
|
|
):
|
|
"""导出注册成功流水 txt:账号----密码----手机号----接码链接。"""
|
|
_require_huya_perm(current, "huya:import")
|
|
content = export_success_logs_text(batch_id=batch_id, tag=tag, limit=limit)
|
|
if not content.strip():
|
|
raise HTTPException(status_code=404, detail="没有可导出的成功记录")
|
|
filename = "huya-register-success"
|
|
if batch_id:
|
|
filename += f"-{batch_id}"
|
|
if tag:
|
|
filename += f"-{tag}"
|
|
filename += ".txt"
|
|
return StreamingResponse(
|
|
iter([content]),
|
|
media_type="text/plain; charset=utf-8",
|
|
headers={"Content-Disposition": f"attachment; filename={filename}"},
|
|
)
|