MibooGram/plugins/genshin/material.py
洛水居室 eed418477f
♻️ Rename HTML templates to use .jinja2 extension
Previously, all templates were named with the .html extension, which caused problems for editors to recognize the Jinja2 syntax used in them. In this commit, all templates have been renamed to use the .jinja2 extension to better reflect their use of Jinja2 and to improve editor recognition.
2023-05-09 19:19:32 +08:00

235 lines
10 KiB
Python
Raw 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.

import re
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.constants import ChatAction
from telegram.ext import CallbackContext, CommandHandler, MessageHandler, filters
from core.dependence.assets import AssetsService
from core.plugin import Plugin, handler
from core.services.template.services import TemplateService
from metadata.genshin import MATERIAL_DATA
from metadata.shortname import roleToName
from modules.apihelper.client.components.remote import Remote
from modules.material.talent import TalentMaterials
from modules.wiki.character import Character
from utils.log import logger
__all__ = ("MaterialPlugin",)
class MaterialPlugin(Plugin):
"""角色培养素材查询"""
KEYBOARD = [[InlineKeyboardButton(text="查看角色培养素材列表并查询", switch_inline_query_current_chat="查看角色培养素材列表并查询")]]
def __init__(
self,
template_service: TemplateService,
assets_service: AssetsService,
):
self.roles_material = {}
self.assets_service = assets_service
self.template_service = template_service
async def initialize(self):
await self._refresh()
async def _refresh(self):
self.roles_material = await Remote.get_remote_material()
async def _parse_material(self, data: dict, character_name: str, talent_level: str) -> dict:
data = data["data"]
if character_name not in data.keys():
return {}
character = self.assets_service.avatar(character_name)
level_up_material = self.assets_service.material(data[character_name]["level_up_materials"])
ascension_material = self.assets_service.material(data[character_name]["ascension_materials"])
local_material = self.assets_service.material(data[character_name]["materials"][0])
enemy_material = self.assets_service.material(data[character_name]["materials"][1])
level_up_materials = [
{
"num": 46,
"rarity": MATERIAL_DATA[str(level_up_material.id)]["rank"],
"icon": (await level_up_material.icon()).as_uri(),
"name": data[character_name]["level_up_materials"],
},
{
"num": 419,
"rarity": 4,
"icon": (await self.assets_service.material(104003).icon()).as_uri(),
"name": "大英雄的经验",
},
{
"num": 1,
"rarity": 2,
"icon": (await ascension_material.icon()).as_uri(),
"name": MATERIAL_DATA[str(ascension_material.id)]["name"],
},
{
"num": 9,
"rarity": 3,
"icon": (await self.assets_service.material(ascension_material.id - 1).icon()).as_uri(),
"name": MATERIAL_DATA[str(ascension_material.id - 1)]["name"],
},
{
"num": 9,
"rarity": 4,
"icon": (await self.assets_service.material(str(ascension_material.id - 2)).icon()).as_uri(),
"name": MATERIAL_DATA[str(ascension_material.id - 2)]["name"],
},
{
"num": 6,
"rarity": 5,
"icon": (await self.assets_service.material(ascension_material.id - 3).icon()).as_uri(),
"name": MATERIAL_DATA[str(ascension_material.id - 3)]["name"],
},
{
"num": 168,
"rarity": MATERIAL_DATA[str(local_material.id)]["rank"],
"icon": (await local_material.icon()).as_uri(),
"name": MATERIAL_DATA[str(local_material.id)]["name"],
},
{
"num": 18,
"rarity": MATERIAL_DATA[str(enemy_material.id)]["rank"],
"icon": (await self.assets_service.material(enemy_material.id).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id)]["name"],
},
{
"num": 30,
"rarity": MATERIAL_DATA[str(enemy_material.id + 1)]["rank"],
"icon": (await self.assets_service.material(enemy_material.id + 1).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id + 1)]["name"],
},
{
"num": 36,
"rarity": MATERIAL_DATA[str(enemy_material.id + 2)]["rank"],
"icon": (await self.assets_service.material(str(enemy_material.id + 2)).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id + 2)]["name"],
},
]
talent_book = self.assets_service.material(f"{data[character_name]['talent'][0]}」的教导")
weekly_talent_material = self.assets_service.material(data[character_name]["talent"][1])
talent_materials = [
{
"num": 9,
"rarity": MATERIAL_DATA[str(talent_book.id)]["rank"],
"icon": (await self.assets_service.material(talent_book.id).icon()).as_uri(),
"name": MATERIAL_DATA[str(talent_book.id)]["name"],
},
{
"num": 63,
"rarity": MATERIAL_DATA[str(talent_book.id + 1)]["rank"],
"icon": (await self.assets_service.material(talent_book.id + 1).icon()).as_uri(),
"name": MATERIAL_DATA[str(talent_book.id + 1)]["name"],
},
{
"num": 114,
"rarity": MATERIAL_DATA[str(talent_book.id + 2)]["rank"],
"icon": (await self.assets_service.material(str(talent_book.id + 2)).icon()).as_uri(),
"name": MATERIAL_DATA[str(talent_book.id + 2)]["name"],
},
{
"num": 18,
"rarity": MATERIAL_DATA[str(enemy_material.id)]["rank"],
"icon": (await self.assets_service.material(enemy_material.id).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id)]["name"],
},
{
"num": 66,
"rarity": MATERIAL_DATA[str(enemy_material.id + 1)]["rank"],
"icon": (await self.assets_service.material(enemy_material.id + 1).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id + 1)]["name"],
},
{
"num": 93,
"rarity": MATERIAL_DATA[str(enemy_material.id + 2)]["rank"],
"icon": (await self.assets_service.material(str(enemy_material.id + 2)).icon()).as_uri(),
"name": MATERIAL_DATA[str(enemy_material.id + 2)]["name"],
},
{
"num": 3,
"rarity": 5,
"icon": (await self.assets_service.material(104319).icon()).as_uri(),
"name": "智识之冕",
},
{
"num": 18,
"rarity": MATERIAL_DATA[str(weekly_talent_material.id)]["rank"],
"icon": (await self.assets_service.material(weekly_talent_material.id).icon()).as_uri(),
"name": MATERIAL_DATA[str(weekly_talent_material.id)]["name"],
},
]
return {
"character": {
"element": character.enka.element.name,
"image": character.enka.images.banner.url,
"name": character_name,
"association": (await Character.get_by_name(character_name)).association.name,
},
"level_up_materials": level_up_materials,
"talent_materials": talent_materials,
"talent_level": talent_level,
"talent_amount": TalentMaterials(list(map(int, talent_level.split("/")))).cal_materials(),
}
async def render(self, character_name: str, talent_amount: str):
if not self.roles_material:
await self._refresh()
data = await self._parse_material(self.roles_material, character_name, talent_amount)
if not data:
return
return await self.template_service.render(
"genshin/material/roles_material.jinja2",
data,
{"width": 960, "height": 1460},
full_page=True,
ttl=7 * 24 * 60 * 60,
)
@staticmethod
def _is_valid(string: str):
"""
判断字符串是否符合`8/9/10`的格式并保证每个数字都在[110]
"""
return bool(
re.match(r"^\d+/\d+/\d+$", string)
and all(1 <= int(num) <= 10 for num in string.split("/"))
and string != "1/1/1"
and string != "10/10/10"
)
@handler(CommandHandler, command="material", block=False)
@handler(MessageHandler, filters=filters.Regex("^角色培养素材查询(.*)"), block=False)
async def command_start(self, update: Update, context: CallbackContext) -> None:
message = update.effective_message
user = update.effective_user
args = self.get_args(context)
if len(args) >= 1:
character_name = args[0]
material_count = "8/8/8"
if len(args) >= 2 and self._is_valid(args[1]):
material_count = args[1]
else:
reply_message = await message.reply_text(
"请回复你要查询的培养素材的角色名", reply_markup=InlineKeyboardMarkup(self.KEYBOARD)
)
if filters.ChatType.GROUPS.filter(reply_message):
self.add_delete_message_job(message)
self.add_delete_message_job(reply_message)
return
character_name = roleToName(character_name)
logger.info("用户 %s[%s] 查询角色培养素材命令请求 || 参数 %s", user.full_name, user.id, character_name)
await message.reply_chat_action(ChatAction.UPLOAD_PHOTO)
result = await self.render(character_name, material_count)
if not result:
reply_message = await message.reply_text(
f"没有找到 {character_name} 的培养素材", reply_markup=InlineKeyboardMarkup(self.KEYBOARD)
)
if filters.ChatType.GROUPS.filter(reply_message):
self.add_delete_message_job(message)
self.add_delete_message_job(reply_message)
return
await result.reply_photo(message)