mirror of
https://github.com/PaiGramTeam/MibooGram.git
synced 2025-01-08 06:37:13 +00:00
♻️ Abyss overview show all data
This commit is contained in:
parent
db7aec6f84
commit
9b385cc995
@ -1,12 +1,9 @@
|
||||
"""防卫战数据查询"""
|
||||
|
||||
import asyncio
|
||||
import math
|
||||
import re
|
||||
from functools import lru_cache, partial
|
||||
from typing import Any, List, Optional, Tuple, Union, TYPE_CHECKING
|
||||
from typing import List, Optional, Tuple, TYPE_CHECKING
|
||||
|
||||
from arkowrapper import ArkoWrapper
|
||||
from simnet.models.zzz.chronicle.challenge import ZZZChallenge
|
||||
from telegram import Message, Update, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from telegram.constants import ChatAction, ParseMode
|
||||
@ -17,7 +14,7 @@ from core.plugin import Plugin, handler
|
||||
from core.services.cookies.error import TooManyRequestPublicCookies
|
||||
from core.services.history_data.models import HistoryDataAbyss
|
||||
from core.services.history_data.services import HistoryDataAbyssServices
|
||||
from core.services.template.models import RenderGroupResult, RenderResult
|
||||
from core.services.template.models import RenderResult
|
||||
from core.services.template.services import TemplateService
|
||||
from gram_core.config import config
|
||||
from gram_core.dependence.redisdb import RedisDB
|
||||
@ -44,18 +41,9 @@ MAX_STARS = MAX_FLOOR * 3
|
||||
|
||||
|
||||
@lru_cache
|
||||
def get_args(text: str) -> Tuple[int, bool, bool]:
|
||||
if text.startswith("/"):
|
||||
result = re.match(cmd_pattern, text).groups()
|
||||
try:
|
||||
floor = int(result[0] or 0)
|
||||
if floor > 100:
|
||||
floor = 0
|
||||
except ValueError:
|
||||
floor = 0
|
||||
return floor, result[0] == "all", bool(result[1])
|
||||
result = re.match(msg_pattern, text).groups()
|
||||
return int(result[2] or 0), result[0] == "总览", result[1] == "上期"
|
||||
def get_args(text: str) -> bool:
|
||||
prev = "pre" in text or "上期" in text
|
||||
return prev
|
||||
|
||||
|
||||
class AbyssUnlocked(Exception):
|
||||
@ -103,10 +91,11 @@ class ChallengePlugin(Plugin):
|
||||
|
||||
@handler.command("challenge", block=False)
|
||||
@handler.message(filters.Regex(msg_pattern), block=False)
|
||||
async def command_start(self, update: Update, _: CallbackContext) -> None:
|
||||
async def command_start(self, update: Update, context: CallbackContext) -> None:
|
||||
user_id = await self.get_real_user_id(update)
|
||||
message = update.effective_message
|
||||
uid, offset = self.get_real_uid_or_offset(update)
|
||||
args = self.get_args(context)
|
||||
message = update.effective_message
|
||||
uid: int = await self.get_uid(user_id, message.reply_to_message, uid, offset)
|
||||
|
||||
# 若查询帮助
|
||||
@ -124,22 +113,13 @@ class ChallengePlugin(Plugin):
|
||||
return
|
||||
|
||||
# 解析参数
|
||||
floor, total, previous = get_args(message.text)
|
||||
|
||||
if floor > MAX_FLOOR or floor < 0:
|
||||
reply_msg = await message.reply_text(f"防卫战层数输入错误,请重新输入。支持的参数为: 1-{MAX_FLOOR} 或 all")
|
||||
if filters.ChatType.GROUPS.filter(message):
|
||||
self.add_delete_message_job(reply_msg)
|
||||
self.add_delete_message_job(message)
|
||||
return
|
||||
previous = get_args(" ".join([i for i in args if not i.startswith("@")]))
|
||||
|
||||
self.log_user(
|
||||
update,
|
||||
logger.info,
|
||||
"[bold]防卫战挑战数据[/bold]请求: uid=%s floor=%s total=%s previous=%s",
|
||||
"[bold]防卫战挑战数据[/bold]请求: uid=%s previous=%s",
|
||||
uid,
|
||||
floor,
|
||||
total,
|
||||
previous,
|
||||
extra={"markup": True},
|
||||
)
|
||||
@ -151,13 +131,12 @@ class ChallengePlugin(Plugin):
|
||||
|
||||
try:
|
||||
async with self.helper.genshin_or_public(user_id, uid=uid) as client:
|
||||
if total:
|
||||
reply_text = await message.reply_text(
|
||||
f"{config.notice.bot_name} 需要时间整理防卫战数据,还请耐心等待哦~"
|
||||
)
|
||||
reply_text = await message.reply_text(
|
||||
f"{config.notice.bot_name} 需要时间整理防卫战数据,还请耐心等待哦~"
|
||||
)
|
||||
await message.reply_chat_action(ChatAction.TYPING)
|
||||
abyss_data = await self.get_rendered_pic_data(client, uid, previous)
|
||||
images = await self.get_rendered_pic(abyss_data, uid, floor, total)
|
||||
images = await self.get_rendered_pic(abyss_data, uid)
|
||||
except TooManyRequestPublicCookies:
|
||||
reply_message = await message.reply_text("查询次数太多,请您稍后重试")
|
||||
if filters.ChatType.GROUPS.filter(message):
|
||||
@ -178,18 +157,12 @@ class ChallengePlugin(Plugin):
|
||||
await reply_message_func("UID 输入错误,请重新输入")
|
||||
return
|
||||
raise e
|
||||
if images is None:
|
||||
await reply_message_func(f"还没有第 {floor} 层的挑战数据")
|
||||
return
|
||||
|
||||
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
|
||||
|
||||
for group in ArkoWrapper(images).group(10): # 每 10 张图片分一个组
|
||||
await RenderGroupResult(results=group).reply_media_group(message, write_timeout=60)
|
||||
await images.reply_photo(message)
|
||||
|
||||
if reply_text is not None:
|
||||
await reply_text.delete()
|
||||
|
||||
self.log_user(update, logger.info, "[bold]防卫战挑战数据[/bold]: 成功发送图片", extra={"markup": True})
|
||||
|
||||
def get_floor_data(self, abyss_data: "ZZZChallenge", floor: int):
|
||||
@ -234,26 +207,16 @@ class ChallengePlugin(Plugin):
|
||||
return f"{int(hours)}时{int(minutes)}分{int(sec)}秒"
|
||||
|
||||
async def get_rendered_pic( # skipcq: PY-R1000 #
|
||||
self, abyss_data: "ZZZChallenge", uid: int, floor: int, total: bool
|
||||
) -> Union[
|
||||
Tuple[
|
||||
Union[BaseException, Any],
|
||||
Union[BaseException, Any],
|
||||
Union[BaseException, Any],
|
||||
Union[BaseException, Any],
|
||||
Union[BaseException, Any],
|
||||
],
|
||||
List[RenderResult],
|
||||
None,
|
||||
]:
|
||||
self,
|
||||
abyss_data: "ZZZChallenge",
|
||||
uid: int,
|
||||
) -> RenderResult:
|
||||
"""
|
||||
获取渲染后的图片
|
||||
|
||||
Args:
|
||||
abyss_data (ZZZChallenge): 防卫战数据
|
||||
uid (int): 需要查询的 uid
|
||||
floor (int): 层数
|
||||
total (bool): 是否为总览
|
||||
|
||||
Returns:
|
||||
bytes格式的图片
|
||||
@ -291,57 +254,22 @@ class ChallengePlugin(Plugin):
|
||||
},
|
||||
}
|
||||
|
||||
overview = await self.template_service.render(
|
||||
"zzz/abyss/overview.html", render_data, viewport={"width": 750, "height": 250}
|
||||
floors_data = []
|
||||
floors = abyss_data.floors[::-1]
|
||||
for i in range(len(floors)):
|
||||
try:
|
||||
floors_data.append(self.get_floor_data(abyss_data, i + 1))
|
||||
except AbyssFastPassed:
|
||||
pass
|
||||
render_data["floors"] = floors_data
|
||||
|
||||
return await self.template_service.render(
|
||||
"zzz/abyss/overview.html",
|
||||
render_data,
|
||||
viewport={"width": 2745, "height": 4000},
|
||||
query_selector=".container",
|
||||
)
|
||||
|
||||
if total:
|
||||
|
||||
def floor_task(floor_index: int):
|
||||
_abyss_data = self.get_floor_data(abyss_data, floor_index)
|
||||
return (
|
||||
floor_index,
|
||||
self.template_service.render(
|
||||
"zzz/abyss/floor.html",
|
||||
{
|
||||
**render_data,
|
||||
**_abyss_data,
|
||||
},
|
||||
viewport={"width": 690, "height": 500},
|
||||
full_page=True,
|
||||
ttl=15 * 24 * 60 * 60,
|
||||
),
|
||||
)
|
||||
|
||||
render_inputs = []
|
||||
floors = abyss_data.floors[::-1]
|
||||
for i, f in enumerate(floors):
|
||||
try:
|
||||
render_inputs.append(floor_task(i + 1))
|
||||
except AbyssFastPassed:
|
||||
pass
|
||||
|
||||
render_group_inputs = list(map(lambda x: x[1], sorted(render_inputs, key=lambda x: x[0])))
|
||||
|
||||
render_group_outputs = await asyncio.gather(*render_group_inputs)
|
||||
render_group_outputs.insert(0, overview)
|
||||
return render_group_outputs
|
||||
|
||||
if floor < 1:
|
||||
return [overview]
|
||||
try:
|
||||
floor_data = abyss_data.floors[-floor]
|
||||
except IndexError:
|
||||
return None
|
||||
if not floor_data:
|
||||
return None
|
||||
render_data.update(self.get_floor_data(abyss_data, floor))
|
||||
return [
|
||||
await self.template_service.render(
|
||||
"zzz/abyss/floor.html", render_data, viewport={"width": 690, "height": 500}
|
||||
)
|
||||
]
|
||||
|
||||
@staticmethod
|
||||
async def save_abyss_data(
|
||||
history_data_abyss: "HistoryDataAbyssServices", uid: int, abyss_data: "ZZZChallenge"
|
||||
@ -444,39 +372,6 @@ class ChallengePlugin(Plugin):
|
||||
send_buttons.append(last_button)
|
||||
return send_buttons
|
||||
|
||||
@staticmethod
|
||||
async def gen_floor_button(
|
||||
data_id: int,
|
||||
abyss_data: "HistoryDataAbyss",
|
||||
user_id: int,
|
||||
uid: int,
|
||||
) -> List[List[InlineKeyboardButton]]:
|
||||
max_floors = len(abyss_data.abyss_data.floors)
|
||||
buttons = [
|
||||
InlineKeyboardButton(
|
||||
f"第 {i + 1} 层",
|
||||
callback_data=f"get_abyss_history|{user_id}|{uid}|{data_id}|{i + 1}",
|
||||
)
|
||||
for i in range(max_floors)
|
||||
]
|
||||
send_buttons = [buttons[i : i + 4] for i in range(0, len(buttons), 4)]
|
||||
all_buttons = [
|
||||
InlineKeyboardButton(
|
||||
"<< 返回",
|
||||
callback_data=f"get_abyss_history|{user_id}|{uid}|p_1",
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
"总览",
|
||||
callback_data=f"get_abyss_history|{user_id}|{uid}|{data_id}|total",
|
||||
),
|
||||
InlineKeyboardButton(
|
||||
"所有",
|
||||
callback_data=f"get_abyss_history|{user_id}|{uid}|{data_id}|all",
|
||||
),
|
||||
]
|
||||
send_buttons.append(all_buttons)
|
||||
return send_buttons
|
||||
|
||||
@handler.command("challenge_history", block=False)
|
||||
@handler.message(filters.Regex(r"^防卫战历史数据"), block=False)
|
||||
async def abyss_history_command_start(self, update: Update, _: CallbackContext) -> None:
|
||||
@ -509,23 +404,7 @@ class ChallengePlugin(Plugin):
|
||||
await callback_query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(buttons))
|
||||
await callback_query.answer(f"已切换到第 {page} 页", show_alert=False)
|
||||
|
||||
async def get_abyss_history_season(self, update: "Update", data_id: int):
|
||||
"""进入选择层数"""
|
||||
callback_query = update.callback_query
|
||||
user = callback_query.from_user
|
||||
|
||||
self.log_user(update, logger.info, "切换防卫战历史数据到层数页 data_id[%s]", data_id)
|
||||
data = await self.history_data_abyss.get_by_id(data_id)
|
||||
if not data:
|
||||
await callback_query.answer("数据不存在,请尝试重新发送命令~", show_alert=True)
|
||||
await callback_query.edit_message_text("数据不存在,请尝试重新发送命令~")
|
||||
return
|
||||
abyss_data = HistoryDataAbyss.from_data(data)
|
||||
buttons = await self.gen_floor_button(data_id, abyss_data, user.id, data.user_id)
|
||||
await callback_query.edit_message_reply_markup(reply_markup=InlineKeyboardMarkup(buttons))
|
||||
await callback_query.answer("已切换到层数页", show_alert=False)
|
||||
|
||||
async def get_abyss_history_floor(self, update: "Update", data_id: int, detail: str):
|
||||
async def get_abyss_history_floor(self, update: "Update", data_id: int):
|
||||
"""渲染层数数据"""
|
||||
callback_query = update.callback_query
|
||||
message = callback_query.message
|
||||
@ -533,14 +412,6 @@ class ChallengePlugin(Plugin):
|
||||
if message.reply_to_message:
|
||||
reply = message.reply_to_message
|
||||
|
||||
floor = 0
|
||||
total = False
|
||||
if detail == "total":
|
||||
floor = 0
|
||||
elif detail == "all":
|
||||
total = True
|
||||
else:
|
||||
floor = int(detail)
|
||||
data = await self.history_data_abyss.get_by_id(data_id)
|
||||
if not data:
|
||||
await callback_query.answer("数据不存在,请尝试重新发送命令", show_alert=True)
|
||||
@ -548,16 +419,13 @@ class ChallengePlugin(Plugin):
|
||||
return
|
||||
abyss_data = HistoryDataAbyss.from_data(data)
|
||||
|
||||
images = await self.get_rendered_pic(abyss_data.abyss_data, data.user_id, floor, total)
|
||||
if images is None:
|
||||
await callback_query.answer(f"还没有第 {floor} 层的挑战数据", show_alert=True)
|
||||
return
|
||||
await callback_query.answer("正在渲染图片中 请稍等 请不要重复点击按钮", show_alert=False)
|
||||
|
||||
images = await self.get_rendered_pic(abyss_data.abyss_data, data.user_id)
|
||||
|
||||
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
|
||||
|
||||
for group in ArkoWrapper(images).group(10): # 每 10 张图片分一个组
|
||||
await RenderGroupResult(results=group).reply_media_group(reply or message, write_timeout=60)
|
||||
await images.reply_photo(reply or message)
|
||||
self.log_user(update, logger.info, "[bold]防卫战挑战数据[/bold]: 成功发送图片", extra={"markup": True})
|
||||
self.add_delete_message_job(message, delay=1)
|
||||
|
||||
@ -568,22 +436,20 @@ class ChallengePlugin(Plugin):
|
||||
|
||||
async def get_abyss_history_callback(
|
||||
callback_query_data: str,
|
||||
) -> Tuple[str, str, int, int]:
|
||||
) -> Tuple[str, int, int]:
|
||||
_data = callback_query_data.split("|")
|
||||
_user_id = int(_data[1])
|
||||
_uid = int(_data[2])
|
||||
_result = _data[3]
|
||||
_detail = _data[4] if len(_data) > 4 else None
|
||||
logger.debug(
|
||||
"callback_query_data函数返回 detail[%s] result[%s] user_id[%s] uid[%s]",
|
||||
_detail,
|
||||
"callback_query_data函数返回 result[%s] user_id[%s] uid[%s]",
|
||||
_result,
|
||||
_user_id,
|
||||
_uid,
|
||||
)
|
||||
return _detail, _result, _user_id, _uid
|
||||
return _result, _user_id, _uid
|
||||
|
||||
detail, result, user_id, uid = await get_abyss_history_callback(callback_query.data)
|
||||
result, user_id, uid = await get_abyss_history_callback(callback_query.data)
|
||||
if user.id != user_id:
|
||||
await callback_query.answer(text="这不是你的按钮!\n" + config.notice.user_mismatch, show_alert=True)
|
||||
return
|
||||
@ -594,10 +460,7 @@ class ChallengePlugin(Plugin):
|
||||
await self.get_abyss_history_page(update, user_id, uid, result)
|
||||
return
|
||||
data_id = int(result)
|
||||
if detail:
|
||||
await self.get_abyss_history_floor(update, data_id, detail)
|
||||
return
|
||||
await self.get_abyss_history_season(update, data_id)
|
||||
await self.get_abyss_history_floor(update, data_id)
|
||||
|
||||
async def abyss_use_by_inline(self, update: "Update", context: "ContextTypes.DEFAULT_TYPE", previous: bool):
|
||||
callback_query = update.callback_query
|
||||
@ -612,8 +475,7 @@ class ChallengePlugin(Plugin):
|
||||
if not client.public:
|
||||
await client.get_record_cards()
|
||||
abyss_data = await self.get_rendered_pic_data(client, uid, previous)
|
||||
images = await self.get_rendered_pic(abyss_data, uid, 0, False)
|
||||
image = images[0]
|
||||
image = await self.get_rendered_pic(abyss_data, uid)
|
||||
except AbyssUnlocked: # 若深渊未解锁
|
||||
notice = "还未解锁防卫战哦~"
|
||||
except TooManyRequestPublicCookies:
|
||||
|
@ -1,59 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>floor</title>
|
||||
<link type="text/css" href="./style.css" rel="stylesheet"/>
|
||||
<link type="text/css" href="../../styles/public.css" rel="stylesheet"/>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.floors, .floor {
|
||||
border-radius: unset;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.floor-num > div:last-child {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="floors">
|
||||
<div class="floors">
|
||||
<div class="floor floor-abyss">
|
||||
<div class="head">
|
||||
<div class="floor-name">
|
||||
<div class="floor-num"></div>
|
||||
<div class="floor_num"></div>
|
||||
<div>
|
||||
<div>UID: {{ uid }}</div>
|
||||
<div>{{ title }}•{{ floor.zone_name }}</div>
|
||||
<div>{{ title }}•{{ data.floor.zone_name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="star star{{ floor.rating }}"></div>
|
||||
<div class="star star{{ data.floor.rating }}"></div>
|
||||
</div>
|
||||
<div class="hr"></div>
|
||||
<div class="chamber">
|
||||
<div class="chamber-info">
|
||||
<div>
|
||||
<span style="color: white;">{{ floor_time }}</span>
|
||||
<span style="color: white;">{{ data.floor_time }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="battles">
|
||||
{% for node in floor_nodes %}
|
||||
{% for node in data.floor_nodes %}
|
||||
<div class="battle">
|
||||
{% for character in node.avatars %}
|
||||
<div class="character">
|
||||
<div class="element" style="background-image: url('../../img/attribute/{{ character.element_type }}.png')"></div>
|
||||
<div class="icon"
|
||||
style="background-image: url('../../background/rarity/half/{{ character.rarity }}.png')">
|
||||
<img src="{{ character_icons[character.id] }}" alt=""/>
|
||||
<img src="{{ data.character_icons[character.id] }}" alt=""/>
|
||||
</div>
|
||||
<div class="caption">Lv.{{ character.level }}</div>
|
||||
</div>
|
||||
@ -63,7 +35,7 @@
|
||||
<div class="character">
|
||||
<div class="icon"
|
||||
style="background-image: url('../../background/rarity/half/{{ character.rarity }}.png')">
|
||||
<img src="{{ buddy_icons[character.id] }}" alt=""/>
|
||||
<img src="{{ data.buddy_icons[character.id] }}" alt=""/>
|
||||
</div>
|
||||
<div class="caption">Lv.{{ character.level }}</div>
|
||||
</div>
|
||||
@ -76,7 +48,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
@ -42,6 +42,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% for data in floors %}
|
||||
{% if loop.index % 4 == 1 %}
|
||||
<div class="floors_row">
|
||||
{% endif %}
|
||||
{% include "zzz/abyss/floor.jinja2" %}
|
||||
{% if loop.index % 4 == 0 or loop.index == loop.length %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -19,20 +19,18 @@ body {
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 750px;
|
||||
position: relative;
|
||||
filter: drop-shadow(2px 2px 5px rgb(0 0 0 /70%));
|
||||
}
|
||||
|
||||
.container2 {
|
||||
width: 850px;
|
||||
position: relative;
|
||||
filter: drop-shadow(2px 2px 5px rgb(0 0 0 /70%));
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 27px;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
color: var(--h-color);
|
||||
}
|
||||
@ -46,8 +44,7 @@ body {
|
||||
/* 概览 */
|
||||
|
||||
.overview {
|
||||
/*height: 250px;*/
|
||||
padding: 20px 40px;
|
||||
padding: 20px 540px;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
@ -61,9 +58,8 @@ body {
|
||||
}
|
||||
|
||||
.summarize {
|
||||
font-size: 20px;
|
||||
font-size: 30px;
|
||||
width: calc(100% - 90px);
|
||||
height: calc(150px - 20px);
|
||||
margin: 20px 0;
|
||||
padding: 10px 0 10px 80px;
|
||||
border-radius: 5px;
|
||||
@ -241,6 +237,7 @@ body {
|
||||
}
|
||||
|
||||
.rank {
|
||||
font-size: 30px;
|
||||
flex: 1;
|
||||
position: relative;
|
||||
display: flex;
|
||||
@ -295,12 +292,12 @@ body {
|
||||
color: var(--white);
|
||||
}
|
||||
|
||||
.floor-name > div:not(.floor-num) {
|
||||
.floor-name > div:not(.floor_num) {
|
||||
margin-left: 20px;
|
||||
text-shadow: 1px 1px 5px rgb(0 0 0/50%);
|
||||
}
|
||||
|
||||
.floor-num {
|
||||
.floor_num {
|
||||
color: black;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
@ -434,3 +431,23 @@ body {
|
||||
.buffs > .buff-item > p > .buff-item-name {
|
||||
color: #f9c87e;
|
||||
}
|
||||
|
||||
.floors_row {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.floors {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.floors, .floor {
|
||||
border-radius: unset;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.floor_num > div:last-child {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user