From efa921384975e4a387a9d5b8cea6ea9b205e2ca9 Mon Sep 17 00:00:00 2001
From: SengokuCola <1026294844@qq.com>
Date: Sun, 30 Mar 2025 23:05:20 +0800
Subject: [PATCH] =?UTF-8?q?fix:=20=E5=B0=86=E7=89=88=E6=9C=AC=E7=A1=AC?=
=?UTF-8?q?=E7=BC=96=E7=A0=81=EF=BC=8C=E6=96=B0=E5=A2=9Econfig=E8=87=AA?=
=?UTF-8?q?=E5=8A=A8=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
考虑到配置文件实际上不会自动更新
---
README.md | 13 ++--
src/common/logger.py | 19 +++++
src/plugins/config/auto_update.py | 93 ++++++++++++++++++++++
src/plugins/config/config.py | 124 +++++++++++++++++++++++++++---
template/bot_config_template.toml | 3 -
5 files changed, 234 insertions(+), 18 deletions(-)
create mode 100644 src/plugins/config/auto_update.py
diff --git a/README.md b/README.md
index 28cd163ee..572c76ad8 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
- LLM 提供对话能力
- MongoDB 提供数据持久化支持
-- 可扩展
+- 可扩展,可支持多种平台和多种功能
**最新版本: v0.6.0** ([查看更新日志](changelog.md))
> [!WARNING]
@@ -38,11 +38,6 @@
> - 由于持续迭代,可能存在一些已知或未知的bug
> - 由于开发中,可能消耗较多token
-
-## ✍️如何给本项目报告BUG/提交建议/做贡献
-
-MaiCore是一个开源项目,我们非常欢迎你的参与。你的贡献,无论是提交bug报告、功能需求还是代码pr,都对项目非常宝贵。我们非常感谢你的支持!🎉 但无序的讨论会降低沟通效率,进而影响问题的解决速度,因此在提交任何贡献前,请务必先阅读本项目的[贡献指南](CONTRIBUTE.md)(待补完)
-
### 💬交流群(开发和建议相关讨论)不一定有空回复,会优先写文档和代码
- [五群](https://qm.qq.com/q/JxvHZnxyec) 1022489779
- [一群](https://qm.qq.com/q/VQ3XZrWgMs) 766798517 【已满】
@@ -115,6 +110,12 @@ MaiCore是一个开源项目,我们非常欢迎你的参与。你的贡献,
- 修复已知bug
- 自动生成的回复逻辑,例如自生成的回复方向,回复风格
+## ✍️如何给本项目报告BUG/提交建议/做贡献
+
+MaiCore是一个开源项目,我们非常欢迎你的参与。你的贡献,无论是提交bug报告、功能需求还是代码pr,都对项目非常宝贵。我们非常感谢你的支持!🎉 但无序的讨论会降低沟通效率,进而影响问题的解决速度,因此在提交任何贡献前,请务必先阅读本项目的[贡献指南](CONTRIBUTE.md)(待补完)
+
+
+
## 设计理念(原始时代的火花)
> **千石可乐说:**
diff --git a/src/common/logger.py b/src/common/logger.py
index 29be8c756..9e118622d 100644
--- a/src/common/logger.py
+++ b/src/common/logger.py
@@ -125,6 +125,24 @@ RELATION_STYLE_CONFIG = {
},
}
+# config
+CONFIG_STYLE_CONFIG = {
+ "advanced": {
+ "console_format": (
+ "{time:YYYY-MM-DD HH:mm:ss} | "
+ "{level: <8} | "
+ "{extra[module]: <12} | "
+ "配置 | "
+ "{message}"
+ ),
+ "file_format": ("{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 配置 | {message}"),
+ },
+ "simple": {
+ "console_format": ("{time:MM-DD HH:mm} | 配置 | {message}"),
+ "file_format": ("{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 配置 | {message}"),
+ },
+}
+
SENDER_STYLE_CONFIG = {
"advanced": {
"console_format": (
@@ -287,6 +305,7 @@ SUB_HEARTFLOW_STYLE_CONFIG = (
SUB_HEARTFLOW_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else SUB_HEARTFLOW_STYLE_CONFIG["advanced"]
) # noqa: E501
WILLING_STYLE_CONFIG = WILLING_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else WILLING_STYLE_CONFIG["advanced"]
+CONFIG_STYLE_CONFIG = CONFIG_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else CONFIG_STYLE_CONFIG["advanced"]
def is_registered_module(record: dict) -> bool:
diff --git a/src/plugins/config/auto_update.py b/src/plugins/config/auto_update.py
new file mode 100644
index 000000000..9c4264233
--- /dev/null
+++ b/src/plugins/config/auto_update.py
@@ -0,0 +1,93 @@
+import shutil
+import tomlkit
+from pathlib import Path
+from datetime import datetime
+
+def update_config():
+ print("开始更新配置文件...")
+ # 获取根目录路径
+ root_dir = Path(__file__).parent.parent.parent.parent
+ template_dir = root_dir / "template"
+ config_dir = root_dir / "config"
+ old_config_dir = config_dir / "old"
+
+ # 创建old目录(如果不存在)
+ old_config_dir.mkdir(exist_ok=True)
+
+ # 定义文件路径
+ template_path = template_dir / "bot_config_template.toml"
+ old_config_path = config_dir / "bot_config.toml"
+ new_config_path = config_dir / "bot_config.toml"
+
+ # 读取旧配置文件
+ old_config = {}
+ if old_config_path.exists():
+ print(f"发现旧配置文件: {old_config_path}")
+ with open(old_config_path, "r", encoding="utf-8") as f:
+ old_config = tomlkit.load(f)
+
+ # 生成带时间戳的新文件名
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+ old_backup_path = old_config_dir / f"bot_config_{timestamp}.toml"
+
+ # 移动旧配置文件到old目录
+ shutil.move(old_config_path, old_backup_path)
+ print(f"已备份旧配置文件到: {old_backup_path}")
+
+ # 复制模板文件到配置目录
+ print(f"从模板文件创建新配置: {template_path}")
+ shutil.copy2(template_path, new_config_path)
+
+ # 读取新配置文件
+ with open(new_config_path, "r", encoding="utf-8") as f:
+ new_config = tomlkit.load(f)
+
+ # 检查version是否相同
+ if old_config and "inner" in old_config and "inner" in new_config:
+ old_version = old_config["inner"].get("version")
+ new_version = new_config["inner"].get("version")
+ if old_version and new_version and old_version == new_version:
+ print(f"检测到版本号相同 (v{old_version}),跳过更新")
+ # 如果version相同,恢复旧配置文件并返回
+ shutil.move(old_backup_path, old_config_path)
+ return
+ else:
+ print(f"检测到版本号不同: 旧版本 v{old_version} -> 新版本 v{new_version}")
+
+ # 递归更新配置
+ def update_dict(target, source):
+ for key, value in source.items():
+ # 跳过version字段的更新
+ if key == "version":
+ continue
+ if key in target:
+ if isinstance(value, dict) and isinstance(target[key], (dict, tomlkit.items.Table)):
+ update_dict(target[key], value)
+ else:
+ try:
+ # 对数组类型进行特殊处理
+ if isinstance(value, list):
+ # 如果是空数组,确保它保持为空数组
+ if not value:
+ target[key] = tomlkit.array()
+ else:
+ target[key] = tomlkit.array(value)
+ else:
+ # 其他类型使用item方法创建新值
+ target[key] = tomlkit.item(value)
+ except (TypeError, ValueError):
+ # 如果转换失败,直接赋值
+ target[key] = value
+
+ # 将旧配置的值更新到新配置中
+ print("开始合并新旧配置...")
+ update_dict(new_config, old_config)
+
+ # 保存更新后的配置(保留注释和格式)
+ with open(new_config_path, "w", encoding="utf-8") as f:
+ f.write(tomlkit.dumps(new_config))
+ print("配置文件更新完成")
+
+
+if __name__ == "__main__":
+ update_config()
diff --git a/src/plugins/config/config.py b/src/plugins/config/config.py
index be53c7bea..bc9d51201 100644
--- a/src/plugins/config/config.py
+++ b/src/plugins/config/config.py
@@ -3,11 +3,120 @@ from dataclasses import dataclass, field
from typing import Dict, List, Optional
import tomli
+import tomlkit
+import shutil
+from datetime import datetime
+from pathlib import Path
from packaging import version
from packaging.version import Version, InvalidVersion
from packaging.specifiers import SpecifierSet, InvalidSpecifier
-from src.common.logger import get_module_logger
+from src.common.logger import get_module_logger, CONFIG_STYLE_CONFIG, LogConfig
+
+# 定义日志配置
+config_config = LogConfig(
+ # 使用消息发送专用样式
+ console_format=CONFIG_STYLE_CONFIG["console_format"],
+ file_format=CONFIG_STYLE_CONFIG["file_format"],
+)
+
+# 配置主程序日志格式
+logger = get_module_logger("config", config=config_config)
+
+
+
+#考虑到,实际上配置文件中的mai_version是不会自动更新的,所以采用硬编码
+mai_version_main = "0.6.0"
+mai_version_fix = "mmc-2"
+mai_version = f"{mai_version_main}-{mai_version_fix}"
+
+
+
+def update_config():
+ # 获取根目录路径
+ root_dir = Path(__file__).parent.parent.parent.parent
+ template_dir = root_dir / "template"
+ config_dir = root_dir / "config"
+ old_config_dir = config_dir / "old"
+
+ # 定义文件路径
+ template_path = template_dir / "bot_config_template.toml"
+ old_config_path = config_dir / "bot_config.toml"
+ new_config_path = config_dir / "bot_config.toml"
+
+ # 检查配置文件是否存在
+ if not old_config_path.exists():
+ logger.info("配置文件不存在,从模板创建新配置")
+ shutil.copy2(template_path, old_config_path)
+ logger.info(f"已创建新配置文件,请填写后重新运行: {old_config_path}")
+ # 如果是新创建的配置文件,直接返回
+ quit()
+ return
+
+ # 读取旧配置文件和模板文件
+ with open(old_config_path, "r", encoding="utf-8") as f:
+ old_config = tomlkit.load(f)
+ with open(template_path, "r", encoding="utf-8") as f:
+ new_config = tomlkit.load(f)
+
+ # 检查version是否相同
+ if old_config and "inner" in old_config and "inner" in new_config:
+ old_version = old_config["inner"].get("version")
+ new_version = new_config["inner"].get("version")
+ if old_version and new_version and old_version == new_version:
+ logger.info(f"检测到配置文件版本号相同 (v{old_version}),跳过更新")
+ return
+ else:
+ logger.info(f"检测到版本号不同: 旧版本 v{old_version} -> 新版本 v{new_version}")
+
+ # 创建old目录(如果不存在)
+ old_config_dir.mkdir(exist_ok=True)
+
+ # 生成带时间戳的新文件名
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
+ old_backup_path = old_config_dir / f"bot_config_{timestamp}.toml"
+
+ # 移动旧配置文件到old目录
+ shutil.move(old_config_path, old_backup_path)
+ logger.info(f"已备份旧配置文件到: {old_backup_path}")
+
+ # 复制模板文件到配置目录
+ shutil.copy2(template_path, new_config_path)
+ logger.info(f"已创建新配置文件: {new_config_path}")
+
+ # 递归更新配置
+ def update_dict(target, source):
+ for key, value in source.items():
+ # 跳过version字段的更新
+ if key == "version":
+ continue
+ if key in target:
+ if isinstance(value, dict) and isinstance(target[key], (dict, tomlkit.items.Table)):
+ update_dict(target[key], value)
+ else:
+ try:
+ # 对数组类型进行特殊处理
+ if isinstance(value, list):
+ # 如果是空数组,确保它保持为空数组
+ if not value:
+ target[key] = tomlkit.array()
+ else:
+ target[key] = tomlkit.array(value)
+ else:
+ # 其他类型使用item方法创建新值
+ target[key] = tomlkit.item(value)
+ except (TypeError, ValueError):
+ # 如果转换失败,直接赋值
+ target[key] = value
+
+ # 将旧配置的值更新到新配置中
+ logger.info("开始合并新旧配置...")
+ update_dict(new_config, old_config)
+
+ # 保存更新后的配置(保留注释和格式)
+ with open(new_config_path, "w", encoding="utf-8") as f:
+ f.write(tomlkit.dumps(new_config))
+ logger.info("配置文件更新完成")
logger = get_module_logger("config")
@@ -17,7 +126,7 @@ class BotConfig:
"""机器人配置类"""
INNER_VERSION: Version = None
- MAI_VERSION: Version = None
+ MAI_VERSION: str = mai_version # 硬编码的版本信息
# bot
BOT_QQ: Optional[int] = 114514
@@ -212,11 +321,6 @@ class BotConfig:
"""从TOML配置文件加载配置"""
config = cls()
- def mai_version(parent: dict):
- mai_version_config = parent["mai_version"]
- version = mai_version_config.get("version")
- version_fix = mai_version_config.get("version-fix")
- config.MAI_VERSION = f"{version}-{version_fix}"
def personality(parent: dict):
personality_config = parent["personality"]
@@ -465,13 +569,12 @@ class BotConfig:
# 主版本号:当你做了不兼容的 API 修改,
# 次版本号:当你做了向下兼容的功能性新增,
# 修订号:当你做了向下兼容的问题修正。
- # 先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
+ # 先行版本号及版本编译信息可以加到"主版本号.次版本号.修订号"的后面,作为延伸。
# 如果你做了break的修改,就应该改动主版本号
# 如果做了一个兼容修改,就不应该要求这个选项是必须的!
include_configs = {
"bot": {"func": bot, "support": ">=0.0.0"},
- "mai_version": {"func": mai_version, "support": ">=1.0.0"},
"groups": {"func": groups, "support": ">=0.0.0"},
"personality": {"func": personality, "support": ">=0.0.0"},
"schedule": {"func": schedule, "support": ">=0.0.11", "necessary": False},
@@ -544,6 +647,9 @@ class BotConfig:
# 获取配置文件路径
+logger.info(f"MaiCore当前版本: {mai_version}")
+update_config()
+
bot_config_floder_path = BotConfig.get_config_dir()
logger.info(f"正在品鉴配置文件目录: {bot_config_floder_path}")
diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml
index 34477b9fd..f8d6c9276 100644
--- a/template/bot_config_template.toml
+++ b/template/bot_config_template.toml
@@ -1,9 +1,6 @@
[inner]
version = "1.0.1"
-[mai_version]
-version = "0.6.0"
-version-fix = "snapshot-2"
#以下是给开发人员阅读的,一般用户不需要阅读
#如果你想要修改配置文件,请在修改后将version的值进行变更