mirror of https://github.com/Mai-with-u/MaiBot.git
转换消息
parent
9379834171
commit
7a68ab0319
|
|
@ -2,13 +2,14 @@ import time # 导入 time 模块以获取当前时间
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from typing import List, Dict, Any, Tuple, Optional, Callable
|
from typing import List, Dict, Any, Tuple, Optional, Callable, Union
|
||||||
from rich.traceback import install
|
from rich.traceback import install
|
||||||
|
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.common.message_repository import find_messages, count_messages
|
from src.common.message_repository import find_messages, count_messages
|
||||||
from src.common.data_models.database_data_model import DatabaseMessages
|
from src.common.data_models.database_data_model import DatabaseMessages
|
||||||
|
from src.common.data_models.message_data_model import MessageAndActionModel
|
||||||
from src.common.database.database_model import ActionRecords
|
from src.common.database.database_model import ActionRecords
|
||||||
from src.common.database.database_model import Images
|
from src.common.database.database_model import Images
|
||||||
from src.person_info.person_info import Person, get_person_id
|
from src.person_info.person_info import Person, get_person_id
|
||||||
|
|
@ -394,7 +395,7 @@ def num_new_messages_since_with_users(
|
||||||
|
|
||||||
|
|
||||||
def _build_readable_messages_internal(
|
def _build_readable_messages_internal(
|
||||||
messages: List[Dict[str, Any]],
|
messages: List[MessageAndActionModel],
|
||||||
replace_bot_name: bool = True,
|
replace_bot_name: bool = True,
|
||||||
merge_messages: bool = False,
|
merge_messages: bool = False,
|
||||||
timestamp_mode: str = "relative",
|
timestamp_mode: str = "relative",
|
||||||
|
|
@ -402,7 +403,7 @@ def _build_readable_messages_internal(
|
||||||
pic_id_mapping: Optional[Dict[str, str]] = None,
|
pic_id_mapping: Optional[Dict[str, str]] = None,
|
||||||
pic_counter: int = 1,
|
pic_counter: int = 1,
|
||||||
show_pic: bool = True,
|
show_pic: bool = True,
|
||||||
message_id_list: Optional[List[Dict[str, Any]]] = None,
|
message_id_list: Optional[List[DatabaseMessages]] = None,
|
||||||
) -> Tuple[str, List[Tuple[float, str, str]], Dict[str, str], int]:
|
) -> Tuple[str, List[Tuple[float, str, str]], Dict[str, str], int]:
|
||||||
"""
|
"""
|
||||||
内部辅助函数,构建可读消息字符串和原始消息详情列表。
|
内部辅助函数,构建可读消息字符串和原始消息详情列表。
|
||||||
|
|
@ -433,14 +434,15 @@ def _build_readable_messages_internal(
|
||||||
timestamp_to_id = {}
|
timestamp_to_id = {}
|
||||||
if message_id_list:
|
if message_id_list:
|
||||||
for item in message_id_list:
|
for item in message_id_list:
|
||||||
message = item.get("message", {})
|
timestamp = item.time
|
||||||
timestamp = message.get("time")
|
|
||||||
if timestamp is not None:
|
if timestamp is not None:
|
||||||
timestamp_to_id[timestamp] = item.get("id", "")
|
timestamp_to_id[timestamp] = item.message_id
|
||||||
|
|
||||||
def process_pic_ids(content: str) -> str:
|
def process_pic_ids(content: Optional[str]) -> str:
|
||||||
"""处理内容中的图片ID,将其替换为[图片x]格式"""
|
"""处理内容中的图片ID,将其替换为[图片x]格式"""
|
||||||
nonlocal current_pic_counter
|
if content is None:
|
||||||
|
logger.warning("Content is None when processing pic IDs.")
|
||||||
|
raise ValueError("Content is None")
|
||||||
|
|
||||||
# 匹配 [picid:xxxxx] 格式
|
# 匹配 [picid:xxxxx] 格式
|
||||||
pic_pattern = r"\[picid:([^\]]+)\]"
|
pic_pattern = r"\[picid:([^\]]+)\]"
|
||||||
|
|
@ -460,38 +462,23 @@ def _build_readable_messages_internal(
|
||||||
# 1 & 2: 获取发送者信息并提取消息组件
|
# 1 & 2: 获取发送者信息并提取消息组件
|
||||||
for msg in messages:
|
for msg in messages:
|
||||||
# 检查是否是动作记录
|
# 检查是否是动作记录
|
||||||
if msg.get("is_action_record", False):
|
if msg.is_action_record:
|
||||||
is_action = True
|
is_action = True
|
||||||
timestamp: float = msg.get("time") # type: ignore
|
timestamp: float = msg.time
|
||||||
content = msg.get("display_message", "")
|
content = msg.display_message
|
||||||
# 对于动作记录,也处理图片ID
|
# 对于动作记录,也处理图片ID
|
||||||
content = process_pic_ids(content)
|
content = process_pic_ids(content)
|
||||||
message_details_raw.append((timestamp, global_config.bot.nickname, content, is_action))
|
message_details_raw.append((timestamp, global_config.bot.nickname, content, is_action))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 检查并修复缺少的user_info字段
|
platform = msg.user_platform
|
||||||
if "user_info" not in msg:
|
user_id = msg.user_id
|
||||||
# 创建user_info字段
|
|
||||||
msg["user_info"] = {
|
|
||||||
"platform": msg.get("user_platform", ""),
|
|
||||||
"user_id": msg.get("user_id", ""),
|
|
||||||
"user_nickname": msg.get("user_nickname", ""),
|
|
||||||
"user_cardname": msg.get("user_cardname", ""),
|
|
||||||
}
|
|
||||||
|
|
||||||
user_info = msg.get("user_info", {})
|
user_nickname = msg.user_nickname
|
||||||
platform = user_info.get("platform")
|
user_cardname = msg.user_cardname
|
||||||
user_id = user_info.get("user_id")
|
|
||||||
|
|
||||||
user_nickname = user_info.get("user_nickname")
|
timestamp = msg.time
|
||||||
user_cardname = user_info.get("user_cardname")
|
content = msg.display_message or msg.processed_plain_text or ""
|
||||||
|
|
||||||
timestamp: float = msg.get("time") # type: ignore
|
|
||||||
content: str
|
|
||||||
if msg.get("display_message"):
|
|
||||||
content = msg.get("display_message", "")
|
|
||||||
else:
|
|
||||||
content = msg.get("processed_plain_text", "") # 默认空字符串
|
|
||||||
|
|
||||||
if "ᶠ" in content:
|
if "ᶠ" in content:
|
||||||
content = content.replace("ᶠ", "")
|
content = content.replace("ᶠ", "")
|
||||||
|
|
@ -819,7 +806,7 @@ def build_readable_messages(
|
||||||
truncate: bool = False,
|
truncate: bool = False,
|
||||||
show_actions: bool = False,
|
show_actions: bool = False,
|
||||||
show_pic: bool = True,
|
show_pic: bool = True,
|
||||||
message_id_list: Optional[List[Dict[str, Any]]] = None,
|
message_id_list: Optional[List[DatabaseMessages]] = None,
|
||||||
) -> str: # sourcery skip: extract-method
|
) -> str: # sourcery skip: extract-method
|
||||||
"""
|
"""
|
||||||
将消息列表转换为可读的文本格式。
|
将消息列表转换为可读的文本格式。
|
||||||
|
|
@ -835,11 +822,24 @@ def build_readable_messages(
|
||||||
truncate: 是否截断长消息
|
truncate: 是否截断长消息
|
||||||
show_actions: 是否显示动作记录
|
show_actions: 是否显示动作记录
|
||||||
"""
|
"""
|
||||||
|
# WIP HERE and BELOW ----------------------------------------------
|
||||||
# 创建messages的深拷贝,避免修改原始列表
|
# 创建messages的深拷贝,避免修改原始列表
|
||||||
if not messages:
|
if not messages:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
copy_messages = list(messages)
|
copy_messages: List[MessageAndActionModel] = [
|
||||||
|
MessageAndActionModel(
|
||||||
|
msg.time,
|
||||||
|
msg.user_info.user_id,
|
||||||
|
msg.user_info.platform,
|
||||||
|
msg.user_info.user_nickname,
|
||||||
|
msg.user_info.user_cardname,
|
||||||
|
msg.processed_plain_text,
|
||||||
|
msg.display_message,
|
||||||
|
msg.chat_info.platform,
|
||||||
|
)
|
||||||
|
for msg in messages
|
||||||
|
]
|
||||||
|
|
||||||
if show_actions and copy_messages:
|
if show_actions and copy_messages:
|
||||||
# 获取所有消息的时间范围
|
# 获取所有消息的时间范围
|
||||||
|
|
@ -847,7 +847,7 @@ def build_readable_messages(
|
||||||
max_time = max(msg.time or 0 for msg in copy_messages)
|
max_time = max(msg.time or 0 for msg in copy_messages)
|
||||||
|
|
||||||
# 从第一条消息中获取chat_id
|
# 从第一条消息中获取chat_id
|
||||||
chat_id = copy_messages[0].chat_id if copy_messages else None
|
chat_id = messages[0].chat_id if messages else None
|
||||||
|
|
||||||
# 获取这个时间范围内的动作记录,并匹配chat_id
|
# 获取这个时间范围内的动作记录,并匹配chat_id
|
||||||
actions_in_range = (
|
actions_in_range = (
|
||||||
|
|
@ -867,23 +867,24 @@ def build_readable_messages(
|
||||||
)
|
)
|
||||||
|
|
||||||
# 合并两部分动作记录
|
# 合并两部分动作记录
|
||||||
actions = list(actions_in_range) + list(action_after_latest)
|
actions: List[ActionRecords] = list(actions_in_range) + list(action_after_latest)
|
||||||
|
|
||||||
# 将动作记录转换为消息格式
|
# 将动作记录转换为消息格式
|
||||||
for action in actions:
|
for action in actions:
|
||||||
# 只有当build_into_prompt为True时才添加动作记录
|
# 只有当build_into_prompt为True时才添加动作记录
|
||||||
if action.action_build_into_prompt:
|
if action.action_build_into_prompt:
|
||||||
action_msg = {
|
action_msg = MessageAndActionModel(
|
||||||
"time": action.time,
|
time=float(action.time), # type: ignore
|
||||||
"user_id": global_config.bot.qq_account, # 使用机器人的QQ账号
|
user_id=global_config.bot.qq_account, # 使用机器人的QQ账号
|
||||||
"user_nickname": global_config.bot.nickname, # 使用机器人的昵称
|
user_platform=global_config.bot.platform, # 使用机器人的平台
|
||||||
"user_cardname": "", # 机器人没有群名片
|
user_nickname=global_config.bot.nickname, # 使用机器人的用户名
|
||||||
"processed_plain_text": f"{action.action_prompt_display}",
|
user_cardname="", # 机器人没有群名片
|
||||||
"display_message": f"{action.action_prompt_display}",
|
processed_plain_text=f"{action.action_prompt_display}",
|
||||||
"chat_info_platform": action.chat_info_platform,
|
display_message=f"{action.action_prompt_display}",
|
||||||
"is_action_record": True, # 添加标识字段
|
chat_info_platform=str(action.chat_info_platform),
|
||||||
"action_name": action.action_name, # 保存动作名称
|
is_action_record=True, # 添加标识字段
|
||||||
}
|
action_name=str(action.action_name), # 保存动作名称
|
||||||
|
)
|
||||||
copy_messages.append(action_msg)
|
copy_messages.append(action_msg)
|
||||||
|
|
||||||
# 重新按时间排序
|
# 重新按时间排序
|
||||||
|
|
|
||||||
|
|
@ -56,70 +56,99 @@ class DatabaseChatInfo(AbstractClassFlag):
|
||||||
|
|
||||||
@dataclass(init=False)
|
@dataclass(init=False)
|
||||||
class DatabaseMessages(AbstractClassFlag):
|
class DatabaseMessages(AbstractClassFlag):
|
||||||
message_id: str = field(default_factory=str)
|
def __init__(
|
||||||
time: float = field(default_factory=float)
|
self,
|
||||||
chat_id: str = field(default_factory=str)
|
message_id: str = "",
|
||||||
reply_to: Optional[str] = None
|
time: float = 0.0,
|
||||||
interest_value: Optional[float] = None
|
chat_id: str = "",
|
||||||
|
reply_to: Optional[str] = None,
|
||||||
|
interest_value: Optional[float] = None,
|
||||||
|
key_words: Optional[str] = None,
|
||||||
|
key_words_lite: Optional[str] = None,
|
||||||
|
is_mentioned: Optional[bool] = None,
|
||||||
|
processed_plain_text: Optional[str] = None,
|
||||||
|
display_message: Optional[str] = None,
|
||||||
|
priority_mode: Optional[str] = None,
|
||||||
|
priority_info: Optional[str] = None,
|
||||||
|
additional_config: Optional[str] = None,
|
||||||
|
is_emoji: bool = False,
|
||||||
|
is_picid: bool = False,
|
||||||
|
is_command: bool = False,
|
||||||
|
is_notify: bool = False,
|
||||||
|
selected_expressions: Optional[str] = None,
|
||||||
|
user_id: str = "",
|
||||||
|
user_nickname: str = "",
|
||||||
|
user_cardname: Optional[str] = None,
|
||||||
|
user_platform: str = "",
|
||||||
|
chat_info_group_id: Optional[str] = None,
|
||||||
|
chat_info_group_name: Optional[str] = None,
|
||||||
|
chat_info_group_platform: Optional[str] = None,
|
||||||
|
chat_info_user_id: str = "",
|
||||||
|
chat_info_user_nickname: str = "",
|
||||||
|
chat_info_user_cardname: Optional[str] = None,
|
||||||
|
chat_info_user_platform: str = "",
|
||||||
|
chat_info_stream_id: str = "",
|
||||||
|
chat_info_platform: str = "",
|
||||||
|
chat_info_create_time: float = 0.0,
|
||||||
|
chat_info_last_active_time: float = 0.0,
|
||||||
|
**kwargs: Any,
|
||||||
|
):
|
||||||
|
self.message_id = message_id
|
||||||
|
self.time = time
|
||||||
|
self.chat_id = chat_id
|
||||||
|
self.reply_to = reply_to
|
||||||
|
self.interest_value = interest_value
|
||||||
|
|
||||||
key_words: Optional[str] = None
|
self.key_words = key_words
|
||||||
key_words_lite: Optional[str] = None
|
self.key_words_lite = key_words_lite
|
||||||
is_mentioned: Optional[bool] = None
|
self.is_mentioned = is_mentioned
|
||||||
|
|
||||||
processed_plain_text: Optional[str] = None # 处理后的纯文本消息
|
self.processed_plain_text = processed_plain_text
|
||||||
display_message: Optional[str] = None # 显示的消息
|
self.display_message = display_message
|
||||||
|
|
||||||
priority_mode: Optional[str] = None
|
self.priority_mode = priority_mode
|
||||||
priority_info: Optional[str] = None
|
self.priority_info = priority_info
|
||||||
|
|
||||||
additional_config: Optional[str] = None
|
self.additional_config = additional_config
|
||||||
is_emoji: bool = False
|
self.is_emoji = is_emoji
|
||||||
is_picid: bool = False
|
self.is_picid = is_picid
|
||||||
is_command: bool = False
|
self.is_command = is_command
|
||||||
is_notify: bool = False
|
self.is_notify = is_notify
|
||||||
|
|
||||||
selected_expressions: Optional[str] = None
|
self.selected_expressions = selected_expressions
|
||||||
|
|
||||||
def __init__(self, **kwargs: Any):
|
self.group_info: Optional[DatabaseGroupInfo] = None
|
||||||
defined = {f.name: f for f in fields(self.__class__)}
|
|
||||||
for name, f in defined.items():
|
|
||||||
if name in kwargs:
|
|
||||||
setattr(self, name, kwargs.pop(name))
|
|
||||||
elif f.default is not MISSING:
|
|
||||||
setattr(self, name, f.default)
|
|
||||||
else:
|
|
||||||
raise TypeError(f"缺失必需字段: {name}")
|
|
||||||
|
|
||||||
self.group_info = None
|
|
||||||
self.user_info = DatabaseUserInfo(
|
self.user_info = DatabaseUserInfo(
|
||||||
user_id=kwargs.get("user_id"), # type: ignore
|
user_id=user_id,
|
||||||
user_nickname=kwargs.get("user_nickname"), # type: ignore
|
user_nickname=user_nickname,
|
||||||
user_cardname=kwargs.get("user_cardname"), # type: ignore
|
user_cardname=user_cardname,
|
||||||
platform=kwargs.get("user_platform"), # type: ignore
|
platform=user_platform,
|
||||||
)
|
)
|
||||||
if kwargs.get("chat_info_group_id") and kwargs.get("chat_info_group_name"):
|
if chat_info_group_id and chat_info_group_name:
|
||||||
self.group_info = DatabaseGroupInfo(
|
self.group_info = DatabaseGroupInfo(
|
||||||
group_id=kwargs.get("chat_info_group_id"), # type: ignore
|
group_id=chat_info_group_id,
|
||||||
group_name=kwargs.get("chat_info_group_name"), # type: ignore
|
group_name=chat_info_group_name,
|
||||||
group_platform=kwargs.get("chat_info_group_platform"), # type: ignore
|
group_platform=chat_info_group_platform,
|
||||||
)
|
)
|
||||||
|
|
||||||
chat_user_info = DatabaseUserInfo(
|
|
||||||
user_id=kwargs.get("chat_info_user_id"), # type: ignore
|
|
||||||
user_nickname=kwargs.get("chat_info_user_nickname"), # type: ignore
|
|
||||||
user_cardname=kwargs.get("chat_info_user_cardname"), # type: ignore
|
|
||||||
platform=kwargs.get("chat_info_user_platform"), # type: ignore
|
|
||||||
)
|
|
||||||
|
|
||||||
self.chat_info = DatabaseChatInfo(
|
self.chat_info = DatabaseChatInfo(
|
||||||
stream_id=kwargs.get("chat_info_stream_id"), # type: ignore
|
stream_id=chat_info_stream_id,
|
||||||
platform=kwargs.get("chat_info_platform"), # type: ignore
|
platform=chat_info_platform,
|
||||||
create_time=kwargs.get("chat_info_create_time"), # type: ignore
|
create_time=chat_info_create_time,
|
||||||
last_active_time=kwargs.get("chat_info_last_active_time"), # type: ignore
|
last_active_time=chat_info_last_active_time,
|
||||||
user_info=chat_user_info,
|
user_info=DatabaseUserInfo(
|
||||||
|
user_id=chat_info_user_id,
|
||||||
|
user_nickname=chat_info_user_nickname,
|
||||||
|
user_cardname=chat_info_user_cardname,
|
||||||
|
platform=chat_info_user_platform,
|
||||||
|
),
|
||||||
group_info=self.group_info,
|
group_info=self.group_info,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if kwargs:
|
||||||
|
for key, value in kwargs.items():
|
||||||
|
setattr(self, key, value)
|
||||||
|
|
||||||
# def __post_init__(self):
|
# def __post_init__(self):
|
||||||
# assert isinstance(self.message_id, str), "message_id must be a string"
|
# assert isinstance(self.message_id, str), "message_id must be a string"
|
||||||
# assert isinstance(self.time, float), "time must be a float"
|
# assert isinstance(self.time, float), "time must be a float"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
from typing import Optional
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class MessageAndActionModel:
|
||||||
|
time: float = field(default_factory=float)
|
||||||
|
user_id: str = field(default_factory=str)
|
||||||
|
user_platform: str = field(default_factory=str)
|
||||||
|
user_nickname: str = field(default_factory=str)
|
||||||
|
user_cardname: Optional[str] = None
|
||||||
|
processed_plain_text: Optional[str] = None
|
||||||
|
display_message: Optional[str] = None
|
||||||
|
chat_info_platform: str = field(default_factory=str)
|
||||||
|
is_action_record: bool = field(default=False)
|
||||||
|
action_name: Optional[str] = None
|
||||||
Loading…
Reference in New Issue