diff --git a/zhenxun/builtin_plugins/chat_history/chat_message_handle.py b/zhenxun/builtin_plugins/chat_history/chat_message_handle.py index 10cfcf43..d9eae97f 100644 --- a/zhenxun/builtin_plugins/chat_history/chat_message_handle.py +++ b/zhenxun/builtin_plugins/chat_history/chat_message_handle.py @@ -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['日', '周', '月', '年'])?消息(排行|统计)\s?(?P\d+)?", + r"(?P['日', '周', '月', '季', '年'])?消息(排行|统计)\s?(?P\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))