fix: auto-fix code issues (cron)

- 修复重复导入/字段
- 修复异常处理
- 修复PEP8格式问题
- 添加类型注解
- 修复缺失的urllib.parse导入
This commit is contained in:
OpenClaw Bot
2026-02-28 06:03:09 +08:00
parent ff83cab6c7
commit fe3d64a1d2
41 changed files with 4501 additions and 1176 deletions

View File

@@ -11,6 +11,7 @@ import json
import os
import sqlite3
import time
import urllib.parse
import uuid
from dataclasses import dataclass, field
from datetime import datetime
@@ -27,6 +28,7 @@ try:
except ImportError:
WEBDAV_AVAILABLE = False
class PluginType(Enum):
"""插件类型"""
@@ -38,6 +40,7 @@ class PluginType(Enum):
WEBDAV = "webdav"
CUSTOM = "custom"
class PluginStatus(Enum):
"""插件状态"""
@@ -46,6 +49,7 @@ class PluginStatus(Enum):
ERROR = "error"
PENDING = "pending"
@dataclass
class Plugin:
"""插件配置"""
@@ -61,6 +65,7 @@ class Plugin:
last_used_at: str | None = None
use_count: int = 0
@dataclass
class PluginConfig:
"""插件详细配置"""
@@ -73,6 +78,7 @@ class PluginConfig:
created_at: str = ""
updated_at: str = ""
@dataclass
class BotSession:
"""机器人会话"""
@@ -90,6 +96,7 @@ class BotSession:
last_message_at: str | None = None
message_count: int = 0
@dataclass
class WebhookEndpoint:
"""Webhook 端点配置Zapier/Make集成"""
@@ -108,6 +115,7 @@ class WebhookEndpoint:
last_triggered_at: str | None = None
trigger_count: int = 0
@dataclass
class WebDAVSync:
"""WebDAV 同步配置"""
@@ -129,6 +137,7 @@ class WebDAVSync:
updated_at: str = ""
sync_count: int = 0
@dataclass
class ChromeExtensionToken:
"""Chrome 扩展令牌"""
@@ -145,6 +154,7 @@ class ChromeExtensionToken:
use_count: int = 0
is_revoked: bool = False
class PluginManager:
"""插件管理主类"""
@@ -206,7 +216,9 @@ class PluginManager:
return self._row_to_plugin(row)
return None
def list_plugins(self, project_id: str = None, plugin_type: str = None, status: str = None) -> list[Plugin]:
def list_plugins(
self, project_id: str = None, plugin_type: str = None, status: str = None
) -> list[Plugin]:
"""列出插件"""
conn = self.db.get_conn()
@@ -225,7 +237,9 @@ class PluginManager:
where_clause = " AND ".join(conditions) if conditions else "1=1"
rows = conn.execute(f"SELECT * FROM plugins WHERE {where_clause} ORDER BY created_at DESC", params).fetchall()
rows = conn.execute(
f"SELECT * FROM plugins WHERE {where_clause} ORDER BY created_at DESC", params
).fetchall()
conn.close()
return [self._row_to_plugin(row) for row in rows]
@@ -292,7 +306,9 @@ class PluginManager:
# ==================== Plugin Config ====================
def set_plugin_config(self, plugin_id: str, key: str, value: str, is_encrypted: bool = False) -> PluginConfig:
def set_plugin_config(
self, plugin_id: str, key: str, value: str, is_encrypted: bool = False
) -> PluginConfig:
"""设置插件配置"""
conn = self.db.get_conn()
now = datetime.now().isoformat()
@@ -336,7 +352,8 @@ class PluginManager:
"""获取插件配置"""
conn = self.db.get_conn()
row = conn.execute(
"SELECT config_value FROM plugin_configs WHERE plugin_id = ? AND config_key = ?", (plugin_id, key)
"SELECT config_value FROM plugin_configs WHERE plugin_id = ? AND config_key = ?",
(plugin_id, key),
).fetchone()
conn.close()
@@ -355,7 +372,9 @@ class PluginManager:
def delete_plugin_config(self, plugin_id: str, key: str) -> bool:
"""删除插件配置"""
conn = self.db.get_conn()
cursor = conn.execute("DELETE FROM plugin_configs WHERE plugin_id = ? AND config_key = ?", (plugin_id, key))
cursor = conn.execute(
"DELETE FROM plugin_configs WHERE plugin_id = ? AND config_key = ?", (plugin_id, key)
)
conn.commit()
conn.close()
@@ -375,6 +394,7 @@ class PluginManager:
conn.commit()
conn.close()
class ChromeExtensionHandler:
"""Chrome 扩展处理器"""
@@ -485,13 +505,17 @@ class ChromeExtensionHandler:
def revoke_token(self, token_id: str) -> bool:
"""撤销令牌"""
conn = self.pm.db.get_conn()
cursor = conn.execute("UPDATE chrome_extension_tokens SET is_revoked = 1 WHERE id = ?", (token_id,))
cursor = conn.execute(
"UPDATE chrome_extension_tokens SET is_revoked = 1 WHERE id = ?", (token_id,)
)
conn.commit()
conn.close()
return cursor.rowcount > 0
def list_tokens(self, user_id: str = None, project_id: str = None) -> list[ChromeExtensionToken]:
def list_tokens(
self, user_id: str = None, project_id: str = None
) -> list[ChromeExtensionToken]:
"""列出令牌"""
conn = self.pm.db.get_conn()
@@ -508,7 +532,8 @@ class ChromeExtensionHandler:
where_clause = " AND ".join(conditions)
rows = conn.execute(
f"SELECT * FROM chrome_extension_tokens WHERE {where_clause} ORDER BY created_at DESC", params
f"SELECT * FROM chrome_extension_tokens WHERE {where_clause} ORDER BY created_at DESC",
params,
).fetchall()
conn.close()
@@ -533,7 +558,12 @@ class ChromeExtensionHandler:
return tokens
async def import_webpage(
self, token: ChromeExtensionToken, url: str, title: str, content: str, html_content: str = None
self,
token: ChromeExtensionToken,
url: str,
title: str,
content: str,
html_content: str = None,
) -> dict:
"""导入网页内容"""
if not token.project_id:
@@ -568,6 +598,7 @@ class ChromeExtensionHandler:
"content_length": len(content),
}
class BotHandler:
"""飞书/钉钉机器人处理器"""
@@ -576,7 +607,12 @@ class BotHandler:
self.bot_type = bot_type
def create_session(
self, session_id: str, session_name: str, project_id: str = None, webhook_url: str = "", secret: str = ""
self,
session_id: str,
session_name: str,
project_id: str = None,
webhook_url: str = "",
secret: str = "",
) -> BotSession:
"""创建机器人会话"""
bot_id = str(uuid.uuid4())[:8]
@@ -588,7 +624,19 @@ class BotHandler:
(id, bot_type, session_id, session_name, project_id, webhook_url, secret,
is_active, created_at, updated_at, message_count)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
(bot_id, self.bot_type, session_id, session_name, project_id, webhook_url, secret, True, now, now, 0),
(
bot_id,
self.bot_type,
session_id,
session_name,
project_id,
webhook_url,
secret,
True,
now,
now,
0,
),
)
conn.commit()
conn.close()
@@ -663,7 +711,9 @@ class BotHandler:
values.append(session_id)
values.append(self.bot_type)
query = f"UPDATE bot_sessions SET {', '.join(updates)} WHERE session_id = ? AND bot_type = ?"
query = (
f"UPDATE bot_sessions SET {', '.join(updates)} WHERE session_id = ? AND bot_type = ?"
)
conn.execute(query, values)
conn.commit()
conn.close()
@@ -674,7 +724,8 @@ class BotHandler:
"""删除会话"""
conn = self.pm.db.get_conn()
cursor = conn.execute(
"DELETE FROM bot_sessions WHERE session_id = ? AND bot_type = ?", (session_id, self.bot_type)
"DELETE FROM bot_sessions WHERE session_id = ? AND bot_type = ?",
(session_id, self.bot_type),
)
conn.commit()
conn.close()
@@ -753,13 +804,16 @@ class BotHandler:
return {
"success": True,
"response": f"""📊 项目状态:
实体数量: {stats.get('entity_count', 0)}
关系数量: {stats.get('relation_count', 0)}
转录数量: {stats.get('transcript_count', 0)}""",
实体数量: {stats.get("entity_count", 0)}
关系数量: {stats.get("relation_count", 0)}
转录数量: {stats.get("transcript_count", 0)}""",
}
# 默认回复
return {"success": True, "response": f"收到消息:{text[:100]}...\n\n使用 /help 查看可用命令"}
return {
"success": True,
"response": f"收到消息:{text[:100]}...\n\n使用 /help 查看可用命令",
}
async def _handle_audio_message(self, session: BotSession, message: dict) -> dict:
"""处理音频消息"""
@@ -820,13 +874,20 @@ class BotHandler:
if session.secret:
string_to_sign = f"{timestamp}\n{session.secret}"
hmac_code = hmac.new(
session.secret.encode("utf-8"), string_to_sign.encode("utf-8"), digestmod=hashlib.sha256
session.secret.encode("utf-8"),
string_to_sign.encode("utf-8"),
digestmod=hashlib.sha256,
).digest()
sign = base64.b64encode(hmac_code).decode("utf-8")
else:
sign = ""
payload = {"timestamp": timestamp, "sign": sign, "msg_type": "text", "content": {"text": message}}
payload = {
"timestamp": timestamp,
"sign": sign,
"msg_type": "text",
"content": {"text": message},
}
async with httpx.AsyncClient() as client:
response = await client.post(
@@ -834,7 +895,9 @@ class BotHandler:
)
return response.status_code == 200
async def _send_dingtalk_message(self, session: BotSession, message: str, msg_type: str) -> bool:
async def _send_dingtalk_message(
self, session: BotSession, message: str, msg_type: str
) -> bool:
"""发送钉钉消息"""
timestamp = str(round(time.time() * 1000))
@@ -842,7 +905,9 @@ class BotHandler:
if session.secret:
string_to_sign = f"{timestamp}\n{session.secret}"
hmac_code = hmac.new(
session.secret.encode("utf-8"), string_to_sign.encode("utf-8"), digestmod=hashlib.sha256
session.secret.encode("utf-8"),
string_to_sign.encode("utf-8"),
digestmod=hashlib.sha256,
).digest()
sign = base64.b64encode(hmac_code).decode("utf-8")
sign = urllib.parse.quote(sign)
@@ -856,9 +921,12 @@ class BotHandler:
url = f"{url}&timestamp={timestamp}&sign={sign}"
async with httpx.AsyncClient() as client:
response = await client.post(url, json=payload, headers={"Content-Type": "application/json"})
response = await client.post(
url, json=payload, headers={"Content-Type": "application/json"}
)
return response.status_code == 200
class WebhookIntegration:
"""Zapier/Make Webhook 集成"""
@@ -921,7 +989,8 @@ class WebhookIntegration:
"""获取端点"""
conn = self.pm.db.get_conn()
row = conn.execute(
"SELECT * FROM webhook_endpoints WHERE id = ? AND endpoint_type = ?", (endpoint_id, self.endpoint_type)
"SELECT * FROM webhook_endpoints WHERE id = ? AND endpoint_type = ?",
(endpoint_id, self.endpoint_type),
).fetchone()
conn.close()
@@ -1039,7 +1108,9 @@ class WebhookIntegration:
payload = {"event": event_type, "timestamp": datetime.now().isoformat(), "data": data}
async with httpx.AsyncClient() as client:
response = await client.post(endpoint.endpoint_url, json=payload, headers=headers, timeout=30.0)
response = await client.post(
endpoint.endpoint_url, json=payload, headers=headers, timeout=30.0
)
success = response.status_code in [200, 201, 202]
@@ -1078,6 +1149,7 @@ class WebhookIntegration:
"message": "Test event sent successfully" if success else "Failed to send test event",
}
class WebDAVSyncManager:
"""WebDAV 同步管理"""
@@ -1157,7 +1229,8 @@ class WebDAVSyncManager:
if project_id:
rows = conn.execute(
"SELECT * FROM webdav_syncs WHERE project_id = ? ORDER BY created_at DESC", (project_id,)
"SELECT * FROM webdav_syncs WHERE project_id = ? ORDER BY created_at DESC",
(project_id,),
).fetchall()
else:
rows = conn.execute("SELECT * FROM webdav_syncs ORDER BY created_at DESC").fetchall()
@@ -1278,7 +1351,11 @@ class WebDAVSyncManager:
transcripts = self.pm.db.list_project_transcripts(sync.project_id)
export_data = {
"project": {"id": project.id, "name": project.name, "description": project.description},
"project": {
"id": project.id,
"name": project.name,
"description": project.description,
},
"entities": [{"id": e.id, "name": e.name, "type": e.type} for e in entities],
"relations": relations,
"transcripts": [{"id": t["id"], "filename": t["filename"]} for t in transcripts],
@@ -1333,9 +1410,11 @@ class WebDAVSyncManager:
return {"success": False, "error": str(e)}
# Singleton instance
_plugin_manager = None
def get_plugin_manager(db_manager=None) -> None:
"""获取 PluginManager 单例"""
global _plugin_manager