front/xhs-agent-desktop/engine/xhs_bridge/license_codes.py
zzh 5a26ae0048 feat: 小红书模块迁移、登录重构与 xhs-agent-desktop 桌面 Agent
- 新增小红书前端模块(启动服务、内容分析、爆款创作、发布记录、技能卡片、拟人设置、AI 助手)

- 新增 xhs-agent-desktop 独立桌面 Agent,对接 OMS 任务调度

- 登录页重构,整合微信登录与 OMS JWT 认证

- 订单、渠道、用户中心等页面与 API 增强

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 16:13:13 +08:00

122 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime, timezone
@dataclass(frozen=True)
class BuiltinActivationCode:
"""内置激活码:固定自然月有效期,过期后不可再激活。"""
code: str
label: str # 如 2026-01,便于识别
expires_at: str # ISO8601 UTC,到达时刻起作废
def _month_label(year: int, month: int) -> str:
return f"{year}-{month:02d}"
def _month_expiry(year: int, month: int) -> str:
"""每月 1 日 0 点(UTC)为界:该月码在下一月 1 日 0 点作废。"""
if month == 12:
end_year, end_month = year + 1, 1
else:
end_year, end_month = year, month + 1
dt = datetime(end_year, end_month, 1, 0, 0, 0, tzinfo=timezone.utc)
return dt.isoformat()
# 12 个 GUID 激活码:2026-05 起连续 12 个月(至 2027-04),过期作废
_BUILTIN_CODE_GUIDS = (
"2A76F0DD-F7A0-480D-B0B2-8B4B41C283AA",
"12205DF6-02DE-4054-8C68-564543727A0F",
"729754A0-99BF-49AA-970A-2C3BFE793E1E",
"DCCE3DD5-C843-4C59-B033-CAA7E8DBA618",
"0CAC138E-8635-4511-8A8D-2EDBB55F60A3",
"4AEFA1D2-E852-41F1-880A-0EC76C544DFC",
"C2FC0006-28A7-4018-8DF3-CC7A589CFAB6",
"6C0F914D-CB48-4EF0-A5A4-A954FD2C48E2",
"488D70D7-472D-44EC-9573-AA40E1FFC2F8",
"C79718F6-6828-413B-98DA-42A0BC323D70",
"E1A4FA71-E258-4FE6-B60E-D4CA6831D0B2",
"C0DAA98A-678A-4F6D-A04B-38F824D104A8",
)
_START_YEAR = 2026
_START_MONTH = 5
def _builtin_month_sequence() -> list[tuple[int, int]]:
months: list[tuple[int, int]] = []
year, month = _START_YEAR, _START_MONTH
for _ in range(len(_BUILTIN_CODE_GUIDS)):
months.append((year, month))
if month == 12:
year, month = year + 1, 1
else:
month += 1
return months
BUILTIN_ACTIVATION_CODES: tuple[BuiltinActivationCode, ...] = tuple(
BuiltinActivationCode(
guid,
_month_label(year, month),
_month_expiry(year, month),
)
for guid, (year, month) in zip(_BUILTIN_CODE_GUIDS, _builtin_month_sequence(), strict=True)
)
_CODE_INDEX: dict[str, BuiltinActivationCode] = {
entry.code: entry for entry in BUILTIN_ACTIVATION_CODES
}
def normalize_activation_code(code: str) -> str:
text = code.strip().upper().replace(" ", "")
hex_only = text.replace("-", "")
if len(hex_only) == 32 and all(c in "0123456789ABCDEF" for c in hex_only):
return (
f"{hex_only[0:8]}-{hex_only[8:12]}-{hex_only[12:16]}-"
f"{hex_only[16:20]}-{hex_only[20:32]}"
)
return text
def lookup_builtin_code(code: str) -> BuiltinActivationCode | None:
return _CODE_INDEX.get(normalize_activation_code(code))
def get_builtin_code_for_period(period_label: str | None = None) -> BuiltinActivationCode | None:
"""按月份标签(如 2026-05)查找内置激活码;默认当前 UTC 月。"""
label = period_label or current_period_label()
for entry in BUILTIN_ACTIVATION_CODES:
if entry.label == label:
return entry
return None
def current_period_label(*, now: datetime | None = None) -> str:
"""当前自然月标签(UTC),与 BuiltinActivationCode.label 一致。"""
moment = now or datetime.now(timezone.utc)
if moment.tzinfo is None:
moment = moment.replace(tzinfo=timezone.utc)
else:
moment = moment.astimezone(timezone.utc)
return _month_label(moment.year, moment.month)
def is_builtin_code_current_month(
entry: BuiltinActivationCode, *, now: datetime | None = None
) -> bool:
return entry.label == current_period_label(now=now)
def is_builtin_code_expired(entry: BuiltinActivationCode, *, now: datetime | None = None) -> bool:
moment = now or datetime.now(timezone.utc)
exp = datetime.fromisoformat(entry.expires_at.replace("Z", "+00:00"))
if exp.tzinfo is None:
exp = exp.replace(tzinfo=timezone.utc)
return moment >= exp