feat: 对自动化处理的toml进行格式化,以及修复通知消息导致的报错

pull/1389/head
Ronifue 2025-11-29 15:53:33 +08:00
parent ed68f969c1
commit f68b9aa109
6 changed files with 97 additions and 20 deletions

View File

@ -39,6 +39,11 @@ class HeartFCMessageReceiver:
message_data: 原始消息字符串
"""
try:
# 通知消息不处理
if message.is_notify:
logger.debug("通知消息,跳过处理")
return
# 1. 消息解析与初始化
userinfo = message.message_info.user_info
chat = message.chat_stream

View File

@ -33,6 +33,11 @@ class MessageStorage:
async def store_message(message: Union[MessageSending, MessageRecv], chat_stream: ChatStream) -> None:
"""存储消息到数据库"""
try:
# 通知消息不存储
if isinstance(message, MessageRecv) and message.is_notify:
logger.debug("通知消息,跳过存储")
return
pattern = r"<MainRule>.*?</MainRule>|<schedule>.*?</schedule>|<UserMessage>.*?</UserMessage>"
# print(message)

View File

@ -0,0 +1,70 @@
"""
TOML 工具函数
提供 TOML 文件的格式化保存功能确保数组等元素以美观的多行格式输出
"""
from typing import Any
import tomlkit
from tomlkit.items import AoT, Table, Array
def _format_toml_value(obj: Any, threshold: int, depth: int = 0) -> Any:
"""递归格式化 TOML 值,将数组转换为多行格式"""
# 处理 AoT (Array of Tables) - 保持原样,递归处理内部
if isinstance(obj, AoT):
for item in obj:
_format_toml_value(item, threshold, depth)
return obj
# 处理字典类型 (dict 或 Table)
if isinstance(obj, (dict, Table)):
for k, v in obj.items():
obj[k] = _format_toml_value(v, threshold, depth)
return obj
# 处理列表类型 (list 或 Array)
if isinstance(obj, (list, Array)):
# 如果包含字典/表,视为 AoT 的列表形式或内联表数组,保持结构递归处理
if obj and isinstance(obj[0], (dict, Table)):
for i, item in enumerate(obj):
# 原地修改或递归处理
if isinstance(obj, list):
obj[i] = _format_toml_value(item, threshold, depth)
else:
_format_toml_value(item, threshold, depth)
return obj
# 决定是否多行:仅在顶层且长度超过阈值时
should_multiline = (depth == 0 and len(obj) > threshold)
# 如果已经是 tomlkit Array原地修改以保留注释
if isinstance(obj, Array):
obj.multiline(should_multiline)
for i, item in enumerate(obj):
obj[i] = _format_toml_value(item, threshold, depth + 1)
return obj
# 普通 list转换为 tomlkit 数组
arr = tomlkit.array()
arr.multiline(should_multiline)
for item in obj:
arr.append(_format_toml_value(item, threshold, depth + 1))
return arr
# 其他基本类型直接返回
return obj
def save_toml_with_format(data: Any, file_path: str, multiline_threshold: int = 1) -> None:
"""格式化 TOML 数据并保存到文件"""
formatted = _format_toml_value(data, multiline_threshold) if multiline_threshold >= 0 else data
with open(file_path, "w", encoding="utf-8") as f:
tomlkit.dump(formatted, f)
def format_toml_string(data: Any, multiline_threshold: int = 1) -> str:
"""格式化 TOML 数据并返回字符串"""
formatted = _format_toml_value(data, multiline_threshold) if multiline_threshold >= 0 else data
return tomlkit.dumps(formatted)

View File

@ -11,6 +11,7 @@ from rich.traceback import install
from typing import List, Optional
from src.common.logger import get_logger
from src.common.toml_utils import format_toml_string
from src.config.config_base import ConfigBase
from src.config.official_configs import (
BotConfig,
@ -252,7 +253,7 @@ def _update_config_generic(config_name: str, template_name: str):
# 如果配置有更新,立即保存到文件
if config_updated:
with open(old_config_path, "w", encoding="utf-8") as f:
f.write(tomlkit.dumps(old_config))
f.write(format_toml_string(old_config))
logger.info(f"已保存更新后的{config_name}配置文件")
else:
logger.info(f"未检测到{config_name}模板默认值变动")
@ -313,9 +314,9 @@ def _update_config_generic(config_name: str, template_name: str):
logger.info(f"开始合并{config_name}新旧配置...")
_update_dict(new_config, old_config)
# 保存更新后的配置(保留注释和格式
# 保存更新后的配置(保留注释和格式,数组多行格式化
with open(new_config_path, "w", encoding="utf-8") as f:
f.write(tomlkit.dumps(new_config))
f.write(format_toml_string(new_config))
logger.info(f"{config_name}配置文件更新完成,建议检查新配置文件中的内容,以免丢失重要信息")

View File

@ -8,6 +8,7 @@ from fastapi import APIRouter, HTTPException, Body
from typing import Any, Annotated
from src.common.logger import get_logger
from src.common.toml_utils import save_toml_with_format
from src.config.config import Config, APIAdapterConfig, CONFIG_DIR, PROJECT_ROOT
from src.config.official_configs import (
BotConfig,
@ -237,10 +238,9 @@ async def update_bot_config(config_data: ConfigBody):
except Exception as e:
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
# 保存配置文件
# 保存配置文件(格式化数组为多行)
config_path = os.path.join(CONFIG_DIR, "bot_config.toml")
with open(config_path, "w", encoding="utf-8") as f:
tomlkit.dump(config_data, f)
save_toml_with_format(config_data, config_path)
logger.info("麦麦主程序配置已更新")
return {"success": True, "message": "配置已保存"}
@ -261,10 +261,9 @@ async def update_model_config(config_data: ConfigBody):
except Exception as e:
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
# 保存配置文件
# 保存配置文件(格式化数组为多行)
config_path = os.path.join(CONFIG_DIR, "model_config.toml")
with open(config_path, "w", encoding="utf-8") as f:
tomlkit.dump(config_data, f)
save_toml_with_format(config_data, config_path)
logger.info("模型配置已更新")
return {"success": True, "message": "配置已保存"}
@ -312,9 +311,8 @@ async def update_bot_config_section(section_name: str, section_data: SectionBody
except Exception as e:
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
# 保存配置tomlkit.dump 会保留注释)
with open(config_path, "w", encoding="utf-8") as f:
tomlkit.dump(config_data, f)
# 保存配置(格式化数组为多行,保留注释)
save_toml_with_format(config_data, config_path)
logger.info(f"配置节 '{section_name}' 已更新(保留注释)")
return {"success": True, "message": f"配置节 '{section_name}' 已保存"}
@ -411,9 +409,8 @@ async def update_model_config_section(section_name: str, section_data: SectionBo
except Exception as e:
raise HTTPException(status_code=400, detail=f"配置数据验证失败: {str(e)}") from e
# 保存配置tomlkit.dump 会保留注释)
with open(config_path, "w", encoding="utf-8") as f:
tomlkit.dump(config_data, f)
# 保存配置(格式化数组为多行,保留注释)
save_toml_with_format(config_data, config_path)
logger.info(f"配置节 '{section_name}' 已更新(保留注释)")
return {"success": True, "message": f"配置节 '{section_name}' 已保存"}

View File

@ -4,6 +4,7 @@ from typing import Optional, List, Dict, Any
from pathlib import Path
import json
from src.common.logger import get_logger
from src.common.toml_utils import save_toml_with_format
from src.config.config import MMC_VERSION
from .git_mirror_service import get_git_mirror_service, set_update_progress_callback
from .token_manager import get_token_manager
@ -1416,8 +1417,7 @@ async def update_plugin_config(
# 更新值
for key, value in request.config.items():
existing_doc[key] = value
with open(config_path, "w", encoding="utf-8") as f:
tomlkit.dump(existing_doc, f)
save_toml_with_format(existing_doc, str(config_path))
logger.info(f"已更新插件配置: {plugin_id}")
@ -1544,9 +1544,8 @@ async def toggle_plugin(plugin_id: str, authorization: Optional[str] = Header(No
new_enabled = not current_enabled
config["plugin"]["enabled"] = new_enabled
# 写入配置(保留注释)
with open(config_path, "w", encoding="utf-8") as f:
tomlkit.dump(config, f)
# 写入配置(保留注释,格式化数组)
save_toml_with_format(config, str(config_path))
status = "启用" if new_enabled else "禁用"
logger.info(f"{status}插件: {plugin_id}")