zhenxun_bot/zhenxun/builtin_plugins/info/my_info.py

202 lines
4.9 KiB
Python
Raw Normal View History

2024-09-29 17:00:31 +08:00
from datetime import datetime, timedelta
import random
2024-09-29 17:00:31 +08:00
from nonebot_plugin_uninfo import Uninfo
from tortoise.expressions import RawSQL
from tortoise.functions import Count
2024-09-29 17:00:31 +08:00
from zhenxun.models.chat_history import ChatHistory
2024-09-29 17:00:31 +08:00
from zhenxun.models.level_user import LevelUser
from zhenxun.models.sign_user import SignUser
2024-09-29 17:00:31 +08:00
from zhenxun.models.statistics import Statistics
from zhenxun.models.user_console import UserConsole
from zhenxun.services import renderer_service
from zhenxun.utils.platform import PlatformUtils
2024-09-29 17:00:31 +08:00
RACE = [
"龙族",
"魅魔",
"森林精灵",
"血精灵",
"暗夜精灵",
"狗头人",
"狼人",
"猫人",
"猪头人",
"骷髅",
"僵尸",
"虫族",
"人类",
"天使",
"恶魔",
"甲壳虫",
"猎猫",
"人鱼",
"哥布林",
"地精",
"泰坦",
"矮人",
"山巨人",
"石巨人",
]
SEX = ["", "", "", ""]
OCC = [
"猎人",
"战士",
"魔法师",
"狂战士",
"魔战士",
"盗贼",
"术士",
"牧师",
"骑士",
"刺客",
"游侠",
"召唤师",
"圣骑士",
"魔使",
"龙骑士",
"赏金猎手",
"吟游诗人",
"德鲁伊",
"祭司",
"符文师",
"狂暴术士",
"萨满",
"裁决者",
"角斗士",
]
lik2level = {
400: 8,
270: 7,
200: 6,
140: 5,
90: 4,
50: 3,
25: 2,
10: 1,
0: 0,
}
def get_level(impression: float) -> int:
"""获取好感度等级"""
return next((level for imp, level in lik2level.items() if impression >= imp), 0)
async def get_chat_history(
user_id: str, group_id: str | None
) -> tuple[list[str], list[int]]:
2024-09-29 17:00:31 +08:00
"""获取用户聊天记录
参数:
user_id: 用户id
group_id: 群id
返回:
tuple[list[str], list[int]]: 日期列表, 次数列表
2024-09-29 17:00:31 +08:00
"""
now = datetime.now()
filter_date = now - timedelta(days=7)
2024-09-29 17:00:31 +08:00
date_list = (
await ChatHistory.filter(
user_id=user_id, group_id=group_id, create_time__gte=filter_date
)
.annotate(date=RawSQL("DATE(create_time)"), count=Count("id"))
.group_by("date")
.values("date", "count")
)
chart_date: list[str] = []
count_list: list[int] = []
date2cnt = {str(item["date"]): item["count"] for item in date_list}
current_date = now.date()
2024-09-29 17:00:31 +08:00
for _ in range(7):
date_str = str(current_date)
count_list.append(date2cnt.get(date_str, 0))
chart_date.append(date_str[5:])
current_date -= timedelta(days=1)
2024-09-29 17:00:31 +08:00
chart_date.reverse()
count_list.reverse()
return chart_date, count_list
async def get_user_info(
session: Uninfo, user_id: str, group_id: str | None, nickname: str
2024-09-29 17:00:31 +08:00
) -> bytes:
"""获取用户个人信息
参数:
2024-10-18 18:57:55 +08:00
session: Uninfo
2024-09-29 17:00:31 +08:00
user_id: 用户id
group_id: 群id
nickname: 用户昵称
返回:
bytes: 图片数据
"""
platform = PlatformUtils.get_platform(session) or "qq"
avatar_url = (
PlatformUtils.get_user_avatar_url(user_id, platform, session.self_id) or ""
)
2024-09-29 17:00:31 +08:00
user = await UserConsole.get_user(user_id, platform)
permission_level = await LevelUser.get_user_level(user_id, group_id)
2024-09-29 17:00:31 +08:00
sign_level = 0
if sign_user := await SignUser.get_or_none(user_id=user_id):
sign_level = get_level(float(sign_user.impression))
2024-09-29 17:00:31 +08:00
chat_count = await ChatHistory.filter(user_id=user_id, group_id=group_id).count()
stat_count = await Statistics.filter(user_id=user_id, group_id=group_id).count()
selected_indices = [""] * 9
selected_indices[sign_level] = "select"
2024-09-29 17:00:31 +08:00
uid = f"{user.uid}".rjust(8, "0")
uid_formatted = f"{uid[:4]} {uid[4:]}"
2024-09-29 17:00:31 +08:00
now = datetime.now()
weather_icon_name = "moon" if now.hour < 6 or now.hour > 19 else "sun"
chart_labels, chart_data = await get_chat_history(user_id, group_id)
profile_data = {
"page": {
"date": str(now.date()),
"weather_icon_name": weather_icon_name,
2024-09-29 17:00:31 +08:00
},
"info": {
"avatar_url": avatar_url,
"nickname": nickname,
"title": "勇 者",
"race": random.choice(RACE),
"sex": random.choice(SEX),
"occupation": random.choice(OCC),
"uid": uid_formatted,
"description": (
"这是一个传奇的故事,人类的赞歌是勇气的赞歌,人类的伟大是勇气的伟大"
),
},
"stats": {
"gold": user.gold,
"prop_count": len(user.props),
"call_count": stat_count,
"chat_count": chat_count,
},
"favorability": {
"level": sign_level,
"selected_indices": selected_indices,
},
"permission_level": permission_level,
"chart": {
"labels": chart_labels,
"data": chart_data,
},
}
return await renderer_service.render("pages/builtin/my_info", data=profile_data)