✨ 签到ui改版
|
Before Width: | Height: | Size: 728 KiB After Width: | Height: | Size: 2.0 MiB |
279
resources/template/sign/main.css
Normal file
@ -0,0 +1,279 @@
|
||||
@font-face {
|
||||
font-family: cr105Font;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/ChillReunion_105S.otf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: cr95Font;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/ChillReunion_95.otf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: cr65sFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/ChillReunion_65S.otf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: shFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/SourceHanSansSC-Bold.otf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: rxxxtFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/日系小熊可爱体 Regular.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: kcytFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("./res/font/江城圆体 700W.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: yshsFont;
|
||||
/* 导入的字体文件 */
|
||||
src: url("/resources/font/YSHaoShenTi-2.ttf");
|
||||
}
|
||||
|
||||
body {
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.wrapper{
|
||||
height: 926px;
|
||||
width: 465px;
|
||||
background-color: #FBE4E4;
|
||||
position: relative;
|
||||
font-family: 'cr105Font'
|
||||
}
|
||||
|
||||
.avatar {
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
border-radius: 50%;
|
||||
margin-top: 38px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
|
||||
.avatar-img {
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.top-head {
|
||||
width: 100%;
|
||||
height: 179px;
|
||||
color: #D37B8D;
|
||||
}
|
||||
|
||||
.nickname {
|
||||
margin-top: 43px;
|
||||
margin-left: 30px;
|
||||
font-size: 47px;
|
||||
}
|
||||
|
||||
.uid {
|
||||
font-size: 21px;
|
||||
position: absolute;
|
||||
width: 255px;
|
||||
top: 84px;
|
||||
left: 30px;
|
||||
font-family: 'cr95Font'
|
||||
}
|
||||
|
||||
.rl-img {
|
||||
height: 90px;
|
||||
width: 90px;
|
||||
position: absolute;
|
||||
top: 27px;
|
||||
left: 30px;
|
||||
}
|
||||
|
||||
.zx-img {
|
||||
height:238px;
|
||||
width: 120px;
|
||||
left: 306px;
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.text-day {
|
||||
font-size: 25px;
|
||||
margin-left: 130px;
|
||||
margin-top: 46px;
|
||||
font-family: 'shFont';
|
||||
}
|
||||
|
||||
.text-zx {
|
||||
font-family: 'cr65sFont';
|
||||
position: absolute;
|
||||
top: 72px;
|
||||
left: 130px;
|
||||
}
|
||||
|
||||
.sign-content{
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sign-top {
|
||||
background-color: #D47E8F;
|
||||
width:445px;
|
||||
height: 150px;
|
||||
position: absolute;
|
||||
left: 9px;
|
||||
color: #FBE4E4;
|
||||
}
|
||||
|
||||
.sign-bottom {
|
||||
background-color: #953B50;
|
||||
width: 445px;
|
||||
height: 150px;
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 15px
|
||||
}
|
||||
|
||||
.qian {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 16px;
|
||||
height: 132px;
|
||||
}
|
||||
|
||||
.sign-data{
|
||||
width: 100%;
|
||||
height: 207px;
|
||||
font-family: 'kcytFont';
|
||||
position: relative;
|
||||
color: #D47E8F;
|
||||
}
|
||||
|
||||
.today-text {
|
||||
font-size: 50px;
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 130px;
|
||||
}
|
||||
|
||||
.abs-text {
|
||||
position: absolute;
|
||||
font-size: 30px;
|
||||
z-index: 2;
|
||||
width: 465px;
|
||||
}
|
||||
|
||||
.gift {
|
||||
text-align: center;
|
||||
/* float: left; */
|
||||
/* margin-top: 150px; */
|
||||
}
|
||||
|
||||
|
||||
|
||||
.sign-text {
|
||||
font-size: 30px;
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 140px;
|
||||
}
|
||||
|
||||
.sign-num {
|
||||
font-size: 30px;
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
}
|
||||
|
||||
.line {
|
||||
background-color: #D1778A;
|
||||
width: 435px;
|
||||
height: 3px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
.bottom-foot{
|
||||
width: 100%;
|
||||
height: 376px;
|
||||
position: relative;
|
||||
font-family: 'rxxxtFont';
|
||||
color: #D47E8F;
|
||||
}
|
||||
|
||||
.heart-list {
|
||||
position: absolute;
|
||||
top: 76px;
|
||||
left: 15px;
|
||||
width: 435px;
|
||||
}
|
||||
|
||||
.heart-img {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.cur-text {
|
||||
font-size: 32px;
|
||||
left: 10px;
|
||||
top: -21px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.bot-text {
|
||||
font-size: 30px;
|
||||
position: absolute;
|
||||
top: 85px;
|
||||
left: 15px;
|
||||
width: 435px;
|
||||
}
|
||||
|
||||
.progress-border {
|
||||
position: absolute;
|
||||
top: 273px;
|
||||
left: 19px;
|
||||
width: 313px;
|
||||
height: 30px;
|
||||
border: #DF9DA8 1px solid;
|
||||
}
|
||||
.progress-bar {
|
||||
height: 30px;
|
||||
background-color: #D47E8F;
|
||||
}
|
||||
|
||||
.weather-img {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
position: absolute;
|
||||
top: 37px;
|
||||
left: 371px;
|
||||
}
|
||||
|
||||
.mbl-img {
|
||||
width: 132px;
|
||||
height: 164px;
|
||||
position: absolute;
|
||||
top: 145px;
|
||||
left: 333px;
|
||||
}
|
||||
|
||||
.wd{
|
||||
position: absolute;
|
||||
font-size: 35px;
|
||||
top: 60px;
|
||||
left: 377px;
|
||||
}
|
||||
|
||||
.date {
|
||||
position: absolute;
|
||||
font-size: 20px;
|
||||
top: 350px;
|
||||
left: 260px;
|
||||
font-family: 'yshsFont';
|
||||
}
|
||||
78
resources/template/sign/main.html
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
</html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>test</title>
|
||||
<!-- <link rel="stylesheet" href="./res/font-awesome/css/font-awesome.min.css"> -->
|
||||
<link rel="stylesheet" href="main.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrapper">
|
||||
<div class="top-head">
|
||||
<div style="display: flex;">
|
||||
<div class="avatar">
|
||||
<img class="avatar-img" src="{{data.ava}}" alt="">
|
||||
</div>
|
||||
<div style="position: relative;">
|
||||
<p class="nickname">{{data.name}}</p>
|
||||
<p class="uid">UID:{{data.uid}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sign-content">
|
||||
<div class="sign-bottom">
|
||||
</div>
|
||||
<div class="sign-top">
|
||||
<img class="rl-img" class="avatar-img" src="res/img/rl.png" alt="">
|
||||
<img class="zx-img" class="avatar-img" src="res/img/1.png" alt="">
|
||||
<p class="text-day">累计签到{{data.sign_count}}天</p>
|
||||
<p class="text-zx">真寻说: {{data.message}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sign-data">
|
||||
<img class="qian" src="res/img/3.png" alt="">
|
||||
<p class="today-text">今日签到</p>
|
||||
<div class="abs-text" style="top: 42px;">
|
||||
<p class="gift">{{data.impression}}</p>
|
||||
</div>
|
||||
<div class="abs-text" style="top: 83px;">
|
||||
<p class="gift">{{data.gold}}</p></div>
|
||||
<div class="abs-text" style="top: 123px;">
|
||||
<p class="gift">{{data.gift}}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="line"></div>
|
||||
<div class="bottom-foot">
|
||||
<p class="cur-text">当前好感度: {{data.cur_impression}}</p>
|
||||
<div class="heart-list">
|
||||
{% for i in data.heart2 %}
|
||||
<img class="heart-img" src="res/img/h2.png" alt=""/>
|
||||
{% endfor %}
|
||||
{% for i in data.heart1 %}
|
||||
<img class="heart-img" src="res/img/h1.png" alt=""/>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="bot-text">
|
||||
<p style="position: absolute; top: 9px">好感度等级: {{data.level}}</p>
|
||||
<p style="position: absolute; top: 58px">小真寻对你的态度: {{data.attitude}}</p>
|
||||
<p style="position: absolute; top: 111px"">距离升级还差{{data.interpolation}}好感度</p>
|
||||
</div>
|
||||
<div class="progress-border">
|
||||
<div class="progress-bar" style="width: {{ data.process }}%;"></div>
|
||||
</div>
|
||||
<img class="weather-img" src="res/img/weather/0.png" alt="">
|
||||
<p class="wd" >28℃</p>
|
||||
<img class="mbl-img" src="res/img/2.png" alt="">
|
||||
<div class="date">
|
||||
{{data.date}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript" src="main.js">
|
||||
</script>
|
||||
</html>
|
||||
17
resources/template/sign/main.js
Normal file
@ -0,0 +1,17 @@
|
||||
let wdDom = document.querySelector(".wd")
|
||||
|
||||
let wd = Math.floor(Math.random() * 40) + 1
|
||||
|
||||
wdDom.innerHTML = wd + "℃"
|
||||
|
||||
let weatherDom = document.querySelector(".weather-img")
|
||||
|
||||
let r = Math.floor(Math.random() * 12)
|
||||
|
||||
weatherDom.src = "res/img/weather/" + r + ".png"
|
||||
|
||||
let qianDom = document.querySelector(".qian")
|
||||
|
||||
let r1 = Math.floor(Math.random() * 6)
|
||||
|
||||
qianDom.src = "res/img/tag/" + r1 + ".png"
|
||||
BIN
resources/template/sign/res/font/ChillReunion_105S.otf
Normal file
BIN
resources/template/sign/res/font/ChillReunion_65S.otf
Normal file
BIN
resources/template/sign/res/font/ChillReunion_95.otf
Normal file
BIN
resources/template/sign/res/font/方正复古粗宋简体.TTF
Normal file
BIN
resources/template/sign/res/font/日系小熊可爱体 Regular.ttf
Normal file
BIN
resources/template/sign/res/img/1.png
Normal file
|
After Width: | Height: | Size: 238 KiB |
BIN
resources/template/sign/res/img/2.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
resources/template/sign/res/img/3.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
resources/template/sign/res/img/h1.png
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
BIN
resources/template/sign/res/img/h2.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
resources/template/sign/res/img/rl.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
resources/template/sign/res/img/tag/0.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
resources/template/sign/res/img/tag/1.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
resources/template/sign/res/img/tag/2.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
resources/template/sign/res/img/tag/3.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
resources/template/sign/res/img/tag/4.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
resources/template/sign/res/img/tag/5.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
resources/template/sign/res/img/weather/0.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/template/sign/res/img/weather/1.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/template/sign/res/img/weather/10.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/template/sign/res/img/weather/11.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/template/sign/res/img/weather/2.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
resources/template/sign/res/img/weather/3.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
resources/template/sign/res/img/weather/4.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
resources/template/sign/res/img/weather/5.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
resources/template/sign/res/img/weather/6.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
resources/template/sign/res/img/weather/7.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
resources/template/sign/res/img/weather/8.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
resources/template/sign/res/img/weather/9.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
@ -62,8 +62,8 @@ async def _():
|
||||
group_user = []
|
||||
try:
|
||||
group_user = await GroupInfoUser.filter(uid__isnull=False).all()
|
||||
except Exception:
|
||||
logger.warning("获取GroupInfoUser数据uid失败...")
|
||||
except Exception as e:
|
||||
logger.warning("获取GroupInfoUser数据uid失败...", e=e)
|
||||
user2uid = {u.user_id: u.uid for u in group_user}
|
||||
db = Tortoise.get_connection("default")
|
||||
old_sign_list = await db.execute_query_dict(SIGN_SQL)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import nonebot
|
||||
from nonebot.adapters import Bot
|
||||
from nonebot.permission import SUPERUSER
|
||||
from nonebot.plugin import PluginMetadata
|
||||
from nonebot.rule import to_me
|
||||
from nonebot_plugin_alconna import Alconna, Args, Match, on_alconna
|
||||
from nonebot_plugin_session import EventSession
|
||||
|
||||
@ -47,6 +47,7 @@ _matcher = on_alconna(
|
||||
priority=1,
|
||||
block=True,
|
||||
permission=SUPERUSER,
|
||||
rule=to_me(),
|
||||
)
|
||||
|
||||
|
||||
@ -66,22 +67,3 @@ async def _(bot: Bot, session: EventSession, ver_type: Match[str]):
|
||||
if result:
|
||||
await MessageUtils.build_message(result).finish()
|
||||
await MessageUtils.build_message("更新版本失败...").finish()
|
||||
|
||||
|
||||
# driver = nonebot.get_driver()
|
||||
|
||||
|
||||
# @driver.on_startup
|
||||
# async def _():
|
||||
# result = await UpdateManage.check_version()
|
||||
# print("-----------------------")
|
||||
# print("-----------------------")
|
||||
# print(result)
|
||||
# print("-----------------------")
|
||||
# print("-----------------------")
|
||||
# result = await UpdateManage.update(None, "", "dev")
|
||||
# print("-----------------------")
|
||||
# print("-----------------------")
|
||||
# print(result)
|
||||
# print("-----------------------")
|
||||
# print("-----------------------")
|
||||
|
||||
@ -72,6 +72,12 @@ __plugin_meta__ = PluginMetadata(
|
||||
default_value=0.05,
|
||||
type=float,
|
||||
),
|
||||
RegisterConfig(
|
||||
key="IMAGE_STYLE",
|
||||
value="zhenxun",
|
||||
help="签到图片样式, [normal, zhenxun]",
|
||||
default_value="zhenxun",
|
||||
),
|
||||
],
|
||||
limits=[PluginCdBlock()],
|
||||
).dict(),
|
||||
|
||||
@ -7,9 +7,10 @@ from pathlib import Path
|
||||
import nonebot
|
||||
import pytz
|
||||
from nonebot.drivers import Driver
|
||||
from nonebot_plugin_htmlrender import template_to_pic
|
||||
|
||||
from zhenxun.configs.config import NICKNAME, Config
|
||||
from zhenxun.configs.path_config import IMAGE_PATH
|
||||
from zhenxun.configs.path_config import IMAGE_PATH, TEMPLATE_PATH
|
||||
from zhenxun.models.sign_log import SignLog
|
||||
from zhenxun.models.sign_user import SignUser
|
||||
from zhenxun.utils.image_utils import BuildImage
|
||||
@ -25,8 +26,27 @@ from .config import (
|
||||
lik2relation,
|
||||
)
|
||||
|
||||
AVA_URL = "http://q1.qlogo.cn/g?b=qq&nk={}&s=160"
|
||||
|
||||
driver: Driver = nonebot.get_driver()
|
||||
|
||||
base_config = Config.get("sign_in")
|
||||
|
||||
|
||||
MORNING_MESSAGE = [
|
||||
"早上好,希望今天是美好的一天!",
|
||||
"醒了吗,今天也要元气满满哦!",
|
||||
"早上好呀,今天也要开心哦!",
|
||||
"早安,愿你拥有美好的一天!",
|
||||
]
|
||||
|
||||
LG_MESSAGE = [
|
||||
"今天要早点休息哦~",
|
||||
"可不要熬夜到太晚呀",
|
||||
"请尽早休息吧!",
|
||||
"不要熬夜啦!",
|
||||
]
|
||||
|
||||
|
||||
@driver.on_startup
|
||||
async def init_image():
|
||||
@ -73,9 +93,14 @@ async def get_card(
|
||||
if card_file.exists():
|
||||
return card_file
|
||||
is_card_view = True
|
||||
return await _generate_card(
|
||||
user, nickname, add_impression, gold, gift, is_double, is_card_view
|
||||
)
|
||||
if base_config.get("IMAGE_STYLE") == "zhenxun":
|
||||
return await _generate_html_card(
|
||||
user, nickname, add_impression, gold, gift, is_double, is_card_view
|
||||
)
|
||||
else:
|
||||
return await _generate_card(
|
||||
user, nickname, add_impression, gold, gift, is_double, is_card_view
|
||||
)
|
||||
|
||||
|
||||
async def _generate_card(
|
||||
@ -237,8 +262,8 @@ async def _generate_card(
|
||||
_type = "sign"
|
||||
current_date = datetime.now()
|
||||
current_datetime_str = current_date.strftime("%Y-%m-%d %a %H:%M:%S")
|
||||
data = current_date.date()
|
||||
data_img = await BuildImage.build_text_image(
|
||||
date = current_date.date()
|
||||
date_img = await BuildImage.build_text_image(
|
||||
f"时间:{current_datetime_str}", size=20
|
||||
)
|
||||
await bk.paste(nickname_img, (30, 15))
|
||||
@ -249,7 +274,7 @@ async def _generate_card(
|
||||
# await bk.paste(sign_day_img, (398, 158))
|
||||
# await bk.text((_x, 167), "days")
|
||||
await bk.paste(tip_image, (10, 167))
|
||||
await bk.paste(data_img, (220, 370))
|
||||
await bk.paste(date_img, (220, 370))
|
||||
await bk.paste(lik_text1_img, (220, 240))
|
||||
await bk.paste(lik_text2_img, (262, 234))
|
||||
await bk.paste(bar_bk, (225, 275))
|
||||
@ -257,8 +282,8 @@ async def _generate_card(
|
||||
await bk.paste(today_sign_text_img, (550, 180))
|
||||
await bk.paste(today_data, (580, 220))
|
||||
await bk.paste(watermark, (15, 400))
|
||||
await bk.save(SIGN_TODAY_CARD_PATH / f"{user.user_id}_{_type}_{data}.png")
|
||||
return IMAGE_PATH / "sign" / "today_card" / f"{user.user_id}_{_type}_{data}.png"
|
||||
await bk.save(SIGN_TODAY_CARD_PATH / f"{user.user_id}_{_type}_{date}.png")
|
||||
return IMAGE_PATH / "sign" / "today_card" / f"{user.user_id}_{_type}_{date}.png"
|
||||
|
||||
|
||||
async def generate_progress_bar_pic():
|
||||
@ -333,3 +358,98 @@ def clear_sign_data_pic():
|
||||
for file in os.listdir(SIGN_TODAY_CARD_PATH):
|
||||
if str(date) not in file:
|
||||
os.remove(SIGN_TODAY_CARD_PATH / file)
|
||||
|
||||
|
||||
async def _generate_html_card(
|
||||
user: SignUser,
|
||||
nickname: str,
|
||||
impression: float,
|
||||
gold: int | None,
|
||||
gift: str,
|
||||
is_double: bool = False,
|
||||
is_card_view: bool = False,
|
||||
) -> Path:
|
||||
"""生成签到卡片
|
||||
|
||||
参数:
|
||||
user: SignUser
|
||||
nickname: 用户昵称
|
||||
impression: 新增的好感度
|
||||
gold: 金币
|
||||
gift: 礼物
|
||||
is_double: 是否触发双倍.
|
||||
is_card_view: 是否展示好感度卡片.
|
||||
|
||||
返回:
|
||||
Path: 卡片路径
|
||||
"""
|
||||
user_console = await user.user_console
|
||||
if user_console and user_console.uid:
|
||||
uid = f"{user_console.uid}".rjust(12, "0")
|
||||
uid = uid[:4] + " " + uid[4:8] + " " + uid[8:]
|
||||
else:
|
||||
uid = "XXXX XXXX XXXX"
|
||||
level, next_impression, previous_impression = get_level_and_next_impression(
|
||||
impression
|
||||
)
|
||||
interpolation = next_impression - impression
|
||||
if level == "9":
|
||||
level = "8"
|
||||
interpolation = 0
|
||||
message = f"{NICKNAME}希望你天天开心!"
|
||||
hour = datetime.now().hour
|
||||
if hour > 6 and hour < 10:
|
||||
message = random.choice(MORNING_MESSAGE)
|
||||
elif hour >= 0 and hour < 6:
|
||||
message = random.choice(LG_MESSAGE)
|
||||
_impression = impression
|
||||
if is_double:
|
||||
_impression = f"{impression}(×2)"
|
||||
process = 1 - (next_impression - user.impression) / (
|
||||
next_impression - previous_impression
|
||||
)
|
||||
if next_impression == 0:
|
||||
process = 0
|
||||
now = datetime.now()
|
||||
data = {
|
||||
"ava": AVA_URL.format(user.user_id),
|
||||
"name": nickname,
|
||||
"uid": uid,
|
||||
"sign_count": f"{user.sign_count}",
|
||||
"message": message,
|
||||
"cur_impression": f"{user.impression:.2f}",
|
||||
"impression": f"好感度+{_impression}",
|
||||
"gold": f"金币+{gold}",
|
||||
"gift": gift,
|
||||
"level": f"{level} [{lik2relation[level]}]",
|
||||
"attitude": level2attitude[level],
|
||||
"interpolation": f"{interpolation:.2f}",
|
||||
"heart2": [1 for _ in range(int(level))],
|
||||
"heart1": [1 for _ in range(9 - int(level))],
|
||||
"process": process,
|
||||
"date": str(now.replace(microsecond=0)),
|
||||
}
|
||||
if is_card_view:
|
||||
value_list = (
|
||||
await SignUser.annotate()
|
||||
.order_by("-impression")
|
||||
.values_list("user_id", flat=True)
|
||||
)
|
||||
index = value_list.index(user.user_id) + 1 # type: ignore
|
||||
data["impression"] = f"好感度排名第 {index} 位"
|
||||
data["gold"] = f"总金币:{gold}"
|
||||
data["gift"] = ""
|
||||
pic = await template_to_pic(
|
||||
template_path=str((TEMPLATE_PATH / "sign").absolute()),
|
||||
template_name="main.html",
|
||||
templates={"data": data},
|
||||
pages={
|
||||
"viewport": {"width": 465, "height": 926},
|
||||
"base_url": f"file://{TEMPLATE_PATH}",
|
||||
},
|
||||
wait=2,
|
||||
)
|
||||
image = BuildImage.open(pic)
|
||||
date = now.date()
|
||||
await image.save(SIGN_TODAY_CARD_PATH / f"{user.user_id}_sign_{date}.png")
|
||||
return IMAGE_PATH / "sign" / "today_card" / f"{user.user_id}_sign_{date}.png"
|
||||
|
||||
@ -45,7 +45,7 @@ class BuildImage:
|
||||
mode: ModeType = "RGBA",
|
||||
font: str | Path | FreeTypeFont = "HYWenHei-85W.ttf",
|
||||
font_size: int = 20,
|
||||
background: str | BytesIO | Path | None = None,
|
||||
background: str | BytesIO | Path | bytes | None = None,
|
||||
) -> None:
|
||||
self.uid = uuid.uuid1()
|
||||
self.width = width
|
||||
@ -57,7 +57,10 @@ class BuildImage:
|
||||
else font
|
||||
)
|
||||
if background:
|
||||
self.markImg = Image.open(background)
|
||||
if isinstance(background, bytes):
|
||||
self.markImg = Image.open(BytesIO(background))
|
||||
else:
|
||||
self.markImg = Image.open(background)
|
||||
if width and height:
|
||||
self.markImg = self.markImg.resize((width, height), Image.LANCZOS)
|
||||
else:
|
||||
@ -74,7 +77,7 @@ class BuildImage:
|
||||
return self.markImg.size
|
||||
|
||||
@classmethod
|
||||
def open(cls, path: str | Path) -> Self:
|
||||
def open(cls, path: str | Path | bytes) -> Self:
|
||||
"""打开图片
|
||||
|
||||
参数:
|
||||
|
||||