117 lines
3.8 KiB
Python
117 lines
3.8 KiB
Python
"""虎牙浏览器兑换的可选目标页:直播间 / 精英宝典 / 电竞宝典。
|
||
|
||
人工兑换时把账号登录态写入操作者自己的浏览器,再打开其中一个目标页:
|
||
- 直播间:直接进房间,适合在房间内完成的活动操作;
|
||
- 精英宝典:沿用绑定/充值活动的 zt 活动页(历史行为);
|
||
- 电竞宝典:同一活动的另一个 zt 活动页,仅 uuid 不同。
|
||
|
||
三个地址都由 pid(`HuyaConfig.room_pid`)与固定活动常量拼出,前端只传目标 key。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from ..huya_defaults import (
|
||
HUYA_DEFAULT_POINTS_PAGE_CODE,
|
||
HUYA_DEFAULT_POINTS_SOURCE_ID,
|
||
)
|
||
from .huya_runner_bind import HUYA_BIND_ROOM_ID, HUYA_BIND_ZT_UUID
|
||
from .huya_runner_core import HUYA_RECHARGE_SOURCE_ID
|
||
|
||
EXCHANGE_TARGET_LIVE_ROOM = "live_room"
|
||
EXCHANGE_TARGET_ELITE = "elite"
|
||
EXCHANGE_TARGET_ESPORTS = "esports"
|
||
|
||
#: 未指定目标时使用的默认页(保持历史行为:精英宝典)
|
||
DEFAULT_EXCHANGE_TARGET = EXCHANGE_TARGET_ELITE
|
||
|
||
#: 旧 zt 活动 uuid 仅保留给旧调用兼容;精英宝典现统一走积分中心页。
|
||
HUYA_ELITE_ZT_UUID = HUYA_BIND_ZT_UUID
|
||
HUYA_ESPORTS_ZT_UUID = "50ea007f"
|
||
|
||
#: 选择器展示顺序
|
||
EXCHANGE_TARGET_KEYS: tuple[str, ...] = (
|
||
EXCHANGE_TARGET_LIVE_ROOM,
|
||
EXCHANGE_TARGET_ELITE,
|
||
EXCHANGE_TARGET_ESPORTS,
|
||
)
|
||
|
||
EXCHANGE_TARGET_LABELS: dict[str, str] = {
|
||
EXCHANGE_TARGET_LIVE_ROOM: "直播间",
|
||
EXCHANGE_TARGET_ELITE: "精英宝典",
|
||
EXCHANGE_TARGET_ESPORTS: "电竞宝典",
|
||
}
|
||
|
||
#: 供 Pydantic 校验使用的正则
|
||
EXCHANGE_TARGET_PATTERN = "^(live_room|elite|esports)$"
|
||
|
||
|
||
def _zt_exchange_url(zt_uuid: str, room_pid: str) -> str:
|
||
"""拼 zt 活动页地址,参数与绑定/充值跳转保持一致。"""
|
||
return (
|
||
f"https://zt.huya.com/{zt_uuid}/pc/index.html"
|
||
f"?sourceId={HUYA_RECHARGE_SOURCE_ID}"
|
||
f"&pid={room_pid}"
|
||
f"&anchorUid={room_pid}"
|
||
f"&roomid={HUYA_BIND_ROOM_ID}"
|
||
)
|
||
|
||
|
||
def _points_exchange_url(
|
||
room_pid: str,
|
||
*,
|
||
page_code: str = HUYA_DEFAULT_POINTS_PAGE_CODE,
|
||
source_id: str = HUYA_DEFAULT_POINTS_SOURCE_ID,
|
||
) -> str:
|
||
pid = str(room_pid or "").strip()
|
||
return (
|
||
"https://m-shop.huya.com/points.html"
|
||
f"?pagecode={page_code}"
|
||
f"&sourceId={source_id}"
|
||
f"&pid={pid}"
|
||
f"&anchorUid={pid}"
|
||
f"&roomid={HUYA_BIND_ROOM_ID}"
|
||
)
|
||
|
||
|
||
def exchange_target_url(
|
||
key: str,
|
||
room_pid: str,
|
||
*,
|
||
points_page_code: str = HUYA_DEFAULT_POINTS_PAGE_CODE,
|
||
points_source_id: str = HUYA_DEFAULT_POINTS_SOURCE_ID,
|
||
) -> str:
|
||
"""返回指定目标页地址;pid 由调用方(路由)归一化,空值在这里会拼出无 pid 的地址。"""
|
||
if key == EXCHANGE_TARGET_LIVE_ROOM:
|
||
return f"https://www.huya.com/{HUYA_BIND_ROOM_ID}"
|
||
if key == EXCHANGE_TARGET_ELITE:
|
||
return _points_exchange_url(
|
||
room_pid,
|
||
page_code=points_page_code,
|
||
source_id=points_source_id,
|
||
)
|
||
if key == EXCHANGE_TARGET_ESPORTS:
|
||
return _zt_exchange_url(HUYA_ESPORTS_ZT_UUID, str(room_pid or "").strip())
|
||
raise ValueError(f"不支持的兑换目标:{key}")
|
||
|
||
|
||
def exchange_target_options(
|
||
room_pid: str,
|
||
*,
|
||
points_page_code: str = HUYA_DEFAULT_POINTS_PAGE_CODE,
|
||
points_source_id: str = HUYA_DEFAULT_POINTS_SOURCE_ID,
|
||
) -> list[dict[str, str]]:
|
||
"""返回三个可选目标页,顺序固定,供前端选择器渲染。"""
|
||
return [
|
||
{
|
||
"key": key,
|
||
"label": EXCHANGE_TARGET_LABELS[key],
|
||
"url": exchange_target_url(
|
||
key,
|
||
room_pid,
|
||
points_page_code=points_page_code,
|
||
points_source_id=points_source_id,
|
||
),
|
||
}
|
||
for key in EXCHANGE_TARGET_KEYS
|
||
]
|