fix: auto-fix code issues (cron)
- 修复重复导入/字段 - 修复异常处理 - 修复PEP8格式问题 - 添加类型注解 - 修复缺失的urllib.parse导入
This commit is contained in:
@@ -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}×tamp={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
|
||||
|
||||
Reference in New Issue
Block a user