Files
Dontdrunk-ComfyUI-DD-Nodes/extensions/Prompt_Manager/prompt_api.py
T
2025-06-23 15:23:47 +08:00

302 lines
12 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.
"""
ComfyUI-DD-Nodes 提示词管理器 API
处理提示词数据的服务器端操作,包括保存、读取和同步JSON文件
"""
import os
import json
import asyncio
from datetime import datetime
from aiohttp import web
import logging
# 尝试导入ComfyUI的PromptServer,如果失败则使用备用方案
try:
from server import PromptServer
COMFYUI_AVAILABLE = True
except ImportError:
print("警告: 无法导入ComfyUI的PromptServer,API功能将不可用")
COMFYUI_AVAILABLE = False
PromptServer = None
# 异步文件操作的备用实现
try:
import aiofiles
AIOFILES_AVAILABLE = True
except ImportError:
print("警告: aiofiles不可用,将使用同步文件操作")
AIOFILES_AVAILABLE = False
# 设置日志
logger = logging.getLogger(__name__)
class PromptManagerAPI:
def __init__(self):
self.prompts_file = os.path.join(os.path.dirname(__file__), "prompts.json")
if COMFYUI_AVAILABLE:
self.setup_routes()
else:
logger.warning("ComfyUI不可用,API路由未注册")
def setup_routes(self):
"""设置API路由"""
if not COMFYUI_AVAILABLE or not PromptServer.instance:
logger.error("PromptServer实例不可用")
return
@PromptServer.instance.routes.post("/dd_nodes/save_prompts")
async def save_prompts(request):
try:
data = await request.json()
prompts = data.get('prompts', [])
# 获取标签数据(如果有的话)
tags = data.get('tags', {})
# 准备要保存的数据
prompts_data = {
"version": "2.4.0",
"exportTime": datetime.now().isoformat(),
"description": "ComfyUI-DD-Nodes 提示词管理器数据文件 - 自动同步",
"totalCount": len(prompts),
"prompts": prompts,
"tags": tags # 添加标签数据
}
# 写入JSON文件
success = await self.write_prompts_file(prompts_data)
if success:
logger.info(f"成功保存 {len(prompts)} 个提示词到JSON文件")
return web.json_response({
"success": True,
"message": f"成功保存 {len(prompts)} 个提示词",
"count": len(prompts)
})
else:
return web.json_response({
"success": False,
"error": "写入文件失败"
}, status=500)
except Exception as e:
logger.error(f"保存提示词失败: {e}")
return web.json_response({
"success": False,
"error": str(e)
}, status=500)
@PromptServer.instance.routes.get("/dd_nodes/load_prompts")
async def load_prompts(request):
try:
prompts_data = await self.read_prompts_file()
if prompts_data:
prompts = prompts_data.get('prompts', [])
tags = prompts_data.get('tags', {}) # 获取标签数据
logger.info(f"成功加载 {len(prompts)} 个提示词从JSON文件")
return web.json_response({
"success": True,
"data": prompts_data,
"prompts": prompts,
"tags": tags, # 返回标签数据
"count": len(prompts)
})
else:
return web.json_response({
"success": True,
"data": None,
"prompts": [],
"tags": {}, # 空标签数据
"count": 0
})
except Exception as e:
logger.error(f"加载提示词失败: {e}")
return web.json_response({
"success": False,
"error": str(e)
}, status=500)
@PromptServer.instance.routes.post("/dd_nodes/sync_prompts")
async def sync_prompts(request):
"""同步提示词数据(增量更新)"""
try:
data = await request.json()
prompts = data.get('prompts', [])
tags = data.get('tags', {})
operation = data.get('operation', 'full_sync') # full_sync, add, update, delete
if operation == 'full_sync':
# 全量同步
prompts_data = {
"version": "2.4.0",
"exportTime": datetime.now().isoformat(),
"description": "ComfyUI-DD-Nodes 提示词管理器数据文件 - 自动同步",
"totalCount": len(prompts),
"prompts": prompts,
"tags": tags
}
success = await self.write_prompts_file(prompts_data)
message = f"全量同步 {len(prompts)} 个提示词和 {len(tags)} 个标签"
else:
# 增量更新(预留接口)
current_data = await self.read_prompts_file()
if current_data:
# 这里可以实现增量更新逻辑
success = await self.write_prompts_file(current_data)
message = "增量同步完成"
else:
success = False
message = "增量同步失败:无现有数据"
if success:
logger.info(message)
return web.json_response({
"success": True,
"message": message
})
else:
return web.json_response({
"success": False,
"error": message
}, status=500)
except Exception as e:
logger.error(f"同步提示词失败: {e}")
return web.json_response({
"success": False,
"error": str(e)
}, status=500)
@PromptServer.instance.routes.post("/dd_nodes/save_tags")
async def save_tags(request):
"""保存标签数据到JSON文件"""
try:
data = await request.json()
tags = data.get('tags', {})
# 读取现有的数据
current_data = await self.read_prompts_file()
if current_data:
# 更新标签数据,保留现有提示词
current_data['tags'] = tags
current_data['exportTime'] = datetime.now().isoformat()
else:
# 创建新的数据结构
current_data = {
"version": "2.4.0",
"exportTime": datetime.now().isoformat(),
"description": "ComfyUI-DD-Nodes 提示词管理器数据文件 - 标签更新",
"totalCount": 0,
"prompts": [],
"tags": tags
}
# 写入JSON文件
success = await self.write_prompts_file(current_data)
if success:
logger.info(f"成功保存 {len(tags)} 个标签到JSON文件")
return web.json_response({
"success": True,
"message": f"成功保存 {len(tags)} 个标签",
"count": len(tags)
})
else:
return web.json_response({
"success": False,
"error": "写入文件失败"
}, status=500)
except Exception as e:
logger.error(f"保存标签失败: {e}")
return web.json_response({
"success": False,
"error": str(e)
}, status=500)
@PromptServer.instance.routes.get("/dd_nodes/load_tags")
async def load_tags(request):
"""从JSON文件加载标签数据"""
try:
prompts_data = await self.read_prompts_file()
if prompts_data:
tags = prompts_data.get('tags', {})
logger.info(f"成功加载 {len(tags)} 个标签从JSON文件")
return web.json_response({
"success": True,
"tags": tags,
"count": len(tags)
})
else:
return web.json_response({
"success": True,
"tags": {},
"count": 0
})
except Exception as e:
logger.error(f"加载标签失败: {e}")
return web.json_response({
"success": False,
"error": str(e)
}, status=500)
async def read_prompts_file(self):
"""读取提示词JSON文件"""
try:
if os.path.exists(self.prompts_file):
if AIOFILES_AVAILABLE:
# 使用异步文件操作
async with aiofiles.open(self.prompts_file, 'r', encoding='utf-8') as f:
content = await f.read()
return json.loads(content)
else:
# 使用同步文件操作作为备用
with open(self.prompts_file, 'r', encoding='utf-8') as f:
content = f.read()
return json.loads(content)
return None
except Exception as e:
logger.error(f"读取提示词文件失败: {e}")
return None
async def write_prompts_file(self, data):
"""写入提示词JSON文件"""
try:
# 确保目录存在
os.makedirs(os.path.dirname(self.prompts_file), exist_ok=True)
if AIOFILES_AVAILABLE:
# 使用异步文件操作
async with aiofiles.open(self.prompts_file, 'w', encoding='utf-8') as f:
await f.write(json.dumps(data, indent=2, ensure_ascii=False))
else:
# 使用同步文件操作作为备用
with open(self.prompts_file, 'w', encoding='utf-8') as f:
f.write(json.dumps(data, indent=2, ensure_ascii=False))
logger.info(f"提示词文件已更新: {self.prompts_file}")
return True
except Exception as e:
logger.error(f"写入提示词文件失败: {e}")
return False
def get_prompts_file_path(self):
"""获取提示词文件路径"""
return self.prompts_file
# 安全地创建API实例
prompt_manager_api = None
try:
prompt_manager_api = PromptManagerAPI()
print("PromptManagerAPI 已成功初始化")
except Exception as e:
print(f"初始化PromptManagerAPI失败: {e}")
# 导出供__init__.py使用
__all__ = ['prompt_manager_api', 'PromptManagerAPI']