type: 收窄斗鱼手册与送礼执行器类型
This commit is contained in:
@@ -2,16 +2,45 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
from typing import Any, TYPE_CHECKING
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from core.douyu import DouyuActivityClient
|
from core.douyu import DouyuActivityClient
|
||||||
from ..models import Account, DouyuTask
|
from ..models import Account, DouyuTask
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .douyu_runner import DouyuBatchRunner
|
||||||
|
|
||||||
DOUYU_GIFT_POINTS_REFRESH_TIMES = 3
|
DOUYU_GIFT_POINTS_REFRESH_TIMES = 3
|
||||||
DOUYU_GIFT_POINTS_REFRESH_INTERVAL = 2
|
DOUYU_GIFT_POINTS_REFRESH_INTERVAL = 2
|
||||||
|
|
||||||
|
|
||||||
class DonateMixin:
|
class DonateMixin:
|
||||||
"""送礼域:精英令/电竞任务礼物赠送与积分确认。"""
|
"""送礼域:精英令/电竞任务礼物赠送与积分确认。"""
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
_stop: Any
|
||||||
|
|
||||||
|
def _client(self, cookie: str) -> DouyuActivityClient: ...
|
||||||
|
def _task_payload(self, task: DouyuTask) -> dict: ...
|
||||||
|
def _push_log(self, level: str, message: str) -> None: ...
|
||||||
|
def _mark_task(self, *args: Any, **kwargs: Any) -> None: ...
|
||||||
|
def _update_task_progress(self, *args: Any, **kwargs: Any) -> None: ...
|
||||||
|
def _refresh_account_points(
|
||||||
|
self,
|
||||||
|
client: DouyuActivityClient,
|
||||||
|
account: Account,
|
||||||
|
cookie: str,
|
||||||
|
*,
|
||||||
|
ctn: str | None = None,
|
||||||
|
) -> dict: ...
|
||||||
|
def _refresh_account_gold_balance(
|
||||||
|
self, client: DouyuActivityClient, account: Account
|
||||||
|
) -> dict: ...
|
||||||
|
def _refresh_esports_handbook(
|
||||||
|
self, client: DouyuActivityClient, account: Account, *, manual_id: str
|
||||||
|
) -> dict: ...
|
||||||
|
|
||||||
def _refresh_points_after_elite_gift(
|
def _refresh_points_after_elite_gift(
|
||||||
self,
|
self,
|
||||||
db: Session,
|
db: Session,
|
||||||
@@ -26,7 +55,9 @@ class DonateMixin:
|
|||||||
) -> dict:
|
) -> dict:
|
||||||
"""赠送精英令后短轮询积分;1 个精英令约等于 10 积分。"""
|
"""赠送精英令后短轮询积分;1 个精英令约等于 10 积分。"""
|
||||||
expected_gain = max(0, gift_count) * 10
|
expected_gain = max(0, gift_count) * 10
|
||||||
target_points = baseline_points + expected_gain if baseline_points is not None else None
|
target_points = (
|
||||||
|
baseline_points + expected_gain if baseline_points is not None else None
|
||||||
|
)
|
||||||
result["gift_points_baseline"] = baseline_points
|
result["gift_points_baseline"] = baseline_points
|
||||||
result["gift_points_expected_gain"] = expected_gain
|
result["gift_points_expected_gain"] = expected_gain
|
||||||
result["gift_points_target"] = target_points
|
result["gift_points_target"] = target_points
|
||||||
@@ -34,13 +65,19 @@ class DonateMixin:
|
|||||||
last_points = None
|
last_points = None
|
||||||
refresh_result: dict = {}
|
refresh_result: dict = {}
|
||||||
for index in range(1, DOUYU_GIFT_POINTS_REFRESH_TIMES + 1):
|
for index in range(1, DOUYU_GIFT_POINTS_REFRESH_TIMES + 1):
|
||||||
refresh_result = self._refresh_account_points(client, account, cookie, ctn=ctn)
|
refresh_result = self._refresh_account_points(
|
||||||
|
client, account, cookie, ctn=ctn
|
||||||
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
last_points = refresh_result["points"]
|
last_points = refresh_result["points"]
|
||||||
result.update(refresh_result)
|
result.update(refresh_result)
|
||||||
result["gift_points_refresh_count"] = index
|
result["gift_points_refresh_count"] = index
|
||||||
if target_points is None or (last_points is not None and last_points >= target_points):
|
if target_points is None or (
|
||||||
result["gift_points_confirmed"] = target_points is None or last_points is not None
|
last_points is not None and last_points >= target_points
|
||||||
|
):
|
||||||
|
result["gift_points_confirmed"] = (
|
||||||
|
target_points is None or last_points is not None
|
||||||
|
)
|
||||||
return refresh_result
|
return refresh_result
|
||||||
if index < DOUYU_GIFT_POINTS_REFRESH_TIMES:
|
if index < DOUYU_GIFT_POINTS_REFRESH_TIMES:
|
||||||
self._update_task_progress(
|
self._update_task_progress(
|
||||||
@@ -72,14 +109,20 @@ class DonateMixin:
|
|||||||
"""赠送电竞手册任务礼物并刷新独立积分。"""
|
"""赠送电竞手册任务礼物并刷新独立积分。"""
|
||||||
payload = self._task_payload(task)
|
payload = self._task_payload(task)
|
||||||
try:
|
try:
|
||||||
gift_count = max(1, int(payload.get("gift_count") or payload.get("count") or 1))
|
gift_count = max(
|
||||||
|
1, int(payload.get("gift_count") or payload.get("count") or 1)
|
||||||
|
)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
self._mark_task(db, task, "failed", "赠送数量必须是正整数")
|
self._mark_task(db, task, "failed", "赠送数量必须是正整数")
|
||||||
return
|
return
|
||||||
|
|
||||||
manual_id = str(config.get("esports_manual_id") or "").strip()
|
manual_id = str(config.get("esports_manual_id") or "").strip()
|
||||||
gift_id = str(payload.get("gift_id") or config.get(config_gift_id_key) or "").strip()
|
gift_id = str(
|
||||||
skin_id = str(payload.get("skin_id") or config.get(config_skin_id_key) or "").strip()
|
payload.get("gift_id") or config.get(config_gift_id_key) or ""
|
||||||
|
).strip()
|
||||||
|
skin_id = str(
|
||||||
|
payload.get("skin_id") or config.get(config_skin_id_key) or ""
|
||||||
|
).strip()
|
||||||
room_id = str(payload.get("room_id") or config.get("room_id") or "").strip()
|
room_id = str(payload.get("room_id") or config.get("room_id") or "").strip()
|
||||||
if not manual_id or not gift_id or not skin_id or not room_id:
|
if not manual_id or not gift_id or not skin_id or not room_id:
|
||||||
self._mark_task(db, task, "failed", "请先完整配置电竞手册、房间和礼物参数")
|
self._mark_task(db, task, "failed", "请先完整配置电竞手册、房间和礼物参数")
|
||||||
@@ -88,7 +131,9 @@ class DonateMixin:
|
|||||||
client = self._client(cookie)
|
client = self._client(cookie)
|
||||||
baseline_points = account.esports_points
|
baseline_points = account.esports_points
|
||||||
try:
|
try:
|
||||||
baseline = self._refresh_esports_handbook(client, account, manual_id=manual_id)
|
baseline = self._refresh_esports_handbook(
|
||||||
|
client, account, manual_id=manual_id
|
||||||
|
)
|
||||||
baseline_points = baseline["esports_points"]
|
baseline_points = baseline["esports_points"]
|
||||||
db.commit()
|
db.commit()
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
@@ -116,7 +161,9 @@ class DonateMixin:
|
|||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
refresh_errors.append(f"鱼翅余额: {exc}")
|
refresh_errors.append(f"鱼翅余额: {exc}")
|
||||||
try:
|
try:
|
||||||
points_result = self._refresh_esports_handbook(client, account, manual_id=manual_id)
|
points_result = self._refresh_esports_handbook(
|
||||||
|
client, account, manual_id=manual_id
|
||||||
|
)
|
||||||
result.update(points_result)
|
result.update(points_result)
|
||||||
result["esports_points_after_gift"] = points_result["esports_points"]
|
result["esports_points_after_gift"] = points_result["esports_points"]
|
||||||
result["esports_points_changed"] = (
|
result["esports_points_changed"] = (
|
||||||
@@ -178,7 +225,9 @@ class DonateMixin:
|
|||||||
config_skin_id_key="esports_firework_skin_id",
|
config_skin_id_key="esports_firework_skin_id",
|
||||||
)
|
)
|
||||||
|
|
||||||
def _execute_donate_elite_gift(self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict):
|
def _execute_donate_elite_gift(
|
||||||
|
self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict
|
||||||
|
):
|
||||||
payload = self._task_payload(task)
|
payload = self._task_payload(task)
|
||||||
gift_count = int(payload.get("gift_count") or payload.get("count") or 1)
|
gift_count = int(payload.get("gift_count") or payload.get("count") or 1)
|
||||||
client = self._client(cookie)
|
client = self._client(cookie)
|
||||||
@@ -186,7 +235,9 @@ class DonateMixin:
|
|||||||
baseline_points = account.points
|
baseline_points = account.points
|
||||||
try:
|
try:
|
||||||
ctn = client.acf_ccn(refresh_subscribe=False)
|
ctn = client.acf_ccn(refresh_subscribe=False)
|
||||||
baseline_result = self._refresh_account_points(client, account, cookie, ctn=ctn)
|
baseline_result = self._refresh_account_points(
|
||||||
|
client, account, cookie, ctn=ctn
|
||||||
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
baseline_points = baseline_result["points"]
|
baseline_points = baseline_result["points"]
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
@@ -228,7 +279,8 @@ class DonateMixin:
|
|||||||
message += f",鱼翅余额: {account.gold_balance}"
|
message += f",鱼翅余额: {account.gold_balance}"
|
||||||
if account.points is not None:
|
if account.points is not None:
|
||||||
message += f",积分: {account.points}"
|
message += f",积分: {account.points}"
|
||||||
if result.get("gift_points_target") is not None and not result.get("gift_points_confirmed"):
|
if result.get("gift_points_target") is not None and not result.get(
|
||||||
|
"gift_points_confirmed"
|
||||||
|
):
|
||||||
message += f"(未确认涨到 {result['gift_points_target']})"
|
message += f"(未确认涨到 {result['gift_points_target']})"
|
||||||
self._mark_task(db, task, "success", message, result)
|
self._mark_task(db, task, "success", message, result)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import time
|
import time
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
from typing import Any, TYPE_CHECKING
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from core.douyu import DouyuActivityClient, DouyuActivityError
|
from core.douyu import DouyuActivityClient, DouyuActivityError
|
||||||
@@ -10,8 +11,31 @@ from ..models import Account, DouyuTask
|
|||||||
from .douyu_service import account_uid, update_account_profile_from_cookie
|
from .douyu_service import account_uid, update_account_profile_from_cookie
|
||||||
from .douyu_runner_core import DOUYU_PAYMENT_POLL_INTERVAL, DOUYU_PAYMENT_POLL_SECONDS
|
from .douyu_runner_core import DOUYU_PAYMENT_POLL_INTERVAL, DOUYU_PAYMENT_POLL_SECONDS
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .douyu_runner import DouyuBatchRunner
|
||||||
|
|
||||||
|
|
||||||
class ManualMixin:
|
class ManualMixin:
|
||||||
"""手册域:精英/电竞手册开通支付、积分查询与到账轮询。"""
|
"""手册域:精英/电竞手册开通支付、积分查询与到账轮询。"""
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
_stop: Any
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _to_int(value: Any) -> int | None: ...
|
||||||
|
|
||||||
|
def _client(self, cookie: str) -> DouyuActivityClient: ...
|
||||||
|
def _task_payload(self, task: DouyuTask) -> dict: ...
|
||||||
|
def _push_log(self, level: str, message: str) -> None: ...
|
||||||
|
def _mark_task(self, *args: Any, **kwargs: Any) -> None: ...
|
||||||
|
def _update_task_progress(self, *args: Any, **kwargs: Any) -> None: ...
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _confirm_act_alias(cls, config: dict) -> str: ...
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _bind_qr_act_alias(cls, config: dict) -> str: ...
|
||||||
|
|
||||||
def _refresh_account_points(
|
def _refresh_account_points(
|
||||||
self,
|
self,
|
||||||
client: DouyuActivityClient,
|
client: DouyuActivityClient,
|
||||||
@@ -51,7 +75,9 @@ class ManualMixin:
|
|||||||
last_points = None
|
last_points = None
|
||||||
while not self._stop.is_set() and time.monotonic() <= deadline:
|
while not self._stop.is_set() and time.monotonic() <= deadline:
|
||||||
try:
|
try:
|
||||||
points_result = self._refresh_account_points(client, account, cookie, ctn=ctn)
|
points_result = self._refresh_account_points(
|
||||||
|
client, account, cookie, ctn=ctn
|
||||||
|
)
|
||||||
db.commit()
|
db.commit()
|
||||||
poll_count += 1
|
poll_count += 1
|
||||||
last_points = points_result["points"]
|
last_points = points_result["points"]
|
||||||
@@ -73,7 +99,9 @@ class ManualMixin:
|
|||||||
poll_count += 1
|
poll_count += 1
|
||||||
result["payment_poll_count"] = poll_count
|
result["payment_poll_count"] = poll_count
|
||||||
result["payment_poll_error"] = str(exc)
|
result["payment_poll_error"] = str(exc)
|
||||||
self._update_task_progress(db, task, "running", f"等待开通到账: {exc}", result)
|
self._update_task_progress(
|
||||||
|
db, task, "running", f"等待开通到账: {exc}", result
|
||||||
|
)
|
||||||
if self._stop.wait(DOUYU_PAYMENT_POLL_INTERVAL):
|
if self._stop.wait(DOUYU_PAYMENT_POLL_INTERVAL):
|
||||||
break
|
break
|
||||||
result["payment_polling"] = False
|
result["payment_polling"] = False
|
||||||
@@ -138,10 +166,7 @@ class ManualMixin:
|
|||||||
result.update(handbook_result)
|
result.update(handbook_result)
|
||||||
result["payment_poll_count"] = poll_count
|
result["payment_poll_count"] = poll_count
|
||||||
result["payment_polling"] = True
|
result["payment_polling"] = True
|
||||||
opened = (
|
opened = (last_manual_type is not None and last_manual_type >= 1) or (
|
||||||
last_manual_type is not None
|
|
||||||
and last_manual_type >= 1
|
|
||||||
) or (
|
|
||||||
baseline_manual_score is not None
|
baseline_manual_score is not None
|
||||||
and last_manual_score is not None
|
and last_manual_score is not None
|
||||||
and last_manual_score > baseline_manual_score
|
and last_manual_score > baseline_manual_score
|
||||||
@@ -163,7 +188,9 @@ class ManualMixin:
|
|||||||
poll_count += 1
|
poll_count += 1
|
||||||
result["payment_poll_count"] = poll_count
|
result["payment_poll_count"] = poll_count
|
||||||
result["payment_poll_error"] = str(exc)
|
result["payment_poll_error"] = str(exc)
|
||||||
self._update_task_progress(db, task, "running", f"等待电竞手册到账: {exc}", result)
|
self._update_task_progress(
|
||||||
|
db, task, "running", f"等待电竞手册到账: {exc}", result
|
||||||
|
)
|
||||||
if self._stop.wait(DOUYU_PAYMENT_POLL_INTERVAL):
|
if self._stop.wait(DOUYU_PAYMENT_POLL_INTERVAL):
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -175,7 +202,9 @@ class ManualMixin:
|
|||||||
result["points"] = last_manual_score
|
result["points"] = last_manual_score
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _execute_create_elite_qr(self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict):
|
def _execute_create_elite_qr(
|
||||||
|
self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict
|
||||||
|
):
|
||||||
client = self._client(cookie)
|
client = self._client(cookie)
|
||||||
ctn = str(self._task_payload(task).get("ctn") or "")
|
ctn = str(self._task_payload(task).get("ctn") or "")
|
||||||
if not ctn:
|
if not ctn:
|
||||||
@@ -192,15 +221,21 @@ class ManualMixin:
|
|||||||
)
|
)
|
||||||
account.bind_status = "elite_qr_created"
|
account.bind_status = "elite_qr_created"
|
||||||
account.updated_at = datetime.now(timezone.utc)
|
account.updated_at = datetime.now(timezone.utc)
|
||||||
self._update_task_progress(db, task, "running", "精英宝典支付码已生成,等待开通到账", result)
|
self._update_task_progress(
|
||||||
opened = self._wait_points_after_payment(db, task, account, client, cookie, ctn, result)
|
db, task, "running", "精英宝典支付码已生成,等待开通到账", result
|
||||||
|
)
|
||||||
|
opened = self._wait_points_after_payment(
|
||||||
|
db, task, account, client, cookie, ctn, result
|
||||||
|
)
|
||||||
if self._stop.is_set():
|
if self._stop.is_set():
|
||||||
self._mark_task(db, task, "stopped", "任务已停止", result)
|
self._mark_task(db, task, "stopped", "任务已停止", result)
|
||||||
return
|
return
|
||||||
if opened:
|
if opened:
|
||||||
account.bind_status = "elite_opened"
|
account.bind_status = "elite_opened"
|
||||||
account.updated_at = datetime.now(timezone.utc)
|
account.updated_at = datetime.now(timezone.utc)
|
||||||
self._mark_task(db, task, "success", f"精英宝典已开通,积分: {account.points}", result)
|
self._mark_task(
|
||||||
|
db, task, "success", f"精英宝典已开通,积分: {account.points}", result
|
||||||
|
)
|
||||||
return
|
return
|
||||||
self._mark_task(
|
self._mark_task(
|
||||||
db,
|
db,
|
||||||
@@ -226,14 +261,18 @@ class ManualMixin:
|
|||||||
act_alias = str(config.get("esports_act_alias") or "").strip()
|
act_alias = str(config.get("esports_act_alias") or "").strip()
|
||||||
manual_id = str(config.get("esports_manual_id") or "").strip()
|
manual_id = str(config.get("esports_manual_id") or "").strip()
|
||||||
if not act_alias or not manual_id:
|
if not act_alias or not manual_id:
|
||||||
self._mark_task(db, task, "failed", "请先配置电竞手册活动 actAlias 和 manualID")
|
self._mark_task(
|
||||||
|
db, task, "failed", "请先配置电竞手册活动 actAlias 和 manualID"
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
baseline_manual_type = None
|
baseline_manual_type = None
|
||||||
baseline_manual_score = None
|
baseline_manual_score = None
|
||||||
baseline_result: dict = {}
|
baseline_result: dict = {}
|
||||||
try:
|
try:
|
||||||
baseline_result = self._refresh_esports_handbook(client, account, manual_id=manual_id)
|
baseline_result = self._refresh_esports_handbook(
|
||||||
|
client, account, manual_id=manual_id
|
||||||
|
)
|
||||||
baseline_manual_type = baseline_result["esports_manual_type"]
|
baseline_manual_type = baseline_result["esports_manual_type"]
|
||||||
baseline_manual_score = baseline_result["esports_manual_score"]
|
baseline_manual_score = baseline_result["esports_manual_score"]
|
||||||
db.commit()
|
db.commit()
|
||||||
@@ -261,7 +300,9 @@ class ManualMixin:
|
|||||||
result.update(baseline_result)
|
result.update(baseline_result)
|
||||||
account.esports_bind_status = "esports_qr_created"
|
account.esports_bind_status = "esports_qr_created"
|
||||||
account.updated_at = datetime.now(timezone.utc)
|
account.updated_at = datetime.now(timezone.utc)
|
||||||
self._update_task_progress(db, task, "running", "电竞手册支付码已生成,等待开通到账", result)
|
self._update_task_progress(
|
||||||
|
db, task, "running", "电竞手册支付码已生成,等待开通到账", result
|
||||||
|
)
|
||||||
opened = self._wait_esports_open_after_payment(
|
opened = self._wait_esports_open_after_payment(
|
||||||
db,
|
db,
|
||||||
task,
|
task,
|
||||||
@@ -314,14 +355,27 @@ class ManualMixin:
|
|||||||
account.esports_bind_status = "esports_points_queried"
|
account.esports_bind_status = "esports_points_queried"
|
||||||
account.updated_at = datetime.now(timezone.utc)
|
account.updated_at = datetime.now(timezone.utc)
|
||||||
points = result["esports_points"]
|
points = result["esports_points"]
|
||||||
self._mark_task(db, task, "success", f"电竞积分: {points if points is not None else '-'}", result)
|
self._mark_task(
|
||||||
|
db,
|
||||||
|
task,
|
||||||
|
"success",
|
||||||
|
f"电竞积分: {points if points is not None else '-'}",
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
|
||||||
def _execute_query_points(self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict):
|
def _execute_query_points(
|
||||||
|
self, db: Session, task: DouyuTask, account: Account, cookie: str, config: dict
|
||||||
|
):
|
||||||
client = self._client(cookie)
|
client = self._client(cookie)
|
||||||
ctn = client.acf_ccn(refresh_subscribe=False)
|
ctn = client.acf_ccn(refresh_subscribe=False)
|
||||||
result = self._refresh_account_points(client, account, cookie, ctn=ctn)
|
result = self._refresh_account_points(client, account, cookie, ctn=ctn)
|
||||||
account.bind_status = "points_queried"
|
account.bind_status = "points_queried"
|
||||||
account.updated_at = datetime.now(timezone.utc)
|
account.updated_at = datetime.now(timezone.utc)
|
||||||
points = result["points"]
|
points = result["points"]
|
||||||
self._mark_task(db, task, "success", f"积分: {points if points is not None else '-'}", result)
|
self._mark_task(
|
||||||
|
db,
|
||||||
|
task,
|
||||||
|
"success",
|
||||||
|
f"积分: {points if points is not None else '-'}",
|
||||||
|
result,
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user