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的值进行变更