697 lines
22 KiB
Python
697 lines
22 KiB
Python
from collections.abc import Mapping, Sequence
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Optional
|
|
|
|
from astrbot.api import logger
|
|
|
|
from ..fun_basic import compare_date_str, week_to_num
|
|
from .base import DATA_PROCESSING_ERRORS, BaseDomainService
|
|
|
|
|
|
def _text(value: Any, default: str = "无") -> str:
|
|
if value is None:
|
|
return default
|
|
result = str(value).strip()
|
|
return result or default
|
|
|
|
|
|
def _format_items(value: Any) -> str:
|
|
if value is None:
|
|
return "无"
|
|
if isinstance(value, str):
|
|
items = [value.strip()] if value.strip() else []
|
|
elif isinstance(value, Sequence) and not isinstance(value, (bytes, bytearray)):
|
|
items = [text for item in value if (text := _text(item, ""))]
|
|
else:
|
|
items = []
|
|
return "\n".join(f"• {item}" for item in items) if items else "无"
|
|
|
|
|
|
class CalendarService(BaseDomainService):
|
|
async def richang(self, server: str, num: int = 0) -> Dict[str, Any]:
|
|
"""日常活动"""
|
|
params = {"server": server, "num": num}
|
|
data: Optional[Dict[str, Any]] = await self.request(
|
|
"jx3_richang", params=params
|
|
)
|
|
if not isinstance(data, dict) or not data:
|
|
return self.failure("获取接口信息失败")
|
|
|
|
week = _text(data.get("week"), "未知")
|
|
week_label = week if week.startswith("星期") else f"星期{week}"
|
|
|
|
weekly = data.get("weekly")
|
|
if isinstance(weekly, Mapping):
|
|
weekly_conn = weekly.get("conn")
|
|
weekly_raid = weekly.get("raid")
|
|
else:
|
|
weekly_conn = None
|
|
weekly_raid = None
|
|
|
|
lines = [
|
|
f"【{_text(server, '未知服务器')}】",
|
|
f"{_text(data.get('date'), '未知日期')} {week_label}",
|
|
"",
|
|
"【今日活动】",
|
|
f"大战:{_text(data.get('war'))}",
|
|
f"战场:{_text(data.get('battle'))}",
|
|
f"阵营:{_text(data.get('orecar'))}",
|
|
f"宗门:{_text(data.get('school'))}",
|
|
f"驰援:{_text(data.get('rescue'))}",
|
|
"",
|
|
"【画像】",
|
|
_format_items(data.get("draw")),
|
|
"",
|
|
"【宠物福缘】",
|
|
_format_items(data.get("lucky")),
|
|
"",
|
|
"【家园声望·加倍道具】",
|
|
_format_items(data.get("card")),
|
|
"",
|
|
"【武林通鉴·公共任务】",
|
|
_format_items(weekly_conn),
|
|
"",
|
|
"【武林通鉴·团队秘境】",
|
|
_format_items(weekly_raid),
|
|
]
|
|
return self.success("\n".join(lines))
|
|
|
|
async def richangyuche(self) -> Dict[str, Any]:
|
|
"""日常预测"""
|
|
return_data = self.new_result()
|
|
|
|
# 1. 构造请求参数
|
|
params = {"num": 30}
|
|
|
|
# 2. 调用基础请求
|
|
data: Optional[Dict[str, Any]] = await self.request(
|
|
"jx3_richangyuche", params=params
|
|
)
|
|
if not data:
|
|
return_data["msg"] = "获取接口信息失败"
|
|
return return_data
|
|
|
|
# 3. 处理返回数据
|
|
try:
|
|
items = []
|
|
num_richang = week_to_num(data["data"][0]["week"]) or 0
|
|
# 空白数据
|
|
for _ in range(num_richang):
|
|
items.append(
|
|
{"en": False, "compare": "", "date": "", "war": "", "battle": ""}
|
|
)
|
|
|
|
# 真实数据
|
|
for m in data["data"]:
|
|
items.append(
|
|
{
|
|
"en": True,
|
|
"compare": compare_date_str(m.get("date", "")),
|
|
"date": m.get("date", ""),
|
|
"war": m.get("war", ""),
|
|
"battle": m.get("battle", ""),
|
|
}
|
|
)
|
|
|
|
return_data["data"]["items"] = items
|
|
return_data["data"]["today"] = data["today"]
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"数据处理时出错: {e}")
|
|
return_data["msg"] = "处理接口返回信息时出错"
|
|
return return_data
|
|
|
|
# 加载模板
|
|
if not await self.attach_template(return_data, "richangyuche.html"):
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def xingxiashijian(self, name: str) -> Dict[str, Any]:
|
|
"""行侠事件"""
|
|
return_data = self.new_result()
|
|
|
|
# 1. 构造请求参数
|
|
params = {"name": name}
|
|
|
|
# 2. 调用基础请求
|
|
data: Optional[Dict[str, Any]] = await self.request(
|
|
"jx3_xingxiashijian", params=params
|
|
)
|
|
if not data:
|
|
return_data["msg"] = "获取接口信息失败"
|
|
return return_data
|
|
|
|
# 3. 处理返回数据
|
|
try:
|
|
return_data["data"]["items"] = data
|
|
return_data["data"]["name"] = name
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"数据处理时出错: {e}")
|
|
return_data["msg"] = "处理接口返回信息时出错"
|
|
return return_data
|
|
|
|
# 加载模板
|
|
if not await self.attach_template(return_data, "xingxiashijian.html"):
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def shaohua(self) -> Dict[str, Any]:
|
|
"""骚话"""
|
|
return_data = self.new_result()
|
|
|
|
# 因为没有参数,所以 params=None
|
|
data: Optional[Dict[str, Any]] = await self.request("jx3_shaohua")
|
|
|
|
if not data:
|
|
return_data["msg"] = "获取接口信息失败"
|
|
return return_data
|
|
|
|
text = data.get("text")
|
|
if text:
|
|
return_data["data"] = text
|
|
else:
|
|
return_data["msg"] = "接口未返回文本"
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def jiemi(self) -> Dict[str, Any]:
|
|
"""解密"""
|
|
return_data = self.new_result()
|
|
|
|
params = {}
|
|
|
|
data: Optional[Dict[str, Any]] = await self.request("jx3_jiemi", params=params)
|
|
|
|
if not data or not isinstance(data, dict):
|
|
return_data["msg"] = "未查询到解密信息"
|
|
return return_data
|
|
|
|
try:
|
|
curr = data.get("curr", {})
|
|
next_data = data.get("next", {})
|
|
if not isinstance(curr, dict):
|
|
curr = {}
|
|
if not isinstance(next_data, dict):
|
|
next_data = {}
|
|
|
|
return_data["data"] = "\n".join(
|
|
[
|
|
"解密",
|
|
f"当前时间:{data.get('time', '')}",
|
|
f"当前节点:{curr.get('node', '')}",
|
|
f"当前结果:{curr.get('data', '')}",
|
|
f"下轮节点:{next_data.get('node', '')}",
|
|
f"下轮结果:{next_data.get('data', '')}",
|
|
f"剩余时间:{data.get('cdtn', '')}",
|
|
]
|
|
)
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"处理解密数据失败: {e}")
|
|
return_data["msg"] = "处理解密数据失败"
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def baizhan(self) -> Dict[str, Any]:
|
|
"""百战首领"""
|
|
return_data = self.new_result()
|
|
|
|
# 1. 构造请求参数
|
|
params = {}
|
|
|
|
data: Optional[Dict[str, Any]] = await self.request(
|
|
"jx3_baizhan", params=params
|
|
)
|
|
|
|
if not data:
|
|
return_data["msg"] = "获取接口信息失败"
|
|
return return_data
|
|
# 处理返回数据
|
|
|
|
try:
|
|
return_data["data"] = data
|
|
return_data["data"]["start"] = datetime.fromtimestamp(
|
|
float(data["start"])
|
|
).strftime("%Y-%m-%d %H:%M:%S")
|
|
return_data["data"]["end"] = datetime.fromtimestamp(
|
|
float(data["end"])
|
|
).strftime("%Y-%m-%d %H:%M:%S")
|
|
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"数据处理时出错: {e}")
|
|
return_data["msg"] = "处理接口返回信息时出错"
|
|
# 加载模板
|
|
if not await self.attach_template(return_data, "baizhan.html"):
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def fuyaojjiutian(self, server: str) -> Dict[str, Any]:
|
|
"""扶摇九天"""
|
|
return_data = self.new_result()
|
|
|
|
# 1. 构造请求参数
|
|
params = {"server": server}
|
|
|
|
# 2. 调用基础请求
|
|
data: Optional[list[Dict[str, Any]]] = await self.request(
|
|
"jx3_fuyaojiutian", params=params
|
|
)
|
|
|
|
if not data:
|
|
return_data["msg"] = "获取接口信息失败"
|
|
return return_data
|
|
|
|
# 3. 处理返回数据
|
|
try:
|
|
data_new = data[0]
|
|
data_time = datetime.fromtimestamp(data_new["time"]).strftime(
|
|
"%Y-%m-%d %H:%M:%S"
|
|
)
|
|
result_msg = f"{server}\n"
|
|
if data_new["status"] == 0:
|
|
result_msg += "本轮扶摇九天尚未开启\n"
|
|
if data_new["status"] == 1:
|
|
result_msg += "本轮扶摇九天正在进行\n"
|
|
if data_new["status"] == 2:
|
|
result_msg += "本轮扶摇九天已经结束\n"
|
|
result_msg += f"开启时间:{data_time}\n"
|
|
return_data["data"] = result_msg
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"处理返回数据失败: {e}")
|
|
return_data["msg"] = "处理返回数据失败"
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def zhueevent(self) -> Dict[str, Any]:
|
|
"""诛恶事件"""
|
|
return_data = self.new_result()
|
|
|
|
params = {}
|
|
|
|
data: Optional[List[Dict[str, Any]]] = await self.request(
|
|
"jx3_zhueevent", params=params
|
|
)
|
|
|
|
if not data or not isinstance(data, list):
|
|
return_data["msg"] = "未查询到诛恶事件信息"
|
|
return return_data
|
|
|
|
try:
|
|
items = []
|
|
for item in data:
|
|
if not isinstance(item, dict):
|
|
continue
|
|
|
|
event_time = item.get("time")
|
|
if event_time:
|
|
try:
|
|
item["time"] = datetime.fromtimestamp(int(event_time)).strftime(
|
|
"%Y-%m-%d %H:%M:%S"
|
|
)
|
|
except (TypeError, ValueError, OSError):
|
|
item["time"] = str(event_time)
|
|
else:
|
|
item["time"] = ""
|
|
|
|
items.append(item)
|
|
|
|
if not items:
|
|
return_data["msg"] = "未查询到诛恶事件信息"
|
|
return return_data
|
|
|
|
return_data["data"] = {
|
|
"items": items,
|
|
"update_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
}
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"处理诛恶事件数据失败: {e}")
|
|
return_data["msg"] = "处理诛恶事件数据失败"
|
|
return return_data
|
|
|
|
if not await self.attach_template(return_data, "zhueevent.html"):
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def benrichitu(self) -> Dict[str, Any]:
|
|
"""本日赤兔"""
|
|
return_data = self.new_result()
|
|
|
|
params = {}
|
|
|
|
data: Optional[List[Dict[str, Any]]] = await self.request(
|
|
"jx3_benrichitu", params=params
|
|
)
|
|
|
|
def no_data() -> Dict[str, Any]:
|
|
return_data["code"] = 200
|
|
return_data["data"] = "本日赤兔 暂无数据"
|
|
return return_data
|
|
|
|
if not data or not isinstance(data, list):
|
|
return no_data()
|
|
|
|
try:
|
|
items = []
|
|
for item in data:
|
|
if not isinstance(item, dict):
|
|
continue
|
|
|
|
date_value = item.get("date", "")
|
|
if date_value:
|
|
try:
|
|
date_text = datetime.fromtimestamp(int(date_value)).strftime(
|
|
"%Y-%m-%d %H:%M:%S"
|
|
)
|
|
except (TypeError, ValueError, OSError):
|
|
date_text = str(date_value)
|
|
else:
|
|
date_text = ""
|
|
|
|
items.append(
|
|
{
|
|
"date": date_text,
|
|
"server": item.get("server", ""),
|
|
"map_name": item.get("map_name", ""),
|
|
}
|
|
)
|
|
|
|
if not items:
|
|
return no_data()
|
|
|
|
result_lines = ["本日赤兔"]
|
|
for item in items:
|
|
result_lines.extend(
|
|
[
|
|
f"时间:{item['date']}",
|
|
f"区服:{item['server']}",
|
|
f"地图:{item['map_name']}",
|
|
"",
|
|
]
|
|
)
|
|
|
|
return_data["code"] = 200
|
|
return_data["data"] = "\n".join(result_lines).rstrip()
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"处理本日赤兔数据失败: {e}")
|
|
return no_data()
|
|
|
|
return return_data
|
|
|
|
async def benzhouchitu(self) -> Dict[str, Any]:
|
|
"""本周赤兔"""
|
|
return_data = self.new_result()
|
|
|
|
params = {}
|
|
|
|
data: Optional[List[Dict[str, Any]]] = await self.request(
|
|
"jx3_benzhouchitu", params=params
|
|
)
|
|
|
|
def no_data() -> Dict[str, Any]:
|
|
return_data["code"] = 200
|
|
return_data["data"] = "本周赤兔 暂无数据"
|
|
return return_data
|
|
|
|
if not data or not isinstance(data, list):
|
|
return no_data()
|
|
|
|
try:
|
|
items = []
|
|
for item in data:
|
|
if not isinstance(item, dict):
|
|
continue
|
|
|
|
date_value = item.get("date", "")
|
|
if date_value:
|
|
try:
|
|
date_text = datetime.fromtimestamp(int(date_value)).strftime(
|
|
"%Y-%m-%d %H:%M:%S"
|
|
)
|
|
except (TypeError, ValueError, OSError):
|
|
date_text = str(date_value)
|
|
else:
|
|
date_text = ""
|
|
|
|
items.append(
|
|
{
|
|
"date": date_text,
|
|
"server": item.get("server", ""),
|
|
"map_name": item.get("map_name", ""),
|
|
}
|
|
)
|
|
|
|
if not items:
|
|
return no_data()
|
|
|
|
result_lines = ["本周赤兔"]
|
|
for item in items:
|
|
result_lines.extend(
|
|
[
|
|
f"时间:{item['date']}",
|
|
f"区服:{item['server']}",
|
|
f"地图:{item['map_name']}",
|
|
"",
|
|
]
|
|
)
|
|
|
|
return_data["code"] = 200
|
|
return_data["data"] = "\n".join(result_lines).rstrip()
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"处理本周赤兔数据失败: {e}")
|
|
return no_data()
|
|
|
|
return return_data
|
|
|
|
async def zhenyingevent(self) -> Dict[str, Any]:
|
|
"""阵营事件"""
|
|
return_data = self.new_result()
|
|
|
|
params = {}
|
|
|
|
data: Optional[List[Dict[str, Any]]] = await self.request(
|
|
"jx3_zhenyingevent", params=params
|
|
)
|
|
|
|
if not data or not isinstance(data, list):
|
|
return_data["msg"] = "未查询到阵营事件信息"
|
|
return return_data
|
|
|
|
try:
|
|
items = []
|
|
for item in data:
|
|
if not isinstance(item, dict):
|
|
continue
|
|
|
|
seize_time = item.get("seize_time")
|
|
if seize_time:
|
|
try:
|
|
item["seize_time"] = datetime.fromtimestamp(
|
|
int(seize_time)
|
|
).strftime("%Y-%m-%d %H:%M:%S")
|
|
except (TypeError, ValueError, OSError):
|
|
item["seize_time"] = str(seize_time)
|
|
else:
|
|
item["seize_time"] = ""
|
|
|
|
items.append(item)
|
|
|
|
if not items:
|
|
return_data["msg"] = "未查询到阵营事件信息"
|
|
return return_data
|
|
|
|
return_data["data"] = {
|
|
"items": items,
|
|
"update_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
}
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"处理阵营事件数据失败: {e}")
|
|
return_data["msg"] = "处理阵营事件数据失败"
|
|
return return_data
|
|
|
|
if not await self.attach_template(return_data, "zhenyingevent.html"):
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def guanaishouling(self) -> Dict[str, Any]:
|
|
"""关隘首领"""
|
|
return_data = self.new_result()
|
|
|
|
params = {}
|
|
|
|
data: Optional[List[Dict[str, Any]]] = await self.request(
|
|
"jx3_guanaishouling", params=params
|
|
)
|
|
|
|
if not data or not isinstance(data, list):
|
|
return_data["msg"] = "未查询到关隘首领信息"
|
|
return return_data
|
|
|
|
try:
|
|
now_ts = int(datetime.now().timestamp())
|
|
|
|
def format_time(value: Any) -> str:
|
|
if not value:
|
|
return ""
|
|
try:
|
|
return datetime.fromtimestamp(int(value)).strftime(
|
|
"%Y-%m-%d %H:%M:%S"
|
|
)
|
|
except (TypeError, ValueError, OSError):
|
|
return str(value)
|
|
|
|
def format_remaining(end_time: Any) -> str:
|
|
if not end_time:
|
|
return ""
|
|
try:
|
|
seconds = max(0, int(end_time) - now_ts)
|
|
except (TypeError, ValueError):
|
|
return str(end_time)
|
|
|
|
hours = seconds // 3600
|
|
minutes = (seconds % 3600) // 60
|
|
secs = seconds % 60
|
|
return f"{hours}时{minutes:02d}分{secs:02d}秒"
|
|
|
|
groups = []
|
|
for group in data:
|
|
if not isinstance(group, dict):
|
|
continue
|
|
|
|
records = group.get("data", [])
|
|
if not isinstance(records, list) or not records:
|
|
continue
|
|
|
|
parsed_records = []
|
|
for item in records:
|
|
if not isinstance(item, dict):
|
|
continue
|
|
|
|
end_time = item.get("end_time")
|
|
parsed_records.append(
|
|
{
|
|
"camp_name": item.get("camp_name", ""),
|
|
"castle": item.get("castle", ""),
|
|
"str_status": item.get("str_status", ""),
|
|
"start_time": format_time(item.get("start_time")),
|
|
"end_time": format_time(end_time),
|
|
"remaining_time": format_remaining(end_time),
|
|
}
|
|
)
|
|
|
|
if parsed_records:
|
|
groups.append(
|
|
{
|
|
"server": group.get("server", ""),
|
|
"records": parsed_records,
|
|
}
|
|
)
|
|
|
|
if not groups:
|
|
return_data["msg"] = "未查询到关隘首领信息"
|
|
return return_data
|
|
|
|
return_data["data"] = {
|
|
"groups": groups,
|
|
"update_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
}
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"处理关隘首领数据失败: {e}")
|
|
return_data["msg"] = "处理关隘首领数据失败"
|
|
return return_data
|
|
|
|
if not await self.attach_template(return_data, "guanaishouling.html"):
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def shuamamsg(self, server: str, type: str, subtype: str) -> Dict[str, Any]:
|
|
"""刷马消息"""
|
|
return_data = self.new_result()
|
|
|
|
params = {"server": server, "type": type, "subtype": subtype}
|
|
# 提取字段可能返回字典
|
|
data: Optional[Dict[str, Any]] = await self.request(
|
|
"jx3box_shuamamsg", params=params
|
|
)
|
|
|
|
if not data:
|
|
return_data["msg"] = "获取接口信息失败或数据格式错误"
|
|
return return_data
|
|
|
|
try:
|
|
#
|
|
new_msg = data.get("list", [])[0]
|
|
return_data["status"] = new_msg.get("id")
|
|
|
|
result_msg = f"{server}\n"
|
|
result_msg += f"{new_msg.get('content')}\n"
|
|
result_msg += f"{new_msg.get('created_at')}\n"
|
|
|
|
return_data["data"] = result_msg
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"数据处理时出错: {e}")
|
|
return_data["msg"] = "处理接口返回信息时出错"
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|
|
|
|
async def shuma(self, server: str) -> Dict[str, Any]:
|
|
"""刷马"""
|
|
return_data = self.new_result()
|
|
|
|
# 1. 构造请求参数
|
|
params = {"server": server}
|
|
|
|
# 2. 调用基础请求
|
|
data: Optional[Dict[str, Any]] = await self.request(
|
|
"jx3_shuama", params=params, out_key=""
|
|
)
|
|
|
|
if not data:
|
|
return_data["msg"] = "获取接口信息失败"
|
|
return return_data
|
|
|
|
# 3. 处理返回数据
|
|
try:
|
|
_data = data["data"]["data"]
|
|
result_msg = f"{server}\n"
|
|
result_msg += f"黑戈壁:\n{_data['黑戈壁'][0]}\n"
|
|
result_msg += f"阴山大草原:\n{_data['阴山大草原'][0]}\n"
|
|
result_msg += f"鲲鹏岛:\n{_data['鲲鹏岛'][0]}\n"
|
|
result_msg += f"\n{data['data']['note']}"
|
|
return_data["data"] = result_msg
|
|
except DATA_PROCESSING_ERRORS as e:
|
|
logger.error(f"处理返回数据失败: {e}")
|
|
return_data["msg"] = "处理返回数据失败"
|
|
return return_data
|
|
|
|
return_data["code"] = 200
|
|
|
|
return return_data
|