Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Update /play_card placeholder image #484

Merged
merged 14 commits into from
Mar 17, 2023
50 changes: 39 additions & 11 deletions plugins/genshin/player_cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from telegram.helpers import create_deep_linked_url

from core.config import config
from core.dependence.assets import DEFAULT_EnkaAssets
from core.dependence.assets import DEFAULT_EnkaAssets, AssetsService
from core.dependence.redisdb import RedisDB
from core.handler.callbackqueryhandler import CallbackQueryHandler
from core.plugin import Plugin, handler
Expand All @@ -47,13 +47,19 @@


class PlayerCards(Plugin):
def __init__(self, player_service: PlayersService, template_service: TemplateService, redis: RedisDB):
def __init__(
self,
player_service: PlayersService,
template_service: TemplateService,
assets_service: AssetsService,
redis: RedisDB,
):
self.player_service = player_service
self.client = EnkaNetworkAPI(lang="chs", user_agent=config.enka_network_api_agent, cache=False)
self.cache = RedisCache(redis.client, key="plugin:player_cards:enka_network")
self.player_cards_file = PlayerCardsFile()
self.assets_service = assets_service
self.template_service = template_service
self.temp_photo: Optional[str] = None

async def _fetch_user(self, uid) -> Union[EnkaNetworkResponse, str]:
try:
Expand Down Expand Up @@ -127,15 +133,13 @@ async def player_cards(self, update: Update, context: CallbackContext) -> None:
else:
logger.info("用户 %s[%s] 角色卡片查询命令请求", user.full_name, user.id)
buttons = self.gen_button(data, user.id, player_info.player_id)
if isinstance(self.temp_photo, str):
photo = self.temp_photo
else:
photo = open("resources/img/kitsune.png", "rb")
reply_message = await message.reply_photo(
photo=photo, caption="请选择你要查询的角色,部分角色数据存在缓存,更新可能不及时", reply_markup=InlineKeyboardMarkup(buttons)
render_data = await self.parse_holder_data(data)
holder = await self.template_service.render(
"genshin/player_card/holder.html", render_data, viewport={"width": 750, "height": 580}
)
await holder.reply_photo(
message, caption="请选择你要查询的角色,部分角色数据存在缓存,更新可能不及时", reply_markup=InlineKeyboardMarkup(buttons)
)
if reply_message.photo:
self.temp_photo = reply_message.photo[-1].file_id
return
for characters in data.characters:
if characters.name == character_name:
Expand Down Expand Up @@ -249,6 +253,30 @@ def gen_button(
send_buttons.append(last_button)
return send_buttons

async def parse_holder_data(self, data: EnkaNetworkResponse) -> dict:
"""
生成渲染所需数据
"""
characters_data = []
for idx, character in enumerate(data.characters):
characters_data.append(
{
"level": character.level,
"element": character.element.name,
"constellation": character.constellations_unlocked,
"rarity": character.rarity,
"icon": (await self.assets_service.avatar(character.id).icon()).as_uri(),
}
)
if idx > 6:
break
return {
"uid": data.uid,
"level": data.player.level,
"signature": data.player.signature,
"characters": characters_data,
}


class Artifact(BaseModel):
"""在 enka Equipments model 基础上扩展了圣遗物评分数据"""
Expand Down
39 changes: 39 additions & 0 deletions resources/genshin/player_card/holder.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="zh-ch">
<head>
<meta charset="UTF-8">
<title>holder</title>
<link type="text/css" href="./style.css" rel="stylesheet"/>
<link type="text/css" href="../../styles/public.css" rel="stylesheet"/>
</head>
<body>
<div class="overview">
<div class="title">角色展柜</div>
<div class="summarize">
<div>
<div>UID: {{ uid }}</div>
<div>冒险等阶: {{ level }} 级</div>
</div>
<div>
<div>签名: {{ signature }}</div>
</div>
</div>
<div class="characters">
{% for character in characters %}
<div class="character">
{% if character.constellation > 0 %}
{% set bg = ['blue','blue', 'green','green', 'red', 'red'][character.constellation - 1] %}
<div style="background-color: var(--{{ bg }})">{{ character.constellation }} 命</div>
{% endif %}
<div class="element" style="background-image: url('../../img/element/{{ character.element }}.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/{{ character.rarity }}.png')">
<img src="{{ character.icon }}" alt=""/>
</div>
<div class="caption">Lv.{{ character.level }}</div>
</div>
{% endfor %}

</div>
</div>
</body>
</html>
58 changes: 58 additions & 0 deletions resources/genshin/player_card/holder_example.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="zh-ch">
<head>
<meta charset="UTF-8">
<title>holder_example</title>
<link type="text/css" href="./style.css" rel="stylesheet"/>
<link type="text/css" href="../../styles/public.css" rel="stylesheet"/>
</head>
<body>
<div class="overview">
<div class="title">角色展柜</div>
<div class="summarize">
<div>
<div>UID: 123456789</div>
<div>冒险等阶: 55</div>
</div>
<div>
<div>签名: 貴方の運命は、すでに我が手中の糸が絡めとった!填充</div>
</div>
</div>
<div class="characters">
<div class="character">
<div style="background-color: var(--green)">4命</div>
<div class="element" style="background-image: url('../../img/element/Cryo.png')"></div>
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000007/icon.png" alt="荧"/>
</div>
<div class="caption">Lv.90</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000007/icon.png" alt="荧"/>
</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000007/icon.png" alt="荧"/>
</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000007/icon.png" alt="荧"/>
</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000007/icon.png" alt="荧"/>
</div>
</div>
<div class="character">
<div class="icon" style="background-image: url('../../background/rarity/half/5.png')">
<img src="../../assets/avatar/10000007/icon.png" alt="荧"/>
</div>
</div>
</div>
</div>
</body>
</html>
Binary file added resources/genshin/player_card/img/holder_bg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
146 changes: 146 additions & 0 deletions resources/genshin/player_card/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
:root {
--white: rgb(246 248 249);
--bg-color: rgb(233 229 220);
--h-color: rgb(203 189 162);
--red: rgb(255 86 33/ 80%);
--blue: rgb(98 168 233/ 80%);
--green: rgb(67 185 124/ 80%);
}

body {
margin: 0;
padding: 5px;
}

.hr {
width: 100%;
height: 3px;
background-color: rgb(246 248 249 / 50%);
}

.container {
width: 750px;
position: relative;
filter: drop-shadow(2px 2px 5px rgb(0 0 0 /70%));
}

.title {
text-align: center;
font-size: 27px;
font-weight: bold;
color: var(--h-color);
}

.caption {
margin: 10px 0;
color: var(--h-color);
font-size: 20px;
}

/* 概览 */

.overview {
height: 540px;
padding: 20px 30px;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-image: linear-gradient(to top, rgb(0 0 0 / 10%), rgb(0 0 0 / 10%)), url("./img/holder_bg.png");
background-attachment: local;
border-radius: 15px;
overflow: hidden;
}

.summarize {
font-size: 20px;
margin: 10px;
padding: 20px;
border-radius: 5px;
border: 2px solid rgb(118 121 120 / 80%);
outline: 4px solid rgb(70, 80, 100);
background-color: rgb(70 80 100 / 60%);
background-image: url("../abyss/background/banner 01.png"), url("../abyss/background/banner 02.png");
background-repeat: no-repeat, no-repeat;
background-position: right, left;
background-size: auto 100%, auto 100%;
backdrop-filter: blur(5px);
}

.summarize > div {
width: 100%;
height: 50%;
padding: 5px;
color: var(--white);
display: flex;
align-items: center;
}

.summarize > div > div {
flex: 1;
}

.characters {
margin-left: 47px;
margin-top: 15px;
display: flex;
flex-wrap: wrap;
}

.character {
width: 120px;
height: 150px;
margin: 15px 12px;
background-color: rgb(233 229 220);
overflow: hidden;
border-radius: 10px;
position: relative;
}

.characters > .character > .element {
position: absolute;
top: 3px;
left: 3px;
width: 25px;
height: 25px;
background-size: contain;
background-position: center;
background-repeat: no-repeat;
}

.icon {
width: 100%;
height: 120px;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
overflow: hidden;
border-radius: 0 0 20px 0;
}

.character > .caption {
font-size: 16px;
margin: 4px 0 0;
padding: 0;
height: min-content;
text-align: center;
color: black;
}


.character > div:first-child:not(.icon, .element) {
position: absolute;
top: 0;
right: 0;
padding: 3px;
min-width: 27px;
text-align: center;
border-radius: 0 0 0 10px;
filter: drop-shadow(1px 1px 5px rgb(0 0 0/50%));
font-weight: 500;
color: var(--white);
}

.icon > img {
width: inherit;
height: inherit;
}