基本完成,舒适性修补
This commit is contained in:
189
backend/services/script_manager.py
Normal file
189
backend/services/script_manager.py
Normal file
@@ -0,0 +1,189 @@
|
||||
"""
|
||||
脚本管理模块
|
||||
|
||||
管理 Tavern Helper 的脚本,支持三种作用域:
|
||||
- GLOBAL: 全局脚本,对所有聊天可用
|
||||
- CHARACTER: 角色脚本,绑定到当前角色卡
|
||||
- PRESET: 预设脚本,绑定到当前预设
|
||||
|
||||
每个脚本包含:
|
||||
- 脚本名称
|
||||
- 脚本内容(JavaScript 代码)
|
||||
- 作者备注
|
||||
- 变量列表(绑定到脚本的变量)
|
||||
- 按钮配置(配合 getButtonEvent 使用)
|
||||
- 启用状态
|
||||
"""
|
||||
from enum import Enum
|
||||
from typing import List, Optional, Dict, Any
|
||||
from pydantic import BaseModel, Field
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
|
||||
|
||||
class ScriptScope(str, Enum):
|
||||
"""脚本作用域"""
|
||||
GLOBAL = 'global' # 全局脚本
|
||||
CHARACTER = 'character' # 角色脚本
|
||||
PRESET = 'preset' # 预设脚本
|
||||
|
||||
|
||||
class ScriptVariable(BaseModel):
|
||||
"""脚本变量"""
|
||||
name: str = Field(..., description="变量名")
|
||||
value: Any = Field(..., description="变量值")
|
||||
description: Optional[str] = Field(None, description="变量描述")
|
||||
|
||||
|
||||
class ScriptButton(BaseModel):
|
||||
"""脚本按钮配置"""
|
||||
label: str = Field(..., description="按钮显示文本")
|
||||
event: str = Field(..., description="按钮事件名称(配合 getButtonEvent 使用)")
|
||||
enabled: bool = Field(True, description="是否启用")
|
||||
|
||||
|
||||
class ScriptItem(BaseModel):
|
||||
"""脚本项"""
|
||||
id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="脚本唯一标识符")
|
||||
name: str = Field(..., description="脚本名称")
|
||||
content: str = Field(..., description="脚本内容(JavaScript 代码)")
|
||||
authorNote: Optional[str] = Field(None, description="作者备注")
|
||||
|
||||
# 变量列表
|
||||
variables: List[ScriptVariable] = Field(default_factory=list, description="绑定到脚本的变量")
|
||||
|
||||
# 按钮配置
|
||||
buttons: List[ScriptButton] = Field(default_factory=list, description="按钮配置")
|
||||
|
||||
# 作用域
|
||||
scope: ScriptScope = Field(ScriptScope.GLOBAL, description="脚本作用域")
|
||||
characterName: Optional[str] = Field(None, description="绑定的角色卡名称")
|
||||
presetName: Optional[str] = Field(None, description="绑定的预设名称")
|
||||
|
||||
# 启用状态
|
||||
enabled: bool = Field(True, description="是否启用")
|
||||
|
||||
# 元数据
|
||||
createdAt: int = Field(default_factory=lambda: int(datetime.now().timestamp()), description="创建时间戳")
|
||||
updatedAt: int = Field(default_factory=lambda: int(datetime.now().timestamp()), description="更新时间戳")
|
||||
order: int = Field(0, description="执行顺序")
|
||||
|
||||
|
||||
class ScriptManager:
|
||||
"""脚本管理器"""
|
||||
|
||||
def __init__(self):
|
||||
self.scripts: List[ScriptItem] = []
|
||||
|
||||
def add_script(self, script: ScriptItem):
|
||||
"""添加脚本"""
|
||||
self.scripts.append(script)
|
||||
|
||||
def remove_script(self, script_id: str) -> bool:
|
||||
"""删除脚本"""
|
||||
for i, script in enumerate(self.scripts):
|
||||
if script.id == script_id:
|
||||
self.scripts.pop(i)
|
||||
return True
|
||||
return False
|
||||
|
||||
def update_script(self, script_id: str, updates: Dict[str, Any]) -> bool:
|
||||
"""更新脚本"""
|
||||
for script in self.scripts:
|
||||
if script.id == script_id:
|
||||
for key, value in updates.items():
|
||||
if hasattr(script, key):
|
||||
setattr(script, key, value)
|
||||
script.updatedAt = int(datetime.now().timestamp())
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_scripts_by_scope(self, scope: ScriptScope, filter_name: Optional[str] = None) -> List[ScriptItem]:
|
||||
"""按作用域获取脚本"""
|
||||
scripts = [s for s in self.scripts if s.scope == scope]
|
||||
|
||||
if filter_name:
|
||||
scripts = [s for s in scripts if filter_name.lower() in s.name.lower()]
|
||||
|
||||
return sorted(scripts, key=lambda s: s.order)
|
||||
|
||||
def get_enabled_scripts(self, scope: ScriptScope) -> List[ScriptItem]:
|
||||
"""获取启用的脚本"""
|
||||
return [s for s in self.scripts if s.scope == scope and s.enabled]
|
||||
|
||||
def get_script(self, script_id: str) -> Optional[ScriptItem]:
|
||||
"""获取单个脚本"""
|
||||
for script in self.scripts:
|
||||
if script.id == script_id:
|
||||
return script
|
||||
return None
|
||||
|
||||
def toggle_script(self, script_id: str) -> bool:
|
||||
"""切换脚本启用状态"""
|
||||
for script in self.scripts:
|
||||
if script.id == script_id:
|
||||
script.enabled = not script.enabled
|
||||
script.updatedAt = int(datetime.now().timestamp())
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_all_scripts(self) -> List[ScriptItem]:
|
||||
"""获取所有脚本"""
|
||||
return self.scripts
|
||||
|
||||
def export_scripts(self, scope: Optional[ScriptScope] = None) -> List[Dict]:
|
||||
"""导出脚本"""
|
||||
if scope:
|
||||
scripts = [s for s in self.scripts if s.scope == scope]
|
||||
else:
|
||||
scripts = self.scripts
|
||||
|
||||
return [s.dict() for s in scripts]
|
||||
|
||||
def import_scripts(self, scripts_data: List[Dict], scope: ScriptScope) -> int:
|
||||
"""导入脚本"""
|
||||
count = 0
|
||||
for data in scripts_data:
|
||||
try:
|
||||
script = ScriptItem(**data)
|
||||
script.scope = scope
|
||||
self.scripts.append(script)
|
||||
count += 1
|
||||
except Exception as e:
|
||||
print(f"导入脚本失败: {e}")
|
||||
|
||||
return count
|
||||
|
||||
|
||||
# 全局脚本管理器实例
|
||||
script_manager = ScriptManager()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import json
|
||||
|
||||
# 测试脚本管理
|
||||
manager = ScriptManager()
|
||||
|
||||
# 添加测试脚本
|
||||
script1 = ScriptItem(
|
||||
name="【骰子系统】-自动更新",
|
||||
content="async function getLatestVersion() {\n try {\n const response = await fetch('/api/version');\n return await response.json();\n } catch (e) {\n return null;\n }\n}",
|
||||
authorNote="感谢a佬开源\n以九颜二改为基础进行三改\n@kousakayou",
|
||||
scope=ScriptScope.GLOBAL,
|
||||
variables=[
|
||||
ScriptVariable(name="version", value="4.8.4", description="版本号")
|
||||
],
|
||||
buttons=[
|
||||
ScriptButton(label="检查更新", event="checkUpdate", enabled=True)
|
||||
]
|
||||
)
|
||||
|
||||
manager.add_script(script1)
|
||||
|
||||
# 导出测试
|
||||
print("=== 导出脚本 ===")
|
||||
exported = manager.export_scripts()
|
||||
print(json.dumps(exported, indent=2, ensure_ascii=False))
|
||||
|
||||
print("\n✅ 脚本管理测试完成!")
|
||||
Reference in New Issue
Block a user