Skip to content

Commit 9322218

Browse files
authored
feat: supports to display plugin CHANGELOG.md (#4337)
* feat: optimize plugin update changelog feature, refactor to reuse ReadmeDialog and support independent view entry * fix: distinguish error state from empty state in ReadmeDialog
1 parent 399062f commit 9322218

8 files changed

Lines changed: 1658 additions & 674 deletions

File tree

astrbot/dashboard/routes/plugin.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def __init__(
5555
"/plugin/on": ("POST", self.on_plugin),
5656
"/plugin/reload": ("POST", self.reload_plugins),
5757
"/plugin/readme": ("GET", self.get_plugin_readme),
58+
"/plugin/changelog": ("GET", self.get_plugin_changelog),
5859
"/plugin/source/get": ("GET", self.get_custom_source),
5960
"/plugin/source/save": ("POST", self.save_custom_source),
6061
}
@@ -615,6 +616,55 @@ async def get_plugin_readme(self):
615616
logger.error(f"/api/plugin/readme: {traceback.format_exc()}")
616617
return Response().error(f"读取README文件失败: {e!s}").__dict__
617618

619+
async def get_plugin_changelog(self):
620+
"""获取插件更新日志
621+
622+
读取插件目录下的 CHANGELOG.md 文件内容。
623+
"""
624+
plugin_name = request.args.get("name")
625+
logger.debug(f"正在获取插件 {plugin_name} 的更新日志")
626+
627+
if not plugin_name:
628+
return Response().error("插件名称不能为空").__dict__
629+
630+
# 查找插件
631+
plugin_obj = None
632+
for plugin in self.plugin_manager.context.get_all_stars():
633+
if plugin.name == plugin_name:
634+
plugin_obj = plugin
635+
break
636+
637+
if not plugin_obj:
638+
return Response().error(f"插件 {plugin_name} 不存在").__dict__
639+
640+
if not plugin_obj.root_dir_name:
641+
return Response().error(f"插件 {plugin_name} 目录不存在").__dict__
642+
643+
plugin_dir = os.path.join(
644+
self.plugin_manager.plugin_store_path,
645+
plugin_obj.root_dir_name,
646+
)
647+
648+
# 尝试多种可能的文件名
649+
changelog_names = ["CHANGELOG.md", "changelog.md", "CHANGELOG", "changelog"]
650+
for name in changelog_names:
651+
changelog_path = os.path.join(plugin_dir, name)
652+
if os.path.isfile(changelog_path):
653+
try:
654+
with open(changelog_path, encoding="utf-8") as f:
655+
changelog_content = f.read()
656+
return (
657+
Response()
658+
.ok({"content": changelog_content}, "成功获取更新日志")
659+
.__dict__
660+
)
661+
except Exception as e:
662+
logger.error(f"/api/plugin/changelog: {traceback.format_exc()}")
663+
return Response().error(f"读取更新日志失败: {e!s}").__dict__
664+
665+
# 没有找到 changelog 文件,返回 ok 但 content 为 null
666+
return Response().ok({"content": None}, "该插件没有更新日志文件").__dict__
667+
618668
async def get_custom_source(self):
619669
"""获取自定义插件源"""
620670
sources = await sp.global_get("custom_plugin_sources", [])

0 commit comments

Comments
 (0)