diff --git a/adapters/db/stats.py b/adapters/db/stats.py index 2319780..f94f37c 100644 --- a/adapters/db/stats.py +++ b/adapters/db/stats.py @@ -2,17 +2,17 @@ async def get_group_stats(chat_id: int) -> dict[str, dict]: """Retrieve statistics for a specific group chat by chat_id.""" - stats = await Stats.get(chat_id=chat_id).values() + stats, _ = await Stats.get_or_create(chat_id=chat_id) return stats async def get_24h_message_stats(chat_id: int) -> dict: """Retrieve 24-hour message statistics for a specific group chat.""" - stats = await Stats.get(chat_id=chat_id) + stats, _ = await Stats.get_or_create(chat_id=chat_id) return stats.messages_24h or {} async def get_user_stats(chat_id: int, user_id: int) -> dict: """Retrieve statistics for a specific user in a group chat.""" - stats = await Stats.get(chat_id=chat_id) + stats, _ = await Stats.get_or_create(chat_id=chat_id) users_data = stats.users if users_data and str(user_id) in users_data: return users_data[str(user_id)] @@ -21,7 +21,7 @@ async def get_user_stats(chat_id: int, user_id: int) -> dict: async def update_group_stats(chat_id: int, user_id: int) -> None: """Update statistics for a specific group chat.""" from datetime import datetime - stats = await Stats.get(chat_id=chat_id) + stats, _ = await Stats.get_or_create(chat_id=chat_id) # JSON 只能使用字符串作为键,所以将 user_id 转换为字符串 uid = str(user_id) stats.total_messages = (stats.total_messages or 0) + 1 @@ -34,13 +34,13 @@ async def update_group_stats(chat_id: int, user_id: int) -> None: async def update_24h_message(chat_id: int, data: dict) -> None: """Update the 24-hour message count for a specific group chat.""" - stats = await Stats.get(chat_id=chat_id) + stats, _ = await Stats.get_or_create(chat_id=chat_id) stats.messages_24h = data await stats.save() async def update_user_stats(chat_id: int, user_id: int, username: str, name: str,attr: None | str) -> None: """Update statistics for a specific user in a group chat.""" - stats = await Stats.get(chat_id=chat_id) + stats, _ = await Stats.get_or_create(chat_id=chat_id) users_data = stats.users or {} uid = str(user_id) user_data = users_data.get(uid, {}) diff --git a/core/actions.py b/core/actions.py index 94b8da0..ef1f131 100644 --- a/core/actions.py +++ b/core/actions.py @@ -6,6 +6,54 @@ import logging +def _parse_action(parts: list[str], default_ending: str = "了") -> tuple[str, str, str | None, str]: + """解析动作参数,支持 -r(替换后缀)和 -p(替换标点)。 + + -r:无参数删除默认后缀,有参数将默认后缀替换为参数。 + -p:无参数删除标点,有参数将默认标点替换为参数。 + + Returns: + (to_remove, replace_with, punctuation, content) + punctuation: None=默认"!",""=无标点,其他=自定义标点 + """ + # 分离 -r 和 -p 部分 + p_args = [] + has_p = "-p" in parts + if has_p: + p_idx = parts.index("-p") + p_args = parts[p_idx + 1:] + parts = parts[:p_idx] + + r_args = [] + if "-r" in parts: + r_idx = parts.index("-r") + content = " ".join(parts[:r_idx]) + r_args = parts[r_idx + 1:] + else: + content = " ".join(parts) + + # 处理 -r + if "-r" not in parts: + to_remove = "" + replace_with = default_ending + elif not r_args: + to_remove = default_ending + replace_with = "" + else: + to_remove = default_ending + replace_with = " ".join(r_args) + + # 处理 -p + if not has_p: + punctuation = None + elif not p_args: + punctuation = "" + else: + punctuation = " ".join(p_args) + + return (to_remove, replace_with, punctuation, content) + + async def handle_actions(message: Message) -> None: if not await config.is_feature_enabled('actions', message.chat.id): logging.debug(f"收到了命中 / 开头的的消息,但是 actions 功能未启用,跳过处理") @@ -22,19 +70,41 @@ async def handle_actions(message: Message) -> None: return from_user = message.from_user.mention_html(message.sender_chat.title) if message.sender_chat else message.from_user.mention_html() - replied_user = message.reply_to_message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else (message.reply_to_message.from_user.mention_html() if message.reply_to_message else None) + replied_user = message.reply_to_message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else (message.reply_to_message.from_user.mention_html() if message.reply_to_message and message.reply_to_message.from_user else None) if " " in rawtext: - if rawtext.split(" ")[0].replace('/','',1).isascii(): + parts = rawtext.split(" ") + if parts[0].replace('/','',1).isascii(): return - await message.reply(f"{from_user} {rawtext.split(" ")[0].replace('/','')}了 {replied_user if message.reply_to_message and replied_user != from_user else '自己' } {''.join(rawtext.split(" ")[1:])}!",disable_web_page_preview=True) + verb = parts[0].replace('/', '') + args = parts[1:] + to_remove, replace_with, punctuation, content = _parse_action(args) + verb = verb.removesuffix(to_remove) + replace_with + punc = "!" if punctuation is None else punctuation + if content: + await message.reply(f"{from_user} {verb} {replied_user if message.reply_to_message and replied_user != from_user else '自己'} {content}{punc}", disable_web_page_preview=True) + else: + await message.reply(f"{from_user} {verb} {replied_user if message.reply_to_message and replied_user != from_user else '自己'}{punc}", disable_web_page_preview=True) else: await message.reply(f"{from_user} {message.text.replace('/','')}了 {replied_user if message.reply_to_message and replied_user != from_user else '自己'}!",disable_web_page_preview=True) async def handle_reverse_actions(message: Message) -> None: from_user = message.from_user.mention_html(message.sender_chat.title) if message.sender_chat else message.from_user.mention_html() - replied_user = message.reply_to_message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else message.reply_to_message.from_user.mention_html() + replied_user = message.reply_to_message.from_user.mention_html(message.reply_to_message.sender_chat.title) if message.reply_to_message and message.reply_to_message.sender_chat else (message.reply_to_message.from_user.mention_html() if message.reply_to_message and message.reply_to_message.from_user else None) if not await config.is_feature_enabled('actions', message.chat.id): logging.debug(f"收到了命中 \\ 开头的的消息,但是 actions 功能未启用,跳过处理") return logging.debug(f"收到了命中 \\ 开头的消息: {message.text}") - await message.reply(f"{from_user} 被 {replied_user if message.reply_to_message and replied_user != from_user else '自己'} {message.text.replace('\\','')}了!",disable_web_page_preview=True) \ No newline at end of file + rawtext = message.text + if " " in rawtext: + parts = rawtext.split(" ") + verb = parts[0].replace('\\', '') + args = parts[1:] + to_remove, replace_with, punctuation, content = _parse_action(args) + verb = verb.removesuffix(to_remove) + replace_with + punc = "!" if punctuation is None else punctuation + if content: + await message.reply(f"{from_user} 被 {replied_user if message.reply_to_message and replied_user != from_user else '自己'} {verb} {content}{punc}", disable_web_page_preview=True) + else: + await message.reply(f"{from_user} 被 {replied_user if message.reply_to_message and replied_user != from_user else '自己'} {verb}{punc}", disable_web_page_preview=True) + else: + await message.reply(f"{from_user} 被 {replied_user if message.reply_to_message and replied_user != from_user else '自己'} {message.text.replace('\\','')}了!",disable_web_page_preview=True) \ No newline at end of file