增强消息统计功能

- 新增用户头像显示
- 添加是否显示已退群用户的配置选项
- 优化移除退群用户后的排行数量显示
- 新增季消息排行选项
- 更新插件版本至0.2
This commit is contained in:
mio 2025-05-13 20:13:20 +08:00 committed by HibiKier
parent 9cda0e5d8f
commit 8c0a600525

View File

@ -1,4 +1,5 @@
from datetime import datetime, timedelta
from io import BytesIO
from nonebot.plugin import PluginMetadata
from nonebot_plugin_alconna import (
@ -14,35 +15,38 @@ from nonebot_plugin_alconna import (
from nonebot_plugin_session import EventSession
import pytz
from zhenxun.configs.utils import Command, PluginExtraData
from zhenxun.configs.config import Config
from zhenxun.configs.utils import Command, PluginExtraData, RegisterConfig
from zhenxun.models.chat_history import ChatHistory
from zhenxun.models.group_member_info import GroupInfoUser
from zhenxun.services.log import logger
from zhenxun.utils.enum import PluginType
from zhenxun.utils.image_utils import ImageTemplate
from zhenxun.utils.image_utils import BuildImage, ImageTemplate
from zhenxun.utils.message import MessageUtils
from zhenxun.utils.platform import PlatformUtils
__plugin_meta__ = PluginMetadata(
name="消息统计",
description="消息统计查询",
usage="""
格式:
消息排行 ?[type [,,,]] ?[--des]
消息排行 ?[type [,,,,]] ?[--des]
快捷:
[,,,]消息排行 ?[数量]
[,,,,]消息排行 ?[数量]
示例:
消息排行 : 所有记录排行
日消息排行 : 今日记录排行
周消息排行 : 今日记录排行
月消息排行 : 今日记录排行
年消息排行 : 今日记录排行
周消息排行 : 本周记录排行
月消息排行 : 本月记录排行
季消息排行 : 本季度记录排行
年消息排行 : 本年记录排行
消息排行 --des : 逆序周记录排行
""".strip(),
extra=PluginExtraData(
author="HibiKier",
version="0.1",
version="0.2",
plugin_type=PluginType.NORMAL,
menu_type="数据统计",
commands=[
@ -50,8 +54,19 @@ __plugin_meta__ = PluginMetadata(
Command(command="日消息统计"),
Command(command="周消息排行"),
Command(command="月消息排行"),
Command(command="季消息排行"),
Command(command="年消息排行"),
],
configs=[
RegisterConfig(
module="chat_history",
key="SHOW_QUIT_MEMBER",
value=True,
help="是否在消息排行中显示已退群用户",
default_value=True,
type=bool,
)
],
).to_dict(),
)
@ -60,7 +75,7 @@ _matcher = on_alconna(
Alconna(
"消息排行",
Option("--des", action=store_true, help_text="逆序"),
Args["type?", ["", "", "", ""]]["count?", int, 10],
Args["type?", ["", "", "", "", ""]]["count?", int, 10],
),
aliases={"消息统计"},
priority=5,
@ -68,7 +83,7 @@ _matcher = on_alconna(
)
_matcher.shortcut(
r"(?P<type>['', '', '', ''])?消息(排行|统计)\s?(?P<cnt>\d+)?",
r"(?P<type>['', '', '', '', ''])?消息(排行|统计)\s?(?P<cnt>\d+)?",
command="消息排行",
arguments=["{type}", "{cnt}"],
prefix=True,
@ -96,20 +111,57 @@ async def _(
date_scope = (time_now - timedelta(days=7), time_now)
elif date in [""]:
date_scope = (time_now - timedelta(days=30), time_now)
column_name = ["名次", "昵称", "发言次数"]
elif date in [""]:
date_scope = (time_now - timedelta(days=90), time_now)
column_name = ["名次", "头像", "昵称", "发言次数"]
show_quit_member = Config.get_config("chat_history", "SHOW_QUIT_MEMBER", True)
fetch_count = count.result
if not show_quit_member:
fetch_count = count.result * 2
if rank_data := await ChatHistory.get_group_msg_rank(
group_id, count.result, "DES" if arparma.find("des") else "DESC", date_scope
group_id, fetch_count, "DES" if arparma.find("des") else "DESC", date_scope
):
idx = 1
data_list = []
for uid, num in rank_data:
if user := await GroupInfoUser.filter(
if len(data_list) >= count.result:
break
user_in_group = await GroupInfoUser.filter(
user_id=uid, group_id=group_id
).first():
user_name = user.user_name
).first()
if not user_in_group and not show_quit_member:
continue
if user_in_group:
user_name = user_in_group.user_name
else:
user_name = uid
data_list.append([idx, user_name, num])
user_name = f"{uid}(已退群)"
avatar_size = 40
try:
avatar_bytes = await PlatformUtils.get_user_avatar(str(uid), "qq")
if avatar_bytes:
avatar_img = BuildImage(
avatar_size, avatar_size, background=BytesIO(avatar_bytes)
)
await avatar_img.circle()
avatar_tuple = (avatar_img, avatar_size, avatar_size)
else:
avatar_img = BuildImage(avatar_size, avatar_size, color="#CCCCCC")
await avatar_img.circle()
avatar_tuple = (avatar_img, avatar_size, avatar_size)
except Exception as e:
logger.warning(f"获取用户头像失败: {e}", "chat_history")
avatar_img = BuildImage(avatar_size, avatar_size, color="#CCCCCC")
await avatar_img.circle()
avatar_tuple = (avatar_img, avatar_size, avatar_size)
data_list.append([idx, avatar_tuple, user_name, num])
idx += 1
if not date_scope:
if date_scope := await ChatHistory.get_group_first_msg_datetime(group_id):
@ -132,13 +184,3 @@ async def _(
)
await MessageUtils.build_message(A).finish(reply_to=True)
await MessageUtils.build_message("群组消息记录为空...").finish()
# # @test.handle()
# # async def _(event: MessageEvent):
# # print(await ChatHistory.get_user_msg(event.user_id, "private"))
# # print(await ChatHistory.get_user_msg_count(event.user_id, "private"))
# # print(await ChatHistory.get_user_msg(event.user_id, "group"))
# # print(await ChatHistory.get_user_msg_count(event.user_id, "group"))
# # print(await ChatHistory.get_group_msg(event.group_id))
# # print(await ChatHistory.get_group_msg_count(event.group_id))