Files
sanguo_llmwiki/mcp_server/tools/daily_update.py
T
claude_dev 62b8fef18a fix: 代码审查问题修复
- C1 (Critical): 添加 PyYAML 解析 frontmatter,支持多行值和列表
- M1 (Major): 添加 FTS5 查询验证,防止注入攻击
- M2/M3 (Major): 工具类使用显式 wiki_vault_path 参数
- M4 (Major): 集成 aiofiles 实现真正的异步文件 I/O
- M5 (Major): 改用 logger.exception() 记录完整堆栈

Co-Authored-By: Claude Dev <noreply@anthropic.com>
2026-06-26 12:10:41 +08:00

109 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Tool Layer - daily_update 工具
日常维护(检查源新鲜度、更新 index、重新生成 hot.md)。
参考设计文档:第 2.2 节
"""
import logging
import os
from typing import Dict, Any
from datetime import datetime
from pathlib import Path
import aiofiles
from ..services import QueryService, IndexerService
logger = logging.getLogger(__name__)
class DailyUpdateTool:
"""daily_update 工具实现"""
def __init__(self, query_service: QueryService, indexer_service: IndexerService, wiki_vault_path: str = None):
self.query_service = query_service
self.indexer_service = indexer_service
# 优先使用传入的路径,否则使用环境变量
self.wiki_vault_path = Path(wiki_vault_path or os.environ.get("WIKI_VAULT_PATH", "/Volumes/KnowledgeBase/wiki-vault"))
async def handle(self) -> Dict[str, Any]:
"""
日常维护
Returns:
{
"updated": 5,
"new": 2,
"hot_md_generated": true,
"index_status": {...}
}
"""
# 1. 增量更新索引
index_status = await self.indexer_service.incremental_update()
# 2. 获取最近更新的页面
recent_pages = await self.query_service.db.get_recent_pages(days=7, limit=20)
# 3. 获取新增标签
new_tags = await self.query_service.db.get_new_tags(days=7)
# 4. 查找孤立页面
from ..services import GraphService
graph_service = GraphService(self.query_service.db)
orphans = await graph_service.find_orphans()
# 5. 生成 hot.md
hot_md_generated = await self._generate_hot_md(recent_pages, new_tags, orphans)
return {
"updated": len(recent_pages),
"new": len(new_tags),
"hot_md_generated": hot_md_generated,
"index_status": index_status
}
async def _generate_hot_md(self, recent_pages, new_tags, orphans) -> bool:
"""生成热点文件"""
try:
# 使用配置的 wiki vault 路径
hot_path = self.wiki_vault_path / "hot.md"
# 格式化内容
content = f"""# Wiki Hot - {datetime.now().strftime('%Y-%m-%d')}
## 最近更新(7 天内)
"""
for page in recent_pages[:10]:
content += f"- [[{page.path}|{page.title}]] - {page.updated_at}\n"
content += "\n## 新增标签(7 天内)\n\n"
for tag, updated_at in new_tags[:10]:
content += f"- `{tag}` - {updated_at}\n"
content += "\n## 待链接页面(孤立页面)\n\n"
for orphan in sorted(list(orphans))[:10]:
content += f"- [[{orphan}]]\n"
# 写入文件(使用 aiofiles 实现异步 I/O
async with aiofiles.open(hot_path, 'w', encoding='utf-8') as f:
await f.write(content)
logger.info(f"Generated hot.md: {hot_path}")
return True
except Exception as e:
logger.error(f"Failed to generate hot.md: {e}")
return False
def get_schema(self) -> dict:
"""返回 MCP Tool schema"""
return {
"name": "daily_update",
"description": "日常维护(检查源新鲜度、更新 index、重新生成 hot.md",
"inputSchema": {
"type": "object",
"properties": {}
}
}