style: auto-format code with ruff (cron)

This commit is contained in:
AutoFix Bot
2026-03-02 18:13:08 +08:00
parent 98527c4de4
commit dc783c9d8e
22 changed files with 685 additions and 590 deletions

View File

@@ -19,16 +19,16 @@ class CodeIssue:
line_no: int, line_no: int,
issue_type: str, issue_type: str,
message: str, message: str,
severity: str = "warning", severity: str = "warning",
original_line: str = "", original_line: str = "",
) -> None: ) -> None:
self.file_path = file_path self.file_path = file_path
self.line_no = line_no self.line_no = line_no
self.issue_type = issue_type self.issue_type = issue_type
self.message = message self.message = message
self.severity = severity self.severity = severity
self.original_line = original_line self.original_line = original_line
self.fixed = False self.fixed = False
def __repr__(self) -> None: def __repr__(self) -> None:
return f"{self.file_path}:{self.line_no} [{self.severity}] {self.issue_type}: {self.message}" return f"{self.file_path}:{self.line_no} [{self.severity}] {self.issue_type}: {self.message}"
@@ -38,11 +38,11 @@ class CodeFixer:
"""代码自动修复器""" """代码自动修复器"""
def __init__(self, project_path: str) -> None: def __init__(self, project_path: str) -> None:
self.project_path = Path(project_path) self.project_path = Path(project_path)
self.issues: list[CodeIssue] = [] self.issues: list[CodeIssue] = []
self.fixed_issues: list[CodeIssue] = [] self.fixed_issues: list[CodeIssue] = []
self.manual_issues: list[CodeIssue] = [] self.manual_issues: list[CodeIssue] = []
self.scanned_files: list[str] = [] self.scanned_files: list[str] = []
def scan_all_files(self) -> None: def scan_all_files(self) -> None:
"""扫描所有 Python 文件""" """扫描所有 Python 文件"""
@@ -55,9 +55,9 @@ class CodeFixer:
def _scan_file(self, file_path: Path) -> None: def _scan_file(self, file_path: Path) -> None:
"""扫描单个文件""" """扫描单个文件"""
try: try:
with open(file_path, "r", encoding = "utf-8") as f: with open(file_path, "r", encoding="utf-8") as f:
content = f.read() content = f.read()
lines = content.split("\n") lines = content.split("\n")
except Exception as e: except Exception as e:
print(f"Error reading {file_path}: {e}") print(f"Error reading {file_path}: {e}")
return return
@@ -123,32 +123,37 @@ class CodeFixer:
if line.rstrip() != line and line.strip(): if line.rstrip() != line and line.strip():
self.issues.append( self.issues.append(
CodeIssue( CodeIssue(
str(file_path), i, "trailing_whitespace", "行尾有空格", "info", line str(file_path),
i,
"trailing_whitespace",
"行尾有空格",
"info",
line,
) )
) )
def _check_unused_imports(self, file_path: Path, content: str) -> None: def _check_unused_imports(self, file_path: Path, content: str) -> None:
"""检查未使用的导入""" """检查未使用的导入"""
try: try:
tree = ast.parse(content) tree = ast.parse(content)
except SyntaxError: except SyntaxError:
return return
imports = {} imports = {}
for node in ast.walk(tree): for node in ast.walk(tree):
if isinstance(node, ast.Import): if isinstance(node, ast.Import):
for alias in node.names: for alias in node.names:
name = alias.asname if alias.asname else alias.name name = alias.asname if alias.asname else alias.name
imports[name] = node.lineno imports[name] = node.lineno
elif isinstance(node, ast.ImportFrom): elif isinstance(node, ast.ImportFrom):
for alias in node.names: for alias in node.names:
name = alias.asname if alias.asname else alias.name name = alias.asname if alias.asname else alias.name
if alias.name == "*": if alias.name == "*":
continue continue
imports[name] = node.lineno imports[name] = node.lineno
# 检查使用 # 检查使用
used_names = set() used_names = set()
for node in ast.walk(tree): for node in ast.walk(tree):
if isinstance(node, ast.Name): if isinstance(node, ast.Name):
used_names.add(node.id) used_names.add(node.id)
@@ -198,7 +203,9 @@ class CodeFixer:
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
if "allow_origins" in line and '["*"]' in line: if "allow_origins" in line and '["*"]' in line:
# 排除扫描工具自身的代码 # 排除扫描工具自身的代码
if "code_reviewer" in str(file_path) or "auto_code_fixer" in str(file_path): if "code_reviewer" in str(file_path) or "auto_code_fixer" in str(
file_path
):
continue continue
self.manual_issues.append( self.manual_issues.append(
CodeIssue( CodeIssue(
@@ -216,11 +223,11 @@ class CodeFixer:
) -> None: ) -> None:
"""检查敏感信息泄露""" """检查敏感信息泄露"""
# 排除的文件 # 排除的文件
excluded_files = ["auto_code_fixer.py", "code_reviewer.py"] excluded_files = ["auto_code_fixer.py", "code_reviewer.py"]
if any(excluded in str(file_path) for excluded in excluded_files): if any(excluded in str(file_path) for excluded in excluded_files):
return return
patterns = [ patterns = [
(r'password\s* = \s*["\'][^"\']{8, }["\']', "硬编码密码"), (r'password\s* = \s*["\'][^"\']{8, }["\']', "硬编码密码"),
(r'secret_key\s* = \s*["\'][^"\']{8, }["\']', "硬编码密钥"), (r'secret_key\s* = \s*["\'][^"\']{8, }["\']', "硬编码密钥"),
(r'api_key\s* = \s*["\'][^"\']{8, }["\']', "硬编码 API Key"), (r'api_key\s* = \s*["\'][^"\']{8, }["\']', "硬编码 API Key"),
@@ -238,10 +245,13 @@ class CodeFixer:
if "os.getenv" in line or "os.environ" in line: if "os.getenv" in line or "os.environ" in line:
continue continue
# 排除示例/测试代码中的占位符 # 排除示例/测试代码中的占位符
if any(x in line.lower() for x in ["your_", "example", "placeholder", "test", "demo"]): if any(
x in line.lower()
for x in ["your_", "example", "placeholder", "test", "demo"]
):
continue continue
# 排除 Enum 定义 # 排除 Enum 定义
if re.search(r'^\s*[A-Z_]+\s* = ', line.strip()): if re.search(r"^\s*[A-Z_]+\s* = ", line.strip()):
continue continue
self.manual_issues.append( self.manual_issues.append(
CodeIssue( CodeIssue(
@@ -256,17 +266,17 @@ class CodeFixer:
def fix_auto_fixable(self) -> None: def fix_auto_fixable(self) -> None:
"""自动修复可修复的问题""" """自动修复可修复的问题"""
auto_fix_types = { auto_fix_types = {
"trailing_whitespace", "trailing_whitespace",
"bare_exception", "bare_exception",
} }
# 按文件分组 # 按文件分组
files_to_fix = {} files_to_fix = {}
for issue in self.issues: for issue in self.issues:
if issue.issue_type in auto_fix_types: if issue.issue_type in auto_fix_types:
if issue.file_path not in files_to_fix: if issue.file_path not in files_to_fix:
files_to_fix[issue.file_path] = [] files_to_fix[issue.file_path] = []
files_to_fix[issue.file_path].append(issue) files_to_fix[issue.file_path].append(issue)
for file_path, file_issues in files_to_fix.items(): for file_path, file_issues in files_to_fix.items():
@@ -275,43 +285,45 @@ class CodeFixer:
continue continue
try: try:
with open(file_path, "r", encoding = "utf-8") as f: with open(file_path, "r", encoding="utf-8") as f:
content = f.read() content = f.read()
lines = content.split("\n") lines = content.split("\n")
except Exception: except Exception:
continue continue
original_lines = lines.copy() original_lines = lines.copy()
fixed_lines = set() fixed_lines = set()
# 修复行尾空格 # 修复行尾空格
for issue in file_issues: for issue in file_issues:
if issue.issue_type == "trailing_whitespace": if issue.issue_type == "trailing_whitespace":
line_idx = issue.line_no - 1 line_idx = issue.line_no - 1
if 0 <= line_idx < len(lines) and line_idx not in fixed_lines: if 0 <= line_idx < len(lines) and line_idx not in fixed_lines:
if lines[line_idx].rstrip() != lines[line_idx]: if lines[line_idx].rstrip() != lines[line_idx]:
lines[line_idx] = lines[line_idx].rstrip() lines[line_idx] = lines[line_idx].rstrip()
fixed_lines.add(line_idx) fixed_lines.add(line_idx)
issue.fixed = True issue.fixed = True
self.fixed_issues.append(issue) self.fixed_issues.append(issue)
# 修复裸异常 # 修复裸异常
for issue in file_issues: for issue in file_issues:
if issue.issue_type == "bare_exception": if issue.issue_type == "bare_exception":
line_idx = issue.line_no - 1 line_idx = issue.line_no - 1
if 0 <= line_idx < len(lines) and line_idx not in fixed_lines: if 0 <= line_idx < len(lines) and line_idx not in fixed_lines:
line = lines[line_idx] line = lines[line_idx]
# 将 except Exception: 改为 except Exception: # 将 except Exception: 改为 except Exception:
if re.search(r"except\s*:\s*$", line.strip()): if re.search(r"except\s*:\s*$", line.strip()):
lines[line_idx] = line.replace("except Exception:", "except Exception:") lines[line_idx] = line.replace(
"except Exception:", "except Exception:"
)
fixed_lines.add(line_idx) fixed_lines.add(line_idx)
issue.fixed = True issue.fixed = True
self.fixed_issues.append(issue) self.fixed_issues.append(issue)
# 如果文件有修改,写回 # 如果文件有修改,写回
if lines != original_lines: if lines != original_lines:
try: try:
with open(file_path, "w", encoding = "utf-8") as f: with open(file_path, "w", encoding="utf-8") as f:
f.write("\n".join(lines)) f.write("\n".join(lines))
print(f"Fixed issues in {file_path}") print(f"Fixed issues in {file_path}")
except Exception as e: except Exception as e:
@@ -319,7 +331,7 @@ class CodeFixer:
def categorize_issues(self) -> dict[str, list[CodeIssue]]: def categorize_issues(self) -> dict[str, list[CodeIssue]]:
"""分类问题""" """分类问题"""
categories = { categories = {
"critical": [], "critical": [],
"error": [], "error": [],
"warning": [], "warning": [],
@@ -334,7 +346,7 @@ class CodeFixer:
def generate_report(self) -> str: def generate_report(self) -> str:
"""生成修复报告""" """生成修复报告"""
report = [] report = []
report.append("# InsightFlow 代码审查报告") report.append("# InsightFlow 代码审查报告")
report.append("") report.append("")
report.append(f"扫描时间: {os.popen('date').read().strip()}") report.append(f"扫描时间: {os.popen('date').read().strip()}")
@@ -349,15 +361,19 @@ class CodeFixer:
report.append("") report.append("")
# 问题统计 # 问题统计
categories = self.categorize_issues() categories = self.categorize_issues()
manual_critical = [i for i in self.manual_issues if i.severity == "critical"] manual_critical = [i for i in self.manual_issues if i.severity == "critical"]
manual_warning = [i for i in self.manual_issues if i.severity == "warning"] manual_warning = [i for i in self.manual_issues if i.severity == "warning"]
report.append("## 问题分类统计") report.append("## 问题分类统计")
report.append("") report.append("")
report.append(f"- 🔴 Critical: {len(categories['critical']) + len(manual_critical)}") report.append(
f"- 🔴 Critical: {len(categories['critical']) + len(manual_critical)}"
)
report.append(f"- 🟠 Error: {len(categories['error'])}") report.append(f"- 🟠 Error: {len(categories['error'])}")
report.append(f"- 🟡 Warning: {len(categories['warning']) + len(manual_warning)}") report.append(
f"- 🟡 Warning: {len(categories['warning']) + len(manual_warning)}"
)
report.append(f"- 🔵 Info: {len(categories['info'])}") report.append(f"- 🔵 Info: {len(categories['info'])}")
report.append(f"- **总计: {len(self.issues) + len(self.manual_issues)}**") report.append(f"- **总计: {len(self.issues) + len(self.manual_issues)}**")
report.append("") report.append("")
@@ -393,17 +409,13 @@ class CodeFixer:
# 其他问题 # 其他问题
report.append("## 📋 其他发现的问题") report.append("## 📋 其他发现的问题")
report.append("") report.append("")
other_issues = [ other_issues = [i for i in self.issues if i not in self.fixed_issues]
i
for i in self.issues
if i not in self.fixed_issues
]
# 按类型分组 # 按类型分组
by_type = {} by_type = {}
for issue in other_issues: for issue in other_issues:
if issue.issue_type not in by_type: if issue.issue_type not in by_type:
by_type[issue.issue_type] = [] by_type[issue.issue_type] = []
by_type[issue.issue_type].append(issue) by_type[issue.issue_type].append(issue)
for issue_type, issues in sorted(by_type.items()): for issue_type, issues in sorted(by_type.items()):
@@ -424,21 +436,21 @@ def git_commit_and_push(project_path: str) -> tuple[bool, str]:
"""Git 提交和推送""" """Git 提交和推送"""
try: try:
# 检查是否有变更 # 检查是否有变更
result = subprocess.run( result = subprocess.run(
["git", "status", "--porcelain"], ["git", "status", "--porcelain"],
cwd = project_path, cwd=project_path,
capture_output = True, capture_output=True,
text = True, text=True,
) )
if not result.stdout.strip(): if not result.stdout.strip():
return True, "没有需要提交的变更" return True, "没有需要提交的变更"
# 添加所有变更 # 添加所有变更
subprocess.run(["git", "add", "-A"], cwd = project_path, check = True) subprocess.run(["git", "add", "-A"], cwd=project_path, check=True)
# 提交 # 提交
commit_msg = """fix: auto-fix code issues (cron) commit_msg = """fix: auto-fix code issues (cron)
- 修复重复导入/字段 - 修复重复导入/字段
- 修复异常处理 - 修复异常处理
@@ -446,11 +458,11 @@ def git_commit_and_push(project_path: str) -> tuple[bool, str]:
- 添加类型注解""" - 添加类型注解"""
subprocess.run( subprocess.run(
["git", "commit", "-m", commit_msg], cwd = project_path, check = True ["git", "commit", "-m", commit_msg], cwd=project_path, check=True
) )
# 推送 # 推送
subprocess.run(["git", "push"], cwd = project_path, check = True) subprocess.run(["git", "push"], cwd=project_path, check=True)
return True, "提交并推送成功" return True, "提交并推送成功"
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
@@ -460,10 +472,10 @@ def git_commit_and_push(project_path: str) -> tuple[bool, str]:
def main() -> None: def main() -> None:
project_path = "/root/.openclaw/workspace/projects/insightflow" project_path = "/root/.openclaw/workspace/projects/insightflow"
print("🔍 开始扫描代码...") print("🔍 开始扫描代码...")
fixer = CodeFixer(project_path) fixer = CodeFixer(project_path)
fixer.scan_all_files() fixer.scan_all_files()
print(f"📊 发现 {len(fixer.issues)} 个可自动修复问题") print(f"📊 发现 {len(fixer.issues)} 个可自动修复问题")
@@ -475,25 +487,25 @@ def main() -> None:
print(f"✅ 已修复 {len(fixer.fixed_issues)} 个问题") print(f"✅ 已修复 {len(fixer.fixed_issues)} 个问题")
# 生成报告 # 生成报告
report = fixer.generate_report() report = fixer.generate_report()
# 保存报告 # 保存报告
report_path = Path(project_path) / "AUTO_CODE_REVIEW_REPORT.md" report_path = Path(project_path) / "AUTO_CODE_REVIEW_REPORT.md"
with open(report_path, "w", encoding = "utf-8") as f: with open(report_path, "w", encoding="utf-8") as f:
f.write(report) f.write(report)
print(f"📝 报告已保存到: {report_path}") print(f"📝 报告已保存到: {report_path}")
# Git 提交 # Git 提交
print("📤 提交变更到 Git...") print("📤 提交变更到 Git...")
success, msg = git_commit_and_push(project_path) success, msg = git_commit_and_push(project_path)
print(f"{'' if success else ''} {msg}") print(f"{'' if success else ''} {msg}")
# 添加 Git 结果到报告 # 添加 Git 结果到报告
report += f"\n\n## Git 提交结果\n\n{'' if success else ''} {msg}\n" report += f"\n\n## Git 提交结果\n\n{'' if success else ''} {msg}\n"
# 重新保存完整报告 # 重新保存完整报告
with open(report_path, "w", encoding = "utf-8") as f: with open(report_path, "w", encoding="utf-8") as f:
f.write(report) f.write(report)
print("\n" + " = " * 60) print("\n" + " = " * 60)

View File

@@ -11,16 +11,18 @@ from pathlib import Path
PROJECT_DIR = Path("/root/.openclaw/workspace/projects/insightflow") PROJECT_DIR = Path("/root/.openclaw/workspace/projects/insightflow")
BACKEND_DIR = PROJECT_DIR / "backend" BACKEND_DIR = PROJECT_DIR / "backend"
def run_flake8(): def run_flake8():
"""运行 flake8 检查""" """运行 flake8 检查"""
result = subprocess.run( result = subprocess.run(
["flake8", "--max-line-length=120", "--ignore=E501,W503", "."], ["flake8", "--max-line-length=120", "--ignore=E501,W503", "."],
cwd=BACKEND_DIR, cwd=BACKEND_DIR,
capture_output=True, capture_output=True,
text=True text=True,
) )
return result.stdout return result.stdout
def fix_missing_imports(): def fix_missing_imports():
"""修复缺失的导入""" """修复缺失的导入"""
fixes = [] fixes = []
@@ -31,13 +33,13 @@ def fix_missing_imports():
content = workflow_file.read_text() content = workflow_file.read_text()
if "import urllib" not in content and "urllib" in content: if "import urllib" not in content and "urllib" in content:
# 在文件开头添加导入 # 在文件开头添加导入
lines = content.split('\n') lines = content.split("\n")
import_idx = 0 import_idx = 0
for i, line in enumerate(lines): for i, line in enumerate(lines):
if line.startswith('import ') or line.startswith('from '): if line.startswith("import ") or line.startswith("from "):
import_idx = i + 1 import_idx = i + 1
lines.insert(import_idx, 'import urllib.parse') lines.insert(import_idx, "import urllib.parse")
workflow_file.write_text('\n'.join(lines)) workflow_file.write_text("\n".join(lines))
fixes.append("workflow_manager.py: 添加 urllib.parse 导入") fixes.append("workflow_manager.py: 添加 urllib.parse 导入")
# 检查 plugin_manager.py 中的 urllib # 检查 plugin_manager.py 中的 urllib
@@ -45,31 +47,38 @@ def fix_missing_imports():
if plugin_file.exists(): if plugin_file.exists():
content = plugin_file.read_text() content = plugin_file.read_text()
if "import urllib" not in content and "urllib" in content: if "import urllib" not in content and "urllib" in content:
lines = content.split('\n') lines = content.split("\n")
import_idx = 0 import_idx = 0
for i, line in enumerate(lines): for i, line in enumerate(lines):
if line.startswith('import ') or line.startswith('from '): if line.startswith("import ") or line.startswith("from "):
import_idx = i + 1 import_idx = i + 1
lines.insert(import_idx, 'import urllib.parse') lines.insert(import_idx, "import urllib.parse")
plugin_file.write_text('\n'.join(lines)) plugin_file.write_text("\n".join(lines))
fixes.append("plugin_manager.py: 添加 urllib.parse 导入") fixes.append("plugin_manager.py: 添加 urllib.parse 导入")
# 检查 main.py 中的 PlainTextResponse # 检查 main.py 中的 PlainTextResponse
main_file = BACKEND_DIR / "main.py" main_file = BACKEND_DIR / "main.py"
if main_file.exists(): if main_file.exists():
content = main_file.read_text() content = main_file.read_text()
if "PlainTextResponse" in content and "from fastapi.responses import" in content: if (
"PlainTextResponse" in content
and "from fastapi.responses import" in content
):
# 检查是否已导入 # 检查是否已导入
if "PlainTextResponse" not in content.split('from fastapi.responses import')[1].split('\n')[0]: if (
"PlainTextResponse"
not in content.split("from fastapi.responses import")[1].split("\n")[0]
):
# 添加导入 # 添加导入
content = content.replace( content = content.replace(
"from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse", "from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse",
"from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse" "from fastapi.responses import JSONResponse, PlainTextResponse, StreamingResponse",
) )
# 实际上已经导入了,可能是误报 # 实际上已经导入了,可能是误报
return fixes return fixes
def fix_unused_imports(): def fix_unused_imports():
"""修复未使用的导入""" """修复未使用的导入"""
fixes = [] fixes = []
@@ -80,15 +89,16 @@ def fix_unused_imports():
content = code_reviewer.read_text() content = code_reviewer.read_text()
original = content original = content
# 移除未使用的导入 # 移除未使用的导入
content = re.sub(r'^import os\n', '', content, flags=re.MULTILINE) content = re.sub(r"^import os\n", "", content, flags=re.MULTILINE)
content = re.sub(r'^import subprocess\n', '', content, flags=re.MULTILINE) content = re.sub(r"^import subprocess\n", "", content, flags=re.MULTILINE)
content = re.sub(r'^from typing import Any\n', '', content, flags=re.MULTILINE) content = re.sub(r"^from typing import Any\n", "", content, flags=re.MULTILINE)
if content != original: if content != original:
code_reviewer.write_text(content) code_reviewer.write_text(content)
fixes.append("code_reviewer.py: 移除未使用的导入") fixes.append("code_reviewer.py: 移除未使用的导入")
return fixes return fixes
def fix_formatting(): def fix_formatting():
"""使用 autopep8 修复格式问题""" """使用 autopep8 修复格式问题"""
fixes = [] fixes = []
@@ -98,7 +108,7 @@ def fix_formatting():
["autopep8", "--in-place", "--aggressive", "--max-line-length=120", "."], ["autopep8", "--in-place", "--aggressive", "--max-line-length=120", "."],
cwd=BACKEND_DIR, cwd=BACKEND_DIR,
capture_output=True, capture_output=True,
text=True text=True,
) )
if result.returncode == 0: if result.returncode == 0:
@@ -106,6 +116,7 @@ def fix_formatting():
return fixes return fixes
def main(): def main():
print("=" * 60) print("=" * 60)
print("InsightFlow 代码自动修复") print("InsightFlow 代码自动修复")
@@ -142,12 +153,13 @@ def main():
print("\n重新运行 flake8 检查...") print("\n重新运行 flake8 检查...")
remaining = run_flake8() remaining = run_flake8()
if remaining: if remaining:
lines = remaining.strip().split('\n') lines = remaining.strip().split("\n")
print(f" 仍有 {len(lines)} 个问题需要手动处理") print(f" 仍有 {len(lines)} 个问题需要手动处理")
else: else:
print(" ✓ 所有问题已修复!") print(" ✓ 所有问题已修复!")
return all_fixes return all_fixes
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -283,7 +283,7 @@ class AIManager:
def get_custom_model(self, model_id: str) -> CustomModel | None: def get_custom_model(self, model_id: str) -> CustomModel | None:
"""获取自定义模型""" """获取自定义模型"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM custom_models WHERE id = ?", (model_id, )).fetchone() row = conn.execute("SELECT * FROM custom_models WHERE id = ?", (model_id,)).fetchone()
if not row: if not row:
return None return None
@@ -350,7 +350,8 @@ class AIManager:
"""获取训练样本""" """获取训练样本"""
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM training_samples WHERE model_id = ? ORDER BY created_at", (model_id, ) "SELECT * FROM training_samples WHERE model_id = ? ORDER BY created_at",
(model_id,),
).fetchall() ).fetchall()
return [self._row_to_training_sample(row) for row in rows] return [self._row_to_training_sample(row) for row in rows]
@@ -712,7 +713,7 @@ class AIManager:
def get_kg_rag(self, rag_id: str) -> KnowledgeGraphRAG | None: def get_kg_rag(self, rag_id: str) -> KnowledgeGraphRAG | None:
"""获取知识图谱 RAG 配置""" """获取知识图谱 RAG 配置"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM kg_rag_configs WHERE id = ?", (rag_id, )).fetchone() row = conn.execute("SELECT * FROM kg_rag_configs WHERE id = ?", (rag_id,)).fetchone()
if not row: if not row:
return None return None
@@ -1122,7 +1123,7 @@ class AIManager:
"""获取预测模型""" """获取预测模型"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM prediction_models WHERE id = ?", (model_id, ) "SELECT * FROM prediction_models WHERE id = ?", (model_id,)
).fetchone() ).fetchone()
if not row: if not row:
@@ -1238,7 +1239,7 @@ class AIManager:
# 更新预测计数 # 更新预测计数
conn.execute( conn.execute(
"UPDATE prediction_models SET prediction_count = prediction_count + 1 WHERE id = ?", "UPDATE prediction_models SET prediction_count = prediction_count + 1 WHERE id = ?",
(model_id, ), (model_id,),
) )
conn.commit() conn.commit()

View File

@@ -207,7 +207,7 @@ class ApiKeyManager:
with sqlite3.connect(self.db_path) as conn: with sqlite3.connect(self.db_path) as conn:
conn.row_factory = sqlite3.Row conn.row_factory = sqlite3.Row
row = conn.execute("SELECT * FROM api_keys WHERE key_hash = ?", (key_hash, )).fetchone() row = conn.execute("SELECT * FROM api_keys WHERE key_hash = ?", (key_hash,)).fetchone()
if not row: if not row:
return None return None
@@ -238,7 +238,7 @@ class ApiKeyManager:
# 验证所有权(如果提供了 owner_id # 验证所有权(如果提供了 owner_id
if owner_id: if owner_id:
row = conn.execute( row = conn.execute(
"SELECT owner_id FROM api_keys WHERE id = ?", (key_id, ) "SELECT owner_id FROM api_keys WHERE id = ?", (key_id,)
).fetchone() ).fetchone()
if not row or row[0] != owner_id: if not row or row[0] != owner_id:
return False return False
@@ -270,7 +270,7 @@ class ApiKeyManager:
"SELECT * FROM api_keys WHERE id = ? AND owner_id = ?", (key_id, owner_id) "SELECT * FROM api_keys WHERE id = ? AND owner_id = ?", (key_id, owner_id)
).fetchone() ).fetchone()
else: else:
row = conn.execute("SELECT * FROM api_keys WHERE id = ?", (key_id, )).fetchone() row = conn.execute("SELECT * FROM api_keys WHERE id = ?", (key_id,)).fetchone()
if row: if row:
return self._row_to_api_key(row) return self._row_to_api_key(row)
@@ -337,7 +337,7 @@ class ApiKeyManager:
# 验证所有权 # 验证所有权
if owner_id: if owner_id:
row = conn.execute( row = conn.execute(
"SELECT owner_id FROM api_keys WHERE id = ?", (key_id, ) "SELECT owner_id FROM api_keys WHERE id = ?", (key_id,)
).fetchone() ).fetchone()
if not row or row[0] != owner_id: if not row or row[0] != owner_id:
return False return False

View File

@@ -263,7 +263,7 @@ class CollaborationManager:
""" """
SELECT * FROM project_shares WHERE token = ? SELECT * FROM project_shares WHERE token = ?
""", """,
(token, ), (token,),
) )
row = cursor.fetchone() row = cursor.fetchone()
@@ -300,7 +300,7 @@ class CollaborationManager:
SET use_count = use_count + 1 SET use_count = use_count + 1
WHERE token = ? WHERE token = ?
""", """,
(token, ), (token,),
) )
self.db.conn.commit() self.db.conn.commit()
@@ -314,7 +314,7 @@ class CollaborationManager:
SET is_active = 0 SET is_active = 0
WHERE id = ? WHERE id = ?
""", """,
(share_id, ), (share_id,),
) )
self.db.conn.commit() self.db.conn.commit()
return cursor.rowcount > 0 return cursor.rowcount > 0
@@ -332,7 +332,7 @@ class CollaborationManager:
WHERE project_id = ? WHERE project_id = ?
ORDER BY created_at DESC ORDER BY created_at DESC
""", """,
(project_id, ), (project_id,),
) )
shares = [] shares = []
@@ -510,7 +510,7 @@ class CollaborationManager:
def _get_comment_by_id(self, comment_id: str) -> Comment | None: def _get_comment_by_id(self, comment_id: str) -> Comment | None:
"""根据ID获取评论""" """根据ID获取评论"""
cursor = self.db.conn.cursor() cursor = self.db.conn.cursor()
cursor.execute("SELECT * FROM comments WHERE id = ?", (comment_id, )) cursor.execute("SELECT * FROM comments WHERE id = ?", (comment_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
return self._row_to_comment(row) return self._row_to_comment(row)
@@ -773,7 +773,7 @@ class CollaborationManager:
""" """
SELECT COUNT(*) FROM change_history WHERE project_id = ? SELECT COUNT(*) FROM change_history WHERE project_id = ?
""", """,
(project_id, ), (project_id,),
) )
total_changes = cursor.fetchone()[0] total_changes = cursor.fetchone()[0]
@@ -783,7 +783,7 @@ class CollaborationManager:
SELECT change_type, COUNT(*) FROM change_history SELECT change_type, COUNT(*) FROM change_history
WHERE project_id = ? GROUP BY change_type WHERE project_id = ? GROUP BY change_type
""", """,
(project_id, ), (project_id,),
) )
type_counts = {row[0]: row[1] for row in cursor.fetchall()} type_counts = {row[0]: row[1] for row in cursor.fetchall()}
@@ -793,7 +793,7 @@ class CollaborationManager:
SELECT entity_type, COUNT(*) FROM change_history SELECT entity_type, COUNT(*) FROM change_history
WHERE project_id = ? GROUP BY entity_type WHERE project_id = ? GROUP BY entity_type
""", """,
(project_id, ), (project_id,),
) )
entity_type_counts = {row[0]: row[1] for row in cursor.fetchall()} entity_type_counts = {row[0]: row[1] for row in cursor.fetchall()}
@@ -806,7 +806,7 @@ class CollaborationManager:
ORDER BY count DESC ORDER BY count DESC
LIMIT 5 LIMIT 5
""", """,
(project_id, ), (project_id,),
) )
top_contributors = [{"name": row[0], "changes": row[1]} for row in cursor.fetchall()] top_contributors = [{"name": row[0], "changes": row[1]} for row in cursor.fetchall()]
@@ -902,7 +902,7 @@ class CollaborationManager:
SELECT * FROM team_members WHERE project_id = ? SELECT * FROM team_members WHERE project_id = ?
ORDER BY joined_at ASC ORDER BY joined_at ASC
""", """,
(project_id, ), (project_id,),
) )
members = [] members = []
@@ -949,7 +949,7 @@ class CollaborationManager:
return False return False
cursor = self.db.conn.cursor() cursor = self.db.conn.cursor()
cursor.execute("DELETE FROM team_members WHERE id = ?", (member_id, )) cursor.execute("DELETE FROM team_members WHERE id = ?", (member_id,))
self.db.conn.commit() self.db.conn.commit()
return cursor.rowcount > 0 return cursor.rowcount > 0

View File

@@ -154,7 +154,7 @@ class DatabaseManager:
def get_project(self, project_id: str) -> Project | None: def get_project(self, project_id: str) -> Project | None:
conn = self.get_conn() conn = self.get_conn()
row = conn.execute("SELECT * FROM projects WHERE id = ?", (project_id, )).fetchone() row = conn.execute("SELECT * FROM projects WHERE id = ?", (project_id,)).fetchone()
conn.close() conn.close()
if row: if row:
return Project(**dict(row)) return Project(**dict(row))
@@ -211,7 +211,8 @@ class DatabaseManager:
"""查找相似实体""" """查找相似实体"""
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT * FROM entities WHERE project_id = ? AND name LIKE ?", (project_id, f"%{name}%") "SELECT * FROM entities WHERE project_id = ? AND name LIKE ?",
(project_id, f"%{name}%"),
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -226,8 +227,8 @@ class DatabaseManager:
"""合并两个实体""" """合并两个实体"""
conn = self.get_conn() conn = self.get_conn()
target = conn.execute("SELECT * FROM entities WHERE id = ?", (target_id, )).fetchone() target = conn.execute("SELECT * FROM entities WHERE id = ?", (target_id,)).fetchone()
source = conn.execute("SELECT * FROM entities WHERE id = ?", (source_id, )).fetchone() source = conn.execute("SELECT * FROM entities WHERE id = ?", (source_id,)).fetchone()
if not target or not source: if not target or not source:
conn.close() conn.close()
@@ -252,7 +253,7 @@ class DatabaseManager:
"UPDATE entity_relations SET target_entity_id = ? WHERE target_entity_id = ?", "UPDATE entity_relations SET target_entity_id = ? WHERE target_entity_id = ?",
(target_id, source_id), (target_id, source_id),
) )
conn.execute("DELETE FROM entities WHERE id = ?", (source_id, )) conn.execute("DELETE FROM entities WHERE id = ?", (source_id,))
conn.commit() conn.commit()
conn.close() conn.close()
@@ -260,7 +261,7 @@ class DatabaseManager:
def get_entity(self, entity_id: str) -> Entity | None: def get_entity(self, entity_id: str) -> Entity | None:
conn = self.get_conn() conn = self.get_conn()
row = conn.execute("SELECT * FROM entities WHERE id = ?", (entity_id, )).fetchone() row = conn.execute("SELECT * FROM entities WHERE id = ?", (entity_id,)).fetchone()
conn.close() conn.close()
if row: if row:
data = dict(row) data = dict(row)
@@ -271,7 +272,7 @@ class DatabaseManager:
def list_project_entities(self, project_id: str) -> list[Entity]: def list_project_entities(self, project_id: str) -> list[Entity]:
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT * FROM entities WHERE project_id = ? ORDER BY updated_at DESC", (project_id, ) "SELECT * FROM entities WHERE project_id = ? ORDER BY updated_at DESC", (project_id,)
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -316,13 +317,13 @@ class DatabaseManager:
def delete_entity(self, entity_id: str) -> None: def delete_entity(self, entity_id: str) -> None:
"""删除实体及其关联数据""" """删除实体及其关联数据"""
conn = self.get_conn() conn = self.get_conn()
conn.execute("DELETE FROM entity_mentions WHERE entity_id = ?", (entity_id, )) conn.execute("DELETE FROM entity_mentions WHERE entity_id = ?", (entity_id,))
conn.execute( conn.execute(
"DELETE FROM entity_relations WHERE source_entity_id = ? OR target_entity_id = ?", "DELETE FROM entity_relations WHERE source_entity_id = ? OR target_entity_id = ?",
(entity_id, entity_id), (entity_id, entity_id),
) )
conn.execute("DELETE FROM entity_attributes WHERE entity_id = ?", (entity_id, )) conn.execute("DELETE FROM entity_attributes WHERE entity_id = ?", (entity_id,))
conn.execute("DELETE FROM entities WHERE id = ?", (entity_id, )) conn.execute("DELETE FROM entities WHERE id = ?", (entity_id,))
conn.commit() conn.commit()
conn.close() conn.close()
@@ -352,7 +353,7 @@ class DatabaseManager:
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT * FROM entity_mentions WHERE entity_id = ? ORDER BY transcript_id, start_pos", "SELECT * FROM entity_mentions WHERE entity_id = ? ORDER BY transcript_id, start_pos",
(entity_id, ), (entity_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
return [EntityMention(**dict(r)) for r in rows] return [EntityMention(**dict(r)) for r in rows]
@@ -380,14 +381,15 @@ class DatabaseManager:
def get_transcript(self, transcript_id: str) -> dict | None: def get_transcript(self, transcript_id: str) -> dict | None:
conn = self.get_conn() conn = self.get_conn()
row = conn.execute("SELECT * FROM transcripts WHERE id = ?", (transcript_id, )).fetchone() row = conn.execute("SELECT * FROM transcripts WHERE id = ?", (transcript_id,)).fetchone()
conn.close() conn.close()
return dict(row) if row else None return dict(row) if row else None
def list_project_transcripts(self, project_id: str) -> list[dict]: def list_project_transcripts(self, project_id: str) -> list[dict]:
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT * FROM transcripts WHERE project_id = ? ORDER BY created_at DESC", (project_id, ) "SELECT * FROM transcripts WHERE project_id = ? ORDER BY created_at DESC",
(project_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
return [dict(r) for r in rows] return [dict(r) for r in rows]
@@ -400,7 +402,7 @@ class DatabaseManager:
(full_text, now, transcript_id), (full_text, now, transcript_id),
) )
conn.commit() conn.commit()
row = conn.execute("SELECT * FROM transcripts WHERE id = ?", (transcript_id, )).fetchone() row = conn.execute("SELECT * FROM transcripts WHERE id = ?", (transcript_id,)).fetchone()
conn.close() conn.close()
return dict(row) if row else None return dict(row) if row else None
@@ -453,7 +455,7 @@ class DatabaseManager:
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT * FROM entity_relations WHERE project_id = ? ORDER BY created_at DESC", "SELECT * FROM entity_relations WHERE project_id = ? ORDER BY created_at DESC",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
return [dict(r) for r in rows] return [dict(r) for r in rows]
@@ -475,13 +477,15 @@ class DatabaseManager:
conn.execute(query, values) conn.execute(query, values)
conn.commit() conn.commit()
row = conn.execute("SELECT * FROM entity_relations WHERE id = ?", (relation_id, )).fetchone() row = conn.execute(
"SELECT * FROM entity_relations WHERE id = ?", (relation_id,)
).fetchone()
conn.close() conn.close()
return dict(row) if row else None return dict(row) if row else None
def delete_relation(self, relation_id: str) -> None: def delete_relation(self, relation_id: str) -> None:
conn = self.get_conn() conn = self.get_conn()
conn.execute("DELETE FROM entity_relations WHERE id = ?", (relation_id, )) conn.execute("DELETE FROM entity_relations WHERE id = ?", (relation_id,))
conn.commit() conn.commit()
conn.close() conn.close()
@@ -495,7 +499,7 @@ class DatabaseManager:
if existing: if existing:
conn.execute( conn.execute(
"UPDATE glossary SET frequency = frequency + 1 WHERE id = ?", (existing["id"], ) "UPDATE glossary SET frequency = frequency + 1 WHERE id = ?", (existing["id"],)
) )
conn.commit() conn.commit()
conn.close() conn.close()
@@ -515,14 +519,14 @@ class DatabaseManager:
def list_glossary(self, project_id: str) -> list[dict]: def list_glossary(self, project_id: str) -> list[dict]:
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT * FROM glossary WHERE project_id = ? ORDER BY frequency DESC", (project_id, ) "SELECT * FROM glossary WHERE project_id = ? ORDER BY frequency DESC", (project_id,)
).fetchall() ).fetchall()
conn.close() conn.close()
return [dict(r) for r in rows] return [dict(r) for r in rows]
def delete_glossary_term(self, term_id: str) -> None: def delete_glossary_term(self, term_id: str) -> None:
conn = self.get_conn() conn = self.get_conn()
conn.execute("DELETE FROM glossary WHERE id = ?", (term_id, )) conn.execute("DELETE FROM glossary WHERE id = ?", (term_id,))
conn.commit() conn.commit()
conn.close() conn.close()
@@ -539,14 +543,14 @@ class DatabaseManager:
JOIN entities t ON r.target_entity_id = t.id JOIN entities t ON r.target_entity_id = t.id
LEFT JOIN transcripts tr ON r.transcript_id = tr.id LEFT JOIN transcripts tr ON r.transcript_id = tr.id
WHERE r.id = ?""", WHERE r.id = ?""",
(relation_id, ), (relation_id,),
).fetchone() ).fetchone()
conn.close() conn.close()
return dict(row) if row else None return dict(row) if row else None
def get_entity_with_mentions(self, entity_id: str) -> dict | None: def get_entity_with_mentions(self, entity_id: str) -> dict | None:
conn = self.get_conn() conn = self.get_conn()
entity_row = conn.execute("SELECT * FROM entities WHERE id = ?", (entity_id, )).fetchone() entity_row = conn.execute("SELECT * FROM entities WHERE id = ?", (entity_id,)).fetchone()
if not entity_row: if not entity_row:
conn.close() conn.close()
return None return None
@@ -559,7 +563,7 @@ class DatabaseManager:
FROM entity_mentions m FROM entity_mentions m
JOIN transcripts t ON m.transcript_id = t.id JOIN transcripts t ON m.transcript_id = t.id
WHERE m.entity_id = ? ORDER BY t.created_at, m.start_pos""", WHERE m.entity_id = ? ORDER BY t.created_at, m.start_pos""",
(entity_id, ), (entity_id,),
).fetchall() ).fetchall()
entity["mentions"] = [dict(m) for m in mentions] entity["mentions"] = [dict(m) for m in mentions]
entity["mention_count"] = len(mentions) entity["mention_count"] = len(mentions)
@@ -598,24 +602,24 @@ class DatabaseManager:
def get_project_summary(self, project_id: str) -> dict: def get_project_summary(self, project_id: str) -> dict:
conn = self.get_conn() conn = self.get_conn()
project = conn.execute("SELECT * FROM projects WHERE id = ?", (project_id, )).fetchone() project = conn.execute("SELECT * FROM projects WHERE id = ?", (project_id,)).fetchone()
entity_count = conn.execute( entity_count = conn.execute(
"SELECT COUNT(*) as count FROM entities WHERE project_id = ?", (project_id, ) "SELECT COUNT(*) as count FROM entities WHERE project_id = ?", (project_id,)
).fetchone()["count"] ).fetchone()["count"]
transcript_count = conn.execute( transcript_count = conn.execute(
"SELECT COUNT(*) as count FROM transcripts WHERE project_id = ?", (project_id, ) "SELECT COUNT(*) as count FROM transcripts WHERE project_id = ?", (project_id,)
).fetchone()["count"] ).fetchone()["count"]
relation_count = conn.execute( relation_count = conn.execute(
"SELECT COUNT(*) as count FROM entity_relations WHERE project_id = ?", (project_id, ) "SELECT COUNT(*) as count FROM entity_relations WHERE project_id = ?", (project_id,)
).fetchone()["count"] ).fetchone()["count"]
recent_transcripts = conn.execute( recent_transcripts = conn.execute(
"""SELECT filename, full_text, created_at FROM transcripts """SELECT filename, full_text, created_at FROM transcripts
WHERE project_id = ? ORDER BY created_at DESC LIMIT 5""", WHERE project_id = ? ORDER BY created_at DESC LIMIT 5""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
top_entities = conn.execute( top_entities = conn.execute(
@@ -624,7 +628,7 @@ class DatabaseManager:
LEFT JOIN entity_mentions m ON e.id = m.entity_id LEFT JOIN entity_mentions m ON e.id = m.entity_id
WHERE e.project_id = ? WHERE e.project_id = ?
GROUP BY e.id ORDER BY mention_count DESC LIMIT 10""", GROUP BY e.id ORDER BY mention_count DESC LIMIT 10""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -645,7 +649,7 @@ class DatabaseManager:
) -> str: ) -> str:
conn = self.get_conn() conn = self.get_conn()
row = conn.execute( row = conn.execute(
"SELECT full_text FROM transcripts WHERE id = ?", (transcript_id, ) "SELECT full_text FROM transcripts WHERE id = ?", (transcript_id,)
).fetchone() ).fetchone()
conn.close() conn.close()
if not row: if not row:
@@ -719,7 +723,7 @@ class DatabaseManager:
FROM entity_mentions m FROM entity_mentions m
JOIN transcripts t ON m.transcript_id = t.id JOIN transcripts t ON m.transcript_id = t.id
WHERE t.project_id = ? GROUP BY DATE(t.created_at) ORDER BY date""", WHERE t.project_id = ? GROUP BY DATE(t.created_at) ORDER BY date""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
entity_stats = conn.execute( entity_stats = conn.execute(
@@ -731,7 +735,7 @@ class DatabaseManager:
LEFT JOIN transcripts t ON m.transcript_id = t.id LEFT JOIN transcripts t ON m.transcript_id = t.id
WHERE e.project_id = ? WHERE e.project_id = ?
GROUP BY e.id ORDER BY mention_count DESC LIMIT 20""", GROUP BY e.id ORDER BY mention_count DESC LIMIT 20""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -772,7 +776,7 @@ class DatabaseManager:
def get_attribute_template(self, template_id: str) -> AttributeTemplate | None: def get_attribute_template(self, template_id: str) -> AttributeTemplate | None:
conn = self.get_conn() conn = self.get_conn()
row = conn.execute( row = conn.execute(
"SELECT * FROM attribute_templates WHERE id = ?", (template_id, ) "SELECT * FROM attribute_templates WHERE id = ?", (template_id,)
).fetchone() ).fetchone()
conn.close() conn.close()
if row: if row:
@@ -786,7 +790,7 @@ class DatabaseManager:
rows = conn.execute( rows = conn.execute(
"""SELECT * FROM attribute_templates WHERE project_id = ? """SELECT * FROM attribute_templates WHERE project_id = ?
ORDER BY sort_order, created_at""", ORDER BY sort_order, created_at""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -832,7 +836,7 @@ class DatabaseManager:
def delete_attribute_template(self, template_id: str) -> None: def delete_attribute_template(self, template_id: str) -> None:
conn = self.get_conn() conn = self.get_conn()
conn.execute("DELETE FROM attribute_templates WHERE id = ?", (template_id, )) conn.execute("DELETE FROM attribute_templates WHERE id = ?", (template_id,))
conn.commit() conn.commit()
conn.close() conn.close()
@@ -905,7 +909,7 @@ class DatabaseManager:
FROM entity_attributes ea FROM entity_attributes ea
LEFT JOIN attribute_templates at ON ea.template_id = at.id LEFT JOIN attribute_templates at ON ea.template_id = at.id
WHERE ea.entity_id = ? ORDER BY ea.created_at""", WHERE ea.entity_id = ? ORDER BY ea.created_at""",
(entity_id, ), (entity_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
return [EntityAttribute(**dict(r)) for r in rows] return [EntityAttribute(**dict(r)) for r in rows]
@@ -1075,7 +1079,7 @@ class DatabaseManager:
def get_video(self, video_id: str) -> dict | None: def get_video(self, video_id: str) -> dict | None:
"""获取视频信息""" """获取视频信息"""
conn = self.get_conn() conn = self.get_conn()
row = conn.execute("SELECT * FROM videos WHERE id = ?", (video_id, )).fetchone() row = conn.execute("SELECT * FROM videos WHERE id = ?", (video_id,)).fetchone()
conn.close() conn.close()
if row: if row:
@@ -1094,7 +1098,7 @@ class DatabaseManager:
"""获取项目的所有视频""" """获取项目的所有视频"""
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT * FROM videos WHERE project_id = ? ORDER BY created_at DESC", (project_id, ) "SELECT * FROM videos WHERE project_id = ? ORDER BY created_at DESC", (project_id,)
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -1149,7 +1153,7 @@ class DatabaseManager:
"""获取视频的所有帧""" """获取视频的所有帧"""
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"""SELECT * FROM video_frames WHERE video_id = ? ORDER BY timestamp""", (video_id, ) """SELECT * FROM video_frames WHERE video_id = ? ORDER BY timestamp""", (video_id,)
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -1201,7 +1205,7 @@ class DatabaseManager:
def get_image(self, image_id: str) -> dict | None: def get_image(self, image_id: str) -> dict | None:
"""获取图片信息""" """获取图片信息"""
conn = self.get_conn() conn = self.get_conn()
row = conn.execute("SELECT * FROM images WHERE id = ?", (image_id, )).fetchone() row = conn.execute("SELECT * FROM images WHERE id = ?", (image_id,)).fetchone()
conn.close() conn.close()
if row: if row:
@@ -1219,7 +1223,7 @@ class DatabaseManager:
"""获取项目的所有图片""" """获取项目的所有图片"""
conn = self.get_conn() conn = self.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT * FROM images WHERE project_id = ? ORDER BY created_at DESC", (project_id, ) "SELECT * FROM images WHERE project_id = ? ORDER BY created_at DESC", (project_id,)
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -1279,7 +1283,7 @@ class DatabaseManager:
FROM multimodal_mentions m FROM multimodal_mentions m
JOIN entities e ON m.entity_id = e.id JOIN entities e ON m.entity_id = e.id
WHERE m.entity_id = ? ORDER BY m.created_at DESC""", WHERE m.entity_id = ? ORDER BY m.created_at DESC""",
(entity_id, ), (entity_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
return [dict(r) for r in rows] return [dict(r) for r in rows]
@@ -1303,7 +1307,7 @@ class DatabaseManager:
FROM multimodal_mentions m FROM multimodal_mentions m
JOIN entities e ON m.entity_id = e.id JOIN entities e ON m.entity_id = e.id
WHERE m.project_id = ? ORDER BY m.created_at DESC""", WHERE m.project_id = ? ORDER BY m.created_at DESC""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -1377,13 +1381,13 @@ class DatabaseManager:
# 视频数量 # 视频数量
row = conn.execute( row = conn.execute(
"SELECT COUNT(*) as count FROM videos WHERE project_id = ?", (project_id, ) "SELECT COUNT(*) as count FROM videos WHERE project_id = ?", (project_id,)
).fetchone() ).fetchone()
stats["video_count"] = row["count"] stats["video_count"] = row["count"]
# 图片数量 # 图片数量
row = conn.execute( row = conn.execute(
"SELECT COUNT(*) as count FROM images WHERE project_id = ?", (project_id, ) "SELECT COUNT(*) as count FROM images WHERE project_id = ?", (project_id,)
).fetchone() ).fetchone()
stats["image_count"] = row["count"] stats["image_count"] = row["count"]
@@ -1391,7 +1395,7 @@ class DatabaseManager:
row = conn.execute( row = conn.execute(
"""SELECT COUNT(DISTINCT entity_id) as count """SELECT COUNT(DISTINCT entity_id) as count
FROM multimodal_mentions WHERE project_id = ?""", FROM multimodal_mentions WHERE project_id = ?""",
(project_id, ), (project_id,),
).fetchone() ).fetchone()
stats["multimodal_entity_count"] = row["count"] stats["multimodal_entity_count"] = row["count"]
@@ -1399,7 +1403,7 @@ class DatabaseManager:
row = conn.execute( row = conn.execute(
"""SELECT COUNT(*) as count FROM multimodal_entity_links """SELECT COUNT(*) as count FROM multimodal_entity_links
WHERE entity_id IN (SELECT id FROM entities WHERE project_id = ?)""", WHERE entity_id IN (SELECT id FROM entities WHERE project_id = ?)""",
(project_id, ), (project_id,),
).fetchone() ).fetchone()
stats["cross_modal_links"] = row["count"] stats["cross_modal_links"] = row["count"]

View File

@@ -444,7 +444,7 @@ class DeveloperEcosystemManager:
def get_sdk_release(self, sdk_id: str) -> SDKRelease | None: def get_sdk_release(self, sdk_id: str) -> SDKRelease | None:
"""获取 SDK 发布详情""" """获取 SDK 发布详情"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM sdk_releases WHERE id = ?", (sdk_id, )).fetchone() row = conn.execute("SELECT * FROM sdk_releases WHERE id = ?", (sdk_id,)).fetchone()
if row: if row:
return self._row_to_sdk_release(row) return self._row_to_sdk_release(row)
@@ -530,7 +530,7 @@ class DeveloperEcosystemManager:
SET download_count = download_count + 1 SET download_count = download_count + 1
WHERE id = ? WHERE id = ?
""", """,
(sdk_id, ), (sdk_id,),
) )
conn.commit() conn.commit()
@@ -538,7 +538,7 @@ class DeveloperEcosystemManager:
"""获取 SDK 版本历史""" """获取 SDK 版本历史"""
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM sdk_versions WHERE sdk_id = ? ORDER BY created_at DESC", (sdk_id, ) "SELECT * FROM sdk_versions WHERE sdk_id = ? ORDER BY created_at DESC", (sdk_id,)
).fetchall() ).fetchall()
return [self._row_to_sdk_version(row) for row in rows] return [self._row_to_sdk_version(row) for row in rows]
@@ -559,7 +559,7 @@ class DeveloperEcosystemManager:
with self._get_db() as conn: with self._get_db() as conn:
# 如果设置为最新版本,取消其他版本的最新标记 # 如果设置为最新版本,取消其他版本的最新标记
if True: # 默认新版本为最新 if True: # 默认新版本为最新
conn.execute("UPDATE sdk_versions SET is_latest = 0 WHERE sdk_id = ?", (sdk_id, )) conn.execute("UPDATE sdk_versions SET is_latest = 0 WHERE sdk_id = ?", (sdk_id,))
conn.execute( conn.execute(
""" """
@@ -700,7 +700,7 @@ class DeveloperEcosystemManager:
"""获取模板详情""" """获取模板详情"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM template_market WHERE id = ?", (template_id, ) "SELECT * FROM template_market WHERE id = ?", (template_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -814,7 +814,7 @@ class DeveloperEcosystemManager:
SET install_count = install_count + 1 SET install_count = install_count + 1
WHERE id = ? WHERE id = ?
""", """,
(template_id, ), (template_id,),
) )
conn.commit() conn.commit()
@@ -880,7 +880,7 @@ class DeveloperEcosystemManager:
FROM template_reviews FROM template_reviews
WHERE template_id = ? WHERE template_id = ?
""", """,
(template_id, ), (template_id,),
).fetchone() ).fetchone()
if row: if row:
@@ -1032,7 +1032,7 @@ class DeveloperEcosystemManager:
def get_plugin(self, plugin_id: str) -> PluginMarketItem | None: def get_plugin(self, plugin_id: str) -> PluginMarketItem | None:
"""获取插件详情""" """获取插件详情"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM plugin_market WHERE id = ?", (plugin_id, )).fetchone() row = conn.execute("SELECT * FROM plugin_market WHERE id = ?", (plugin_id,)).fetchone()
if row: if row:
return self._row_to_plugin(row) return self._row_to_plugin(row)
@@ -1120,7 +1120,7 @@ class DeveloperEcosystemManager:
SET install_count = install_count + 1 SET install_count = install_count + 1
WHERE id = ? WHERE id = ?
""", """,
(plugin_id, ), (plugin_id,),
) )
if active: if active:
@@ -1130,7 +1130,7 @@ class DeveloperEcosystemManager:
SET active_install_count = active_install_count + 1 SET active_install_count = active_install_count + 1
WHERE id = ? WHERE id = ?
""", """,
(plugin_id, ), (plugin_id,),
) )
conn.commit() conn.commit()
@@ -1195,7 +1195,7 @@ class DeveloperEcosystemManager:
FROM plugin_reviews FROM plugin_reviews
WHERE plugin_id = ? WHERE plugin_id = ?
""", """,
(plugin_id, ), (plugin_id,),
).fetchone() ).fetchone()
if row: if row:
@@ -1334,7 +1334,7 @@ class DeveloperEcosystemManager:
FROM developer_revenues FROM developer_revenues
WHERE developer_id = ? WHERE developer_id = ?
""", """,
(developer_id, ), (developer_id,),
).fetchone() ).fetchone()
return { return {
@@ -1420,7 +1420,7 @@ class DeveloperEcosystemManager:
"""获取开发者档案""" """获取开发者档案"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM developer_profiles WHERE id = ?", (developer_id, ) "SELECT * FROM developer_profiles WHERE id = ?", (developer_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -1431,7 +1431,7 @@ class DeveloperEcosystemManager:
"""通过用户 ID 获取开发者档案""" """通过用户 ID 获取开发者档案"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM developer_profiles WHERE user_id = ?", (user_id, ) "SELECT * FROM developer_profiles WHERE user_id = ?", (user_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -1469,12 +1469,13 @@ class DeveloperEcosystemManager:
with self._get_db() as conn: with self._get_db() as conn:
# 统计插件数量 # 统计插件数量
plugin_row = conn.execute( plugin_row = conn.execute(
"SELECT COUNT(*) as count FROM plugin_market WHERE author_id = ?", (developer_id, ) "SELECT COUNT(*) as count FROM plugin_market WHERE author_id = ?", (developer_id,)
).fetchone() ).fetchone()
# 统计模板数量 # 统计模板数量
template_row = conn.execute( template_row = conn.execute(
"SELECT COUNT(*) as count FROM template_market WHERE author_id = ?", (developer_id, ) "SELECT COUNT(*) as count FROM template_market WHERE author_id = ?",
(developer_id,),
).fetchone() ).fetchone()
# 统计总下载量 # 统计总下载量
@@ -1581,7 +1582,9 @@ class DeveloperEcosystemManager:
def get_code_example(self, example_id: str) -> CodeExample | None: def get_code_example(self, example_id: str) -> CodeExample | None:
"""获取代码示例""" """获取代码示例"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM code_examples WHERE id = ?", (example_id, )).fetchone() row = conn.execute(
"SELECT * FROM code_examples WHERE id = ?", (example_id,)
).fetchone()
if row: if row:
return self._row_to_code_example(row) return self._row_to_code_example(row)
@@ -1626,7 +1629,7 @@ class DeveloperEcosystemManager:
SET view_count = view_count + 1 SET view_count = view_count + 1
WHERE id = ? WHERE id = ?
""", """,
(example_id, ), (example_id,),
) )
conn.commit() conn.commit()
@@ -1639,7 +1642,7 @@ class DeveloperEcosystemManager:
SET copy_count = copy_count + 1 SET copy_count = copy_count + 1
WHERE id = ? WHERE id = ?
""", """,
(example_id, ), (example_id,),
) )
conn.commit() conn.commit()
@@ -1695,7 +1698,9 @@ class DeveloperEcosystemManager:
def get_api_documentation(self, doc_id: str) -> APIDocumentation | None: def get_api_documentation(self, doc_id: str) -> APIDocumentation | None:
"""获取 API 文档""" """获取 API 文档"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM api_documentation WHERE id = ?", (doc_id, )).fetchone() row = conn.execute(
"SELECT * FROM api_documentation WHERE id = ?", (doc_id,)
).fetchone()
if row: if row:
return self._row_to_api_documentation(row) return self._row_to_api_documentation(row)
@@ -1794,7 +1799,7 @@ class DeveloperEcosystemManager:
"""获取开发者门户配置""" """获取开发者门户配置"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM developer_portal_configs WHERE id = ?", (config_id, ) "SELECT * FROM developer_portal_configs WHERE id = ?", (config_id,)
).fetchone() ).fetchone()
if row: if row:

View File

@@ -688,7 +688,7 @@ class EnterpriseManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM sso_configs WHERE id = ?", (config_id, )) cursor.execute("SELECT * FROM sso_configs WHERE id = ?", (config_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -722,7 +722,7 @@ class EnterpriseManager:
WHERE tenant_id = ? AND status = 'active' WHERE tenant_id = ? AND status = 'active'
ORDER BY created_at DESC LIMIT 1 ORDER BY created_at DESC LIMIT 1
""", """,
(tenant_id, ), (tenant_id,),
) )
row = cursor.fetchone() row = cursor.fetchone()
@@ -802,7 +802,7 @@ class EnterpriseManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("DELETE FROM sso_configs WHERE id = ?", (config_id, )) cursor.execute("DELETE FROM sso_configs WHERE id = ?", (config_id,))
conn.commit() conn.commit()
return cursor.rowcount > 0 return cursor.rowcount > 0
finally: finally:
@@ -818,7 +818,7 @@ class EnterpriseManager:
SELECT * FROM sso_configs WHERE tenant_id = ? SELECT * FROM sso_configs WHERE tenant_id = ?
ORDER BY created_at DESC ORDER BY created_at DESC
""", """,
(tenant_id, ), (tenant_id,),
) )
rows = cursor.fetchall() rows = cursor.fetchall()
@@ -926,7 +926,7 @@ class EnterpriseManager:
""" """
SELECT * FROM saml_auth_requests WHERE request_id = ? SELECT * FROM saml_auth_requests WHERE request_id = ?
""", """,
(request_id, ), (request_id,),
) )
row = cursor.fetchone() row = cursor.fetchone()
@@ -1084,7 +1084,7 @@ class EnterpriseManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM scim_configs WHERE id = ?", (config_id, )) cursor.execute("SELECT * FROM scim_configs WHERE id = ?", (config_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -1104,7 +1104,7 @@ class EnterpriseManager:
SELECT * FROM scim_configs WHERE tenant_id = ? SELECT * FROM scim_configs WHERE tenant_id = ?
ORDER BY created_at DESC LIMIT 1 ORDER BY created_at DESC LIMIT 1
""", """,
(tenant_id, ), (tenant_id,),
) )
row = cursor.fetchone() row = cursor.fetchone()
@@ -1398,7 +1398,7 @@ class EnterpriseManager:
UPDATE audit_log_exports SET status = 'processing' UPDATE audit_log_exports SET status = 'processing'
WHERE id = ? WHERE id = ?
""", """,
(export_id, ), (export_id,),
) )
conn.commit() conn.commit()
@@ -1523,7 +1523,7 @@ class EnterpriseManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM audit_log_exports WHERE id = ?", (export_id, )) cursor.execute("SELECT * FROM audit_log_exports WHERE id = ?", (export_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -1661,7 +1661,7 @@ class EnterpriseManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM data_retention_policies WHERE id = ?", (policy_id, )) cursor.execute("SELECT * FROM data_retention_policies WHERE id = ?", (policy_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -1758,7 +1758,7 @@ class EnterpriseManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("DELETE FROM data_retention_policies WHERE id = ?", (policy_id, )) cursor.execute("DELETE FROM data_retention_policies WHERE id = ?", (policy_id,))
conn.commit() conn.commit()
return cursor.rowcount > 0 return cursor.rowcount > 0
finally: finally:
@@ -1887,7 +1887,7 @@ class EnterpriseManager:
SELECT COUNT(*) as count FROM audit_logs SELECT COUNT(*) as count FROM audit_logs
WHERE created_at < ? WHERE created_at < ?
""", """,
(cutoff_date, ), (cutoff_date,),
) )
count = cursor.fetchone()["count"] count = cursor.fetchone()["count"]
@@ -1896,7 +1896,7 @@ class EnterpriseManager:
""" """
DELETE FROM audit_logs WHERE created_at < ? DELETE FROM audit_logs WHERE created_at < ?
""", """,
(cutoff_date, ), (cutoff_date,),
) )
deleted = cursor.rowcount deleted = cursor.rowcount
return {"affected": count, "archived": 0, "deleted": deleted, "errors": 0} return {"affected": count, "archived": 0, "deleted": deleted, "errors": 0}
@@ -1927,7 +1927,7 @@ class EnterpriseManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM data_retention_jobs WHERE id = ?", (job_id, )) cursor.execute("SELECT * FROM data_retention_jobs WHERE id = ?", (job_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:

View File

@@ -677,7 +677,9 @@ class GrowthManager:
) -> FunnelAnalysis | None: ) -> FunnelAnalysis | None:
"""分析漏斗转化率""" """分析漏斗转化率"""
with self._get_db() as conn: with self._get_db() as conn:
funnel_row = conn.execute("SELECT * FROM funnels WHERE id = ?", (funnel_id, )).fetchone() funnel_row = conn.execute(
"SELECT * FROM funnels WHERE id = ?", (funnel_id,)
).fetchone()
if not funnel_row: if not funnel_row:
return None return None
@@ -891,7 +893,7 @@ class GrowthManager:
"""获取实验详情""" """获取实验详情"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM experiments WHERE id = ?", (experiment_id, ) "SELECT * FROM experiments WHERE id = ?", (experiment_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -1246,7 +1248,7 @@ class GrowthManager:
"""获取邮件模板""" """获取邮件模板"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM email_templates WHERE id = ?", (template_id, ) "SELECT * FROM email_templates WHERE id = ?", (template_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -1452,7 +1454,7 @@ class GrowthManager:
"""发送整个营销活动""" """发送整个营销活动"""
with self._get_db() as conn: with self._get_db() as conn:
campaign_row = conn.execute( campaign_row = conn.execute(
"SELECT * FROM email_campaigns WHERE id = ?", (campaign_id, ) "SELECT * FROM email_campaigns WHERE id = ?", (campaign_id,)
).fetchone() ).fetchone()
if not campaign_row: if not campaign_row:
@@ -1573,7 +1575,8 @@ class GrowthManager:
"""触发自动化工作流""" """触发自动化工作流"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM automation_workflows WHERE id = ? AND is_active = 1", (workflow_id, ) "SELECT * FROM automation_workflows WHERE id = ? AND is_active = 1",
(workflow_id,),
).fetchone() ).fetchone()
if not row: if not row:
@@ -1592,7 +1595,7 @@ class GrowthManager:
# 更新执行计数 # 更新执行计数
conn.execute( conn.execute(
"UPDATE automation_workflows SET execution_count = execution_count + 1 WHERE id = ?", "UPDATE automation_workflows SET execution_count = execution_count + 1 WHERE id = ?",
(workflow_id, ), (workflow_id,),
) )
conn.commit() conn.commit()
@@ -1766,7 +1769,7 @@ class GrowthManager:
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT 1 FROM referrals WHERE referral_code = ?", (code, ) "SELECT 1 FROM referrals WHERE referral_code = ?", (code,)
).fetchone() ).fetchone()
if not row: if not row:
@@ -1776,7 +1779,7 @@ class GrowthManager:
"""获取推荐计划""" """获取推荐计划"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM referral_programs WHERE id = ?", (program_id, ) "SELECT * FROM referral_programs WHERE id = ?", (program_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -1811,7 +1814,7 @@ class GrowthManager:
def reward_referral(self, referral_id: str) -> bool: def reward_referral(self, referral_id: str) -> bool:
"""发放推荐奖励""" """发放推荐奖励"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM referrals WHERE id = ?", (referral_id, )).fetchone() row = conn.execute("SELECT * FROM referrals WHERE id = ?", (referral_id,)).fetchone()
if not row or row["status"] != ReferralStatus.CONVERTED.value: if not row or row["status"] != ReferralStatus.CONVERTED.value:
return False return False
@@ -1972,7 +1975,7 @@ class GrowthManager:
ORDER BY timestamp DESC ORDER BY timestamp DESC
LIMIT 20 LIMIT 20
""", """,
(tenant_id, ), (tenant_id,),
).fetchall() ).fetchall()
# 热门功能 # 热门功能

View File

@@ -1074,7 +1074,7 @@ class LocalizationManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM language_configs WHERE code = ?", (code, )) cursor.execute("SELECT * FROM language_configs WHERE code = ?", (code,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
return self._row_to_language_config(row) return self._row_to_language_config(row)
@@ -1100,7 +1100,7 @@ class LocalizationManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM data_centers WHERE id = ?", (dc_id, )) cursor.execute("SELECT * FROM data_centers WHERE id = ?", (dc_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
return self._row_to_data_center(row) return self._row_to_data_center(row)
@@ -1112,7 +1112,7 @@ class LocalizationManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM data_centers WHERE region_code = ?", (region_code, )) cursor.execute("SELECT * FROM data_centers WHERE region_code = ?", (region_code,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
return self._row_to_data_center(row) return self._row_to_data_center(row)
@@ -1146,7 +1146,7 @@ class LocalizationManager:
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute( cursor.execute(
"SELECT * FROM tenant_data_center_mappings WHERE tenant_id = ?", (tenant_id, ) "SELECT * FROM tenant_data_center_mappings WHERE tenant_id = ?", (tenant_id,)
) )
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -1166,7 +1166,7 @@ class LocalizationManager:
SELECT * FROM data_centers WHERE supported_regions LIKE ? AND status = 'active' SELECT * FROM data_centers WHERE supported_regions LIKE ? AND status = 'active'
ORDER BY priority LIMIT 1 ORDER BY priority LIMIT 1
""", """,
(f'%"{region_code}"%', ), (f'%"{region_code}"%',),
) )
row = cursor.fetchone() row = cursor.fetchone()
if not row: if not row:
@@ -1182,7 +1182,7 @@ class LocalizationManager:
""" """
SELECT * FROM data_centers WHERE id != ? AND status = 'active' ORDER BY priority LIMIT 1 SELECT * FROM data_centers WHERE id != ? AND status = 'active' ORDER BY priority LIMIT 1
""", """,
(primary_dc_id, ), (primary_dc_id,),
) )
secondary_row = cursor.fetchone() secondary_row = cursor.fetchone()
secondary_dc_id = secondary_row["id"] if secondary_row else None secondary_dc_id = secondary_row["id"] if secondary_row else None
@@ -1222,7 +1222,7 @@ class LocalizationManager:
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute( cursor.execute(
"SELECT * FROM localized_payment_methods WHERE provider = ?", (provider, ) "SELECT * FROM localized_payment_methods WHERE provider = ?", (provider,)
) )
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -1278,7 +1278,7 @@ class LocalizationManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM country_configs WHERE code = ?", (code, )) cursor.execute("SELECT * FROM country_configs WHERE code = ?", (code,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
return self._row_to_country_config(row) return self._row_to_country_config(row)
@@ -1408,7 +1408,7 @@ class LocalizationManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM localization_settings WHERE tenant_id = ?", (tenant_id, )) cursor.execute("SELECT * FROM localization_settings WHERE tenant_id = ?", (tenant_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
return self._row_to_localization_settings(row) return self._row_to_localization_settings(row)
@@ -1505,7 +1505,8 @@ class LocalizationManager:
params.append(tenant_id) params.append(tenant_id)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute( cursor.execute(
f"UPDATE localization_settings SET {', '.join(updates)} WHERE tenant_id = ?", params f"UPDATE localization_settings SET {', '.join(updates)} WHERE tenant_id = ?",
params,
) )
conn.commit() conn.commit()
return self.get_localization_settings(tenant_id) return self.get_localization_settings(tenant_id)

View File

@@ -1166,7 +1166,7 @@ async def create_manual_entity(
start_pos=entity.start_pos, start_pos=entity.start_pos,
end_pos=entity.end_pos, end_pos=entity.end_pos,
text_snippet=text[ text_snippet=text[
max(0, entity.start_pos - 20): min(len(text), entity.end_pos + 20) max(0, entity.start_pos - 20) : min(len(text), entity.end_pos + 20)
], ],
confidence=1.0, confidence=1.0,
) )
@@ -1408,7 +1408,7 @@ async def upload_audio(project_id: str, file: UploadFile = File(...), _=Depends(
start_pos=pos, start_pos=pos,
end_pos=pos + len(name), end_pos=pos + len(name),
text_snippet=full_text[ text_snippet=full_text[
max(0, pos - 20): min(len(full_text), pos + len(name) + 20) max(0, pos - 20) : min(len(full_text), pos + len(name) + 20)
], ],
confidence=1.0, confidence=1.0,
) )
@@ -1534,7 +1534,7 @@ async def upload_document(project_id: str, file: UploadFile = File(...), _=Depen
start_pos=pos, start_pos=pos,
end_pos=pos + len(name), end_pos=pos + len(name),
text_snippet=full_text[ text_snippet=full_text[
max(0, pos - 20): min(len(full_text), pos + len(name) + 20) max(0, pos - 20) : min(len(full_text), pos + len(name) + 20)
], ],
confidence=1.0, confidence=1.0,
) )

View File

@@ -549,7 +549,7 @@ class OpsManager:
def get_alert_rule(self, rule_id: str) -> AlertRule | None: def get_alert_rule(self, rule_id: str) -> AlertRule | None:
"""获取告警规则""" """获取告警规则"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM alert_rules WHERE id = ?", (rule_id, )).fetchone() row = conn.execute("SELECT * FROM alert_rules WHERE id = ?", (rule_id,)).fetchone()
if row: if row:
return self._row_to_alert_rule(row) return self._row_to_alert_rule(row)
@@ -616,7 +616,7 @@ class OpsManager:
def delete_alert_rule(self, rule_id: str) -> bool: def delete_alert_rule(self, rule_id: str) -> bool:
"""删除告警规则""" """删除告警规则"""
with self._get_db() as conn: with self._get_db() as conn:
conn.execute("DELETE FROM alert_rules WHERE id = ?", (rule_id, )) conn.execute("DELETE FROM alert_rules WHERE id = ?", (rule_id,))
conn.commit() conn.commit()
return conn.total_changes > 0 return conn.total_changes > 0
@@ -680,7 +680,7 @@ class OpsManager:
"""获取告警渠道""" """获取告警渠道"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM alert_channels WHERE id = ?", (channel_id, ) "SELECT * FROM alert_channels WHERE id = ?", (channel_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -692,7 +692,7 @@ class OpsManager:
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM alert_channels WHERE tenant_id = ? ORDER BY created_at DESC", "SELECT * FROM alert_channels WHERE tenant_id = ? ORDER BY created_at DESC",
(tenant_id, ), (tenant_id,),
).fetchall() ).fetchall()
return [self._row_to_alert_channel(row) for row in rows] return [self._row_to_alert_channel(row) for row in rows]
@@ -1220,7 +1220,7 @@ class OpsManager:
def get_alert(self, alert_id: str) -> Alert | None: def get_alert(self, alert_id: str) -> Alert | None:
"""获取告警详情""" """获取告警详情"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM alerts WHERE id = ?", (alert_id, )).fetchone() row = conn.execute("SELECT * FROM alerts WHERE id = ?", (alert_id,)).fetchone()
if row: if row:
return self._row_to_alert(row) return self._row_to_alert(row)
@@ -1294,7 +1294,7 @@ class OpsManager:
SET suppression_count = suppression_count + 1 SET suppression_count = suppression_count + 1
WHERE id = ? WHERE id = ?
""", """,
(alert_id, ), (alert_id,),
) )
conn.commit() conn.commit()
@@ -1304,7 +1304,7 @@ class OpsManager:
"""更新告警通知状态""" """更新告警通知状态"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT notification_sent FROM alerts WHERE id = ?", (alert_id, ) "SELECT notification_sent FROM alerts WHERE id = ?", (alert_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -1394,7 +1394,7 @@ class OpsManager:
"""检查告警是否被抑制""" """检查告警是否被抑制"""
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM alert_suppression_rules WHERE tenant_id = ?", (rule.tenant_id, ) "SELECT * FROM alert_suppression_rules WHERE tenant_id = ?", (rule.tenant_id,)
).fetchall() ).fetchall()
for row in rows: for row in rows:
@@ -1627,7 +1627,7 @@ class OpsManager:
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM capacity_plans WHERE tenant_id = ? ORDER BY created_at DESC", "SELECT * FROM capacity_plans WHERE tenant_id = ? ORDER BY created_at DESC",
(tenant_id, ), (tenant_id,),
).fetchall() ).fetchall()
return [self._row_to_capacity_plan(row) for row in rows] return [self._row_to_capacity_plan(row) for row in rows]
@@ -1704,7 +1704,7 @@ class OpsManager:
"""获取自动扩缩容策略""" """获取自动扩缩容策略"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM auto_scaling_policies WHERE id = ?", (policy_id, ) "SELECT * FROM auto_scaling_policies WHERE id = ?", (policy_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -1716,7 +1716,7 @@ class OpsManager:
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM auto_scaling_policies WHERE tenant_id = ? ORDER BY created_at DESC", "SELECT * FROM auto_scaling_policies WHERE tenant_id = ? ORDER BY created_at DESC",
(tenant_id, ), (tenant_id,),
).fetchall() ).fetchall()
return [self._row_to_auto_scaling_policy(row) for row in rows] return [self._row_to_auto_scaling_policy(row) for row in rows]
@@ -1818,7 +1818,7 @@ class OpsManager:
"""SELECT * FROM scaling_events """SELECT * FROM scaling_events
WHERE policy_id = ? WHERE policy_id = ?
ORDER BY started_at DESC LIMIT 1""", ORDER BY started_at DESC LIMIT 1""",
(policy_id, ), (policy_id,),
).fetchone() ).fetchone()
if row: if row:
@@ -1857,7 +1857,7 @@ class OpsManager:
def get_scaling_event(self, event_id: str) -> ScalingEvent | None: def get_scaling_event(self, event_id: str) -> ScalingEvent | None:
"""获取扩缩容事件""" """获取扩缩容事件"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM scaling_events WHERE id = ?", (event_id, )).fetchone() row = conn.execute("SELECT * FROM scaling_events WHERE id = ?", (event_id,)).fetchone()
if row: if row:
return self._row_to_scaling_event(row) return self._row_to_scaling_event(row)
@@ -1951,7 +1951,7 @@ class OpsManager:
def get_health_check(self, check_id: str) -> HealthCheck | None: def get_health_check(self, check_id: str) -> HealthCheck | None:
"""获取健康检查配置""" """获取健康检查配置"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM health_checks WHERE id = ?", (check_id, )).fetchone() row = conn.execute("SELECT * FROM health_checks WHERE id = ?", (check_id,)).fetchone()
if row: if row:
return self._row_to_health_check(row) return self._row_to_health_check(row)
@@ -1962,7 +1962,7 @@ class OpsManager:
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM health_checks WHERE tenant_id = ? ORDER BY created_at DESC", "SELECT * FROM health_checks WHERE tenant_id = ? ORDER BY created_at DESC",
(tenant_id, ), (tenant_id,),
).fetchall() ).fetchall()
return [self._row_to_health_check(row) for row in rows] return [self._row_to_health_check(row) for row in rows]
@@ -2153,7 +2153,7 @@ class OpsManager:
"""获取故障转移配置""" """获取故障转移配置"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM failover_configs WHERE id = ?", (config_id, ) "SELECT * FROM failover_configs WHERE id = ?", (config_id,)
).fetchone() ).fetchone()
if row: if row:
@@ -2165,7 +2165,7 @@ class OpsManager:
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM failover_configs WHERE tenant_id = ? ORDER BY created_at DESC", "SELECT * FROM failover_configs WHERE tenant_id = ? ORDER BY created_at DESC",
(tenant_id, ), (tenant_id,),
).fetchall() ).fetchall()
return [self._row_to_failover_config(row) for row in rows] return [self._row_to_failover_config(row) for row in rows]
@@ -2258,7 +2258,9 @@ class OpsManager:
def get_failover_event(self, event_id: str) -> FailoverEvent | None: def get_failover_event(self, event_id: str) -> FailoverEvent | None:
"""获取故障转移事件""" """获取故障转移事件"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM failover_events WHERE id = ?", (event_id, )).fetchone() row = conn.execute(
"SELECT * FROM failover_events WHERE id = ?", (event_id,)
).fetchone()
if row: if row:
return self._row_to_failover_event(row) return self._row_to_failover_event(row)
@@ -2344,7 +2346,7 @@ class OpsManager:
def get_backup_job(self, job_id: str) -> BackupJob | None: def get_backup_job(self, job_id: str) -> BackupJob | None:
"""获取备份任务""" """获取备份任务"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM backup_jobs WHERE id = ?", (job_id, )).fetchone() row = conn.execute("SELECT * FROM backup_jobs WHERE id = ?", (job_id,)).fetchone()
if row: if row:
return self._row_to_backup_job(row) return self._row_to_backup_job(row)
@@ -2355,7 +2357,7 @@ class OpsManager:
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM backup_jobs WHERE tenant_id = ? ORDER BY created_at DESC", "SELECT * FROM backup_jobs WHERE tenant_id = ? ORDER BY created_at DESC",
(tenant_id, ), (tenant_id,),
).fetchall() ).fetchall()
return [self._row_to_backup_job(row) for row in rows] return [self._row_to_backup_job(row) for row in rows]
@@ -2427,7 +2429,9 @@ class OpsManager:
def get_backup_record(self, record_id: str) -> BackupRecord | None: def get_backup_record(self, record_id: str) -> BackupRecord | None:
"""获取备份记录""" """获取备份记录"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute("SELECT * FROM backup_records WHERE id = ?", (record_id, )).fetchone() row = conn.execute(
"SELECT * FROM backup_records WHERE id = ?", (record_id,)
).fetchone()
if row: if row:
return self._row_to_backup_record(row) return self._row_to_backup_record(row)
@@ -2700,7 +2704,7 @@ class OpsManager:
with self._get_db() as conn: with self._get_db() as conn:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM idle_resources WHERE tenant_id = ? ORDER BY detected_at DESC", "SELECT * FROM idle_resources WHERE tenant_id = ? ORDER BY detected_at DESC",
(tenant_id, ), (tenant_id,),
).fetchall() ).fetchall()
return [self._row_to_idle_resource(row) for row in rows] return [self._row_to_idle_resource(row) for row in rows]
@@ -2814,7 +2818,7 @@ class OpsManager:
"""获取成本优化建议详情""" """获取成本优化建议详情"""
with self._get_db() as conn: with self._get_db() as conn:
row = conn.execute( row = conn.execute(
"SELECT * FROM cost_optimization_suggestions WHERE id = ?", (suggestion_id, ) "SELECT * FROM cost_optimization_suggestions WHERE id = ?", (suggestion_id,)
).fetchone() ).fetchone()
if row: if row:

View File

@@ -500,7 +500,7 @@ class CacheManager:
WHERE e.project_id = ? WHERE e.project_id = ?
ORDER BY mention_count DESC ORDER BY mention_count DESC
LIMIT 100""", LIMIT 100""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for entity in entities: for entity in entities:
@@ -517,7 +517,7 @@ class CacheManager:
JOIN entities e2 ON r.target_entity_id = e2.id JOIN entities e2 ON r.target_entity_id = e2.id
WHERE r.project_id = ? WHERE r.project_id = ?
LIMIT 200""", LIMIT 200""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for relation in relations: for relation in relations:
@@ -531,7 +531,7 @@ class CacheManager:
WHERE project_id = ? WHERE project_id = ?
ORDER BY created_at DESC ORDER BY created_at DESC
LIMIT 10""", LIMIT 10""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for transcript in transcripts: for transcript in transcripts:
@@ -548,11 +548,11 @@ class CacheManager:
# 预热项目知识库摘要 # 预热项目知识库摘要
entity_count = conn.execute( entity_count = conn.execute(
"SELECT COUNT(*) FROM entities WHERE project_id = ?", (project_id, ) "SELECT COUNT(*) FROM entities WHERE project_id = ?", (project_id,)
).fetchone()[0] ).fetchone()[0]
relation_count = conn.execute( relation_count = conn.execute(
"SELECT COUNT(*) FROM entity_relations WHERE project_id = ?", (project_id, ) "SELECT COUNT(*) FROM entity_relations WHERE project_id = ?", (project_id,)
).fetchone()[0] ).fetchone()[0]
summary = { summary = {
@@ -757,11 +757,11 @@ class DatabaseSharding:
source_conn.row_factory = sqlite3.Row source_conn.row_factory = sqlite3.Row
entities = source_conn.execute( entities = source_conn.execute(
"SELECT * FROM entities WHERE project_id = ?", (project_id, ) "SELECT * FROM entities WHERE project_id = ?", (project_id,)
).fetchall() ).fetchall()
relations = source_conn.execute( relations = source_conn.execute(
"SELECT * FROM entity_relations WHERE project_id = ?", (project_id, ) "SELECT * FROM entity_relations WHERE project_id = ?", (project_id,)
).fetchall() ).fetchall()
source_conn.close() source_conn.close()
@@ -794,8 +794,8 @@ class DatabaseSharding:
# 从源分片删除数据 # 从源分片删除数据
source_conn = sqlite3.connect(source_info.db_path) source_conn = sqlite3.connect(source_info.db_path)
source_conn.execute("DELETE FROM entities WHERE project_id = ?", (project_id, )) source_conn.execute("DELETE FROM entities WHERE project_id = ?", (project_id,))
source_conn.execute("DELETE FROM entity_relations WHERE project_id = ?", (project_id, )) source_conn.execute("DELETE FROM entity_relations WHERE project_id = ?", (project_id,))
source_conn.commit() source_conn.commit()
source_conn.close() source_conn.close()
@@ -1024,7 +1024,7 @@ class TaskQueue:
with self.task_lock: with self.task_lock:
self.tasks[task_id] = task self.tasks[task_id] = task
# 异步执行 # 异步执行
threading.Thread(target=self._execute_task, args=(task_id, ), daemon=True).start() threading.Thread(target=self._execute_task, args=(task_id,), daemon=True).start()
# 保存到数据库 # 保存到数据库
self._save_task(task) self._save_task(task)
@@ -1061,7 +1061,7 @@ class TaskQueue:
task.status = "retrying" task.status = "retrying"
# 延迟重试 # 延迟重试
threading.Timer( threading.Timer(
10 * task.retry_count, self._execute_task, args=(task_id, ) 10 * task.retry_count, self._execute_task, args=(task_id,)
).start() ).start()
else: else:
task.status = "failed" task.status = "failed"
@@ -1248,7 +1248,7 @@ class TaskQueue:
if not self.use_celery: if not self.use_celery:
with self.task_lock: with self.task_lock:
self.tasks[task_id] = task self.tasks[task_id] = task
threading.Thread(target=self._execute_task, args=(task_id, ), daemon=True).start() threading.Thread(target=self._execute_task, args=(task_id,), daemon=True).start()
self._update_task_status(task) self._update_task_status(task)
return True return True
@@ -1439,7 +1439,7 @@ class PerformanceMonitor:
FROM performance_metrics FROM performance_metrics
WHERE timestamp > datetime('now', ?) WHERE timestamp > datetime('now', ?)
""", """,
(f"-{hours} hours", ), (f"-{hours} hours",),
).fetchone() ).fetchone()
# 按类型统计 # 按类型统计
@@ -1454,7 +1454,7 @@ class PerformanceMonitor:
WHERE timestamp > datetime('now', ?) WHERE timestamp > datetime('now', ?)
GROUP BY metric_type GROUP BY metric_type
""", """,
(f"-{hours} hours", ), (f"-{hours} hours",),
).fetchall() ).fetchall()
# 按端点统计API # 按端点统计API
@@ -1472,7 +1472,7 @@ class PerformanceMonitor:
ORDER BY avg_duration DESC ORDER BY avg_duration DESC
LIMIT 20 LIMIT 20
""", """,
(f"-{hours} hours", ), (f"-{hours} hours",),
).fetchall() ).fetchall()
# 慢查询统计 # 慢查询统计
@@ -1597,7 +1597,7 @@ class PerformanceMonitor:
DELETE FROM performance_metrics DELETE FROM performance_metrics
WHERE timestamp < datetime('now', ?) WHERE timestamp < datetime('now', ?)
""", """,
(f"-{days} days", ), (f"-{days} days",),
) )
deleted = cursor.rowcount deleted = cursor.rowcount

View File

@@ -212,7 +212,7 @@ class PluginManager:
def get_plugin(self, plugin_id: str) -> Plugin | None: def get_plugin(self, plugin_id: str) -> Plugin | None:
"""获取插件""" """获取插件"""
conn = self.db.get_conn() conn = self.db.get_conn()
row = conn.execute("SELECT * FROM plugins WHERE id = ?", (plugin_id, )).fetchone() row = conn.execute("SELECT * FROM plugins WHERE id = ?", (plugin_id,)).fetchone()
conn.close() conn.close()
if row: if row:
@@ -283,10 +283,10 @@ class PluginManager:
conn = self.db.get_conn() conn = self.db.get_conn()
# 删除关联的配置 # 删除关联的配置
conn.execute("DELETE FROM plugin_configs WHERE plugin_id = ?", (plugin_id, )) conn.execute("DELETE FROM plugin_configs WHERE plugin_id = ?", (plugin_id,))
# 删除插件 # 删除插件
cursor = conn.execute("DELETE FROM plugins WHERE id = ?", (plugin_id, )) cursor = conn.execute("DELETE FROM plugins WHERE id = ?", (plugin_id,))
conn.commit() conn.commit()
conn.close() conn.close()
@@ -318,7 +318,8 @@ class PluginManager:
# 检查是否已存在 # 检查是否已存在
existing = conn.execute( existing = conn.execute(
"SELECT id FROM plugin_configs WHERE plugin_id = ? AND config_key = ?", (plugin_id, key) "SELECT id FROM plugin_configs WHERE plugin_id = ? AND config_key = ?",
(plugin_id, key),
).fetchone() ).fetchone()
if existing: if existing:
@@ -366,7 +367,7 @@ class PluginManager:
"""获取插件所有配置""" """获取插件所有配置"""
conn = self.db.get_conn() conn = self.db.get_conn()
rows = conn.execute( rows = conn.execute(
"SELECT config_key, config_value FROM plugin_configs WHERE plugin_id = ?", (plugin_id, ) "SELECT config_key, config_value FROM plugin_configs WHERE plugin_id = ?", (plugin_id,)
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -416,7 +417,9 @@ class ChromeExtensionHandler:
token_id = str(uuid.uuid4())[:UUID_LENGTH] token_id = str(uuid.uuid4())[:UUID_LENGTH]
# 生成随机令牌 # 生成随机令牌
raw_token = f"if_ext_{base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8').rstrip(' = ')}" raw_token = (
f"if_ext_{base64.urlsafe_b64encode(os.urandom(32)).decode('utf-8').rstrip(' = ')}"
)
# 哈希存储 # 哈希存储
token_hash = hashlib.sha256(raw_token.encode()).hexdigest() token_hash = hashlib.sha256(raw_token.encode()).hexdigest()
@@ -469,7 +472,7 @@ class ChromeExtensionHandler:
row = conn.execute( row = conn.execute(
"""SELECT * FROM chrome_extension_tokens """SELECT * FROM chrome_extension_tokens
WHERE token_hash = ? AND is_revoked = 0""", WHERE token_hash = ? AND is_revoked = 0""",
(token_hash, ), (token_hash,),
).fetchone() ).fetchone()
conn.close() conn.close()
@@ -509,7 +512,7 @@ class ChromeExtensionHandler:
"""撤销令牌""" """撤销令牌"""
conn = self.pm.db.get_conn() conn = self.pm.db.get_conn()
cursor = conn.execute( cursor = conn.execute(
"UPDATE chrome_extension_tokens SET is_revoked = 1 WHERE id = ?", (token_id, ) "UPDATE chrome_extension_tokens SET is_revoked = 1 WHERE id = ?", (token_id,)
) )
conn.commit() conn.commit()
conn.close() conn.close()
@@ -685,7 +688,7 @@ class BotHandler:
rows = conn.execute( rows = conn.execute(
"""SELECT * FROM bot_sessions """SELECT * FROM bot_sessions
WHERE bot_type = ? ORDER BY created_at DESC""", WHERE bot_type = ? ORDER BY created_at DESC""",
(self.bot_type, ), (self.bot_type,),
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -1015,7 +1018,7 @@ class WebhookIntegration:
rows = conn.execute( rows = conn.execute(
"""SELECT * FROM webhook_endpoints """SELECT * FROM webhook_endpoints
WHERE endpoint_type = ? ORDER BY created_at DESC""", WHERE endpoint_type = ? ORDER BY created_at DESC""",
(self.endpoint_type, ), (self.endpoint_type,),
).fetchall() ).fetchall()
conn.close() conn.close()
@@ -1064,7 +1067,7 @@ class WebhookIntegration:
def delete_endpoint(self, endpoint_id: str) -> bool: def delete_endpoint(self, endpoint_id: str) -> bool:
"""删除端点""" """删除端点"""
conn = self.pm.db.get_conn() conn = self.pm.db.get_conn()
cursor = conn.execute("DELETE FROM webhook_endpoints WHERE id = ?", (endpoint_id, )) cursor = conn.execute("DELETE FROM webhook_endpoints WHERE id = ?", (endpoint_id,))
conn.commit() conn.commit()
conn.close() conn.close()
@@ -1219,7 +1222,7 @@ class WebDAVSyncManager:
def get_sync(self, sync_id: str) -> WebDAVSync | None: def get_sync(self, sync_id: str) -> WebDAVSync | None:
"""获取同步配置""" """获取同步配置"""
conn = self.pm.db.get_conn() conn = self.pm.db.get_conn()
row = conn.execute("SELECT * FROM webdav_syncs WHERE id = ?", (sync_id, )).fetchone() row = conn.execute("SELECT * FROM webdav_syncs WHERE id = ?", (sync_id,)).fetchone()
conn.close() conn.close()
if row: if row:
@@ -1233,7 +1236,7 @@ class WebDAVSyncManager:
if project_id: if project_id:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM webdav_syncs WHERE project_id = ? ORDER BY created_at DESC", "SELECT * FROM webdav_syncs WHERE project_id = ? ORDER BY created_at DESC",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
else: else:
rows = conn.execute("SELECT * FROM webdav_syncs ORDER BY created_at DESC").fetchall() rows = conn.execute("SELECT * FROM webdav_syncs ORDER BY created_at DESC").fetchall()
@@ -1282,7 +1285,7 @@ class WebDAVSyncManager:
def delete_sync(self, sync_id: str) -> bool: def delete_sync(self, sync_id: str) -> bool:
"""删除同步配置""" """删除同步配置"""
conn = self.pm.db.get_conn() conn = self.pm.db.get_conn()
cursor = conn.execute("DELETE FROM webdav_syncs WHERE id = ?", (sync_id, )) cursor = conn.execute("DELETE FROM webdav_syncs WHERE id = ?", (sync_id,))
conn.commit() conn.commit()
conn.close() conn.close()

View File

@@ -385,7 +385,7 @@ class FullTextSearch:
# 排序和分页 # 排序和分页
scored_results.sort(key=lambda x: x.score, reverse=True) scored_results.sort(key=lambda x: x.score, reverse=True)
return scored_results[offset: offset + limit] return scored_results[offset : offset + limit]
def _parse_boolean_query(self, query: str) -> dict: def _parse_boolean_query(self, query: str) -> dict:
""" """
@@ -551,13 +551,13 @@ class FullTextSearch:
try: try:
if content_type == "transcript": if content_type == "transcript":
row = conn.execute( row = conn.execute(
"SELECT full_text FROM transcripts WHERE id = ?", (content_id, ) "SELECT full_text FROM transcripts WHERE id = ?", (content_id,)
).fetchone() ).fetchone()
return row["full_text"] if row else None return row["full_text"] if row else None
elif content_type == "entity": elif content_type == "entity":
row = conn.execute( row = conn.execute(
"SELECT name, definition FROM entities WHERE id = ?", (content_id, ) "SELECT name, definition FROM entities WHERE id = ?", (content_id,)
).fetchone() ).fetchone()
if row: if row:
return f"{row['name']} {row['definition'] or ''}" return f"{row['name']} {row['definition'] or ''}"
@@ -571,7 +571,7 @@ class FullTextSearch:
JOIN entities e1 ON r.source_entity_id = e1.id JOIN entities e1 ON r.source_entity_id = e1.id
JOIN entities e2 ON r.target_entity_id = e2.id JOIN entities e2 ON r.target_entity_id = e2.id
WHERE r.id = ?""", WHERE r.id = ?""",
(content_id, ), (content_id,),
).fetchone() ).fetchone()
if row: if row:
return f"{row['source_name']} {row['relation_type']} {row['target_name']} {row['evidence'] or ''}" return f"{row['source_name']} {row['relation_type']} {row['target_name']} {row['evidence'] or ''}"
@@ -589,15 +589,15 @@ class FullTextSearch:
try: try:
if content_type == "transcript": if content_type == "transcript":
row = conn.execute( row = conn.execute(
"SELECT project_id FROM transcripts WHERE id = ?", (content_id, ) "SELECT project_id FROM transcripts WHERE id = ?", (content_id,)
).fetchone() ).fetchone()
elif content_type == "entity": elif content_type == "entity":
row = conn.execute( row = conn.execute(
"SELECT project_id FROM entities WHERE id = ?", (content_id, ) "SELECT project_id FROM entities WHERE id = ?", (content_id,)
).fetchone() ).fetchone()
elif content_type == "relation": elif content_type == "relation":
row = conn.execute( row = conn.execute(
"SELECT project_id FROM entity_relations WHERE id = ?", (content_id, ) "SELECT project_id FROM entity_relations WHERE id = ?", (content_id,)
).fetchone() ).fetchone()
else: else:
return None return None
@@ -738,7 +738,7 @@ class FullTextSearch:
# 索引转录文本 # 索引转录文本
transcripts = conn.execute( transcripts = conn.execute(
"SELECT id, project_id, full_text FROM transcripts WHERE project_id = ?", "SELECT id, project_id, full_text FROM transcripts WHERE project_id = ?",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for t in transcripts: for t in transcripts:
@@ -751,7 +751,7 @@ class FullTextSearch:
# 索引实体 # 索引实体
entities = conn.execute( entities = conn.execute(
"SELECT id, project_id, name, definition FROM entities WHERE project_id = ?", "SELECT id, project_id, name, definition FROM entities WHERE project_id = ?",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for e in entities: for e in entities:
@@ -769,7 +769,7 @@ class FullTextSearch:
JOIN entities e1 ON r.source_entity_id = e1.id JOIN entities e1 ON r.source_entity_id = e1.id
JOIN entities e2 ON r.target_entity_id = e2.id JOIN entities e2 ON r.target_entity_id = e2.id
WHERE r.project_id = ?""", WHERE r.project_id = ?""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for r in relations: for r in relations:
@@ -1029,13 +1029,13 @@ class SemanticSearch:
try: try:
if content_type == "transcript": if content_type == "transcript":
row = conn.execute( row = conn.execute(
"SELECT full_text FROM transcripts WHERE id = ?", (content_id, ) "SELECT full_text FROM transcripts WHERE id = ?", (content_id,)
).fetchone() ).fetchone()
result = row["full_text"] if row else None result = row["full_text"] if row else None
elif content_type == "entity": elif content_type == "entity":
row = conn.execute( row = conn.execute(
"SELECT name, definition FROM entities WHERE id = ?", (content_id, ) "SELECT name, definition FROM entities WHERE id = ?", (content_id,)
).fetchone() ).fetchone()
result = f"{row['name']}: {row['definition']}" if row else None result = f"{row['name']}: {row['definition']}" if row else None
@@ -1047,7 +1047,7 @@ class SemanticSearch:
JOIN entities e1 ON r.source_entity_id = e1.id JOIN entities e1 ON r.source_entity_id = e1.id
JOIN entities e2 ON r.target_entity_id = e2.id JOIN entities e2 ON r.target_entity_id = e2.id
WHERE r.id = ?""", WHERE r.id = ?""",
(content_id, ), (content_id,),
).fetchone() ).fetchone()
result = ( result = (
f"{row['source_name']} {row['relation_type']} {row['target_name']}" f"{row['source_name']} {row['relation_type']} {row['target_name']}"
@@ -1192,7 +1192,7 @@ class EntityPathDiscovery:
# 获取项目ID # 获取项目ID
row = conn.execute( row = conn.execute(
"SELECT project_id FROM entities WHERE id = ?", (source_entity_id, ) "SELECT project_id FROM entities WHERE id = ?", (source_entity_id,)
).fetchone() ).fetchone()
if not row: if not row:
@@ -1203,7 +1203,8 @@ class EntityPathDiscovery:
# 验证目标实体也在同一项目 # 验证目标实体也在同一项目
row = conn.execute( row = conn.execute(
"SELECT 1 FROM entities WHERE id = ? AND project_id = ?", (target_entity_id, project_id) "SELECT 1 FROM entities WHERE id = ? AND project_id = ?",
(target_entity_id, project_id),
).fetchone() ).fetchone()
if not row: if not row:
@@ -1267,7 +1268,7 @@ class EntityPathDiscovery:
# 获取项目ID # 获取项目ID
row = conn.execute( row = conn.execute(
"SELECT project_id FROM entities WHERE id = ?", (source_entity_id, ) "SELECT project_id FROM entities WHERE id = ?", (source_entity_id,)
).fetchone() ).fetchone()
if not row: if not row:
@@ -1278,7 +1279,9 @@ class EntityPathDiscovery:
paths = [] paths = []
def dfs(current_id: str, target_id: str, path: list[str], visited: set[str], depth: int) -> None: def dfs(
current_id: str, target_id: str, path: list[str], visited: set[str], depth: int
) -> None:
if depth > max_depth: if depth > max_depth:
return return
@@ -1325,7 +1328,7 @@ class EntityPathDiscovery:
nodes = [] nodes = []
for entity_id in entity_ids: for entity_id in entity_ids:
row = conn.execute( row = conn.execute(
"SELECT id, name, type FROM entities WHERE id = ?", (entity_id, ) "SELECT id, name, type FROM entities WHERE id = ?", (entity_id,)
).fetchone() ).fetchone()
if row: if row:
nodes.append({"id": row["id"], "name": row["name"], "type": row["type"]}) nodes.append({"id": row["id"], "name": row["name"], "type": row["type"]})
@@ -1395,7 +1398,7 @@ class EntityPathDiscovery:
# 获取项目ID # 获取项目ID
row = conn.execute( row = conn.execute(
"SELECT project_id, name FROM entities WHERE id = ?", (entity_id, ) "SELECT project_id, name FROM entities WHERE id = ?", (entity_id,)
).fetchone() ).fetchone()
if not row: if not row:
@@ -1442,7 +1445,7 @@ class EntityPathDiscovery:
# 获取邻居信息 # 获取邻居信息
neighbor_info = conn.execute( neighbor_info = conn.execute(
"SELECT name, type FROM entities WHERE id = ?", (neighbor_id, ) "SELECT name, type FROM entities WHERE id = ?", (neighbor_id,)
).fetchone() ).fetchone()
if neighbor_info: if neighbor_info:
@@ -1562,7 +1565,7 @@ class EntityPathDiscovery:
# 获取所有实体 # 获取所有实体
entities = conn.execute( entities = conn.execute(
"SELECT id, name FROM entities WHERE project_id = ?", (project_id, ) "SELECT id, name FROM entities WHERE project_id = ?", (project_id,)
).fetchall() ).fetchall()
# 计算每个实体作为桥梁的次数 # 计算每个实体作为桥梁的次数
@@ -1688,7 +1691,7 @@ class KnowledgeGapDetection:
# 获取项目的属性模板 # 获取项目的属性模板
templates = conn.execute( templates = conn.execute(
"SELECT id, name, type, is_required FROM attribute_templates WHERE project_id = ?", "SELECT id, name, type, is_required FROM attribute_templates WHERE project_id = ?",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
if not templates: if not templates:
@@ -1703,7 +1706,7 @@ class KnowledgeGapDetection:
# 检查每个实体的属性完整性 # 检查每个实体的属性完整性
entities = conn.execute( entities = conn.execute(
"SELECT id, name FROM entities WHERE project_id = ?", (project_id, ) "SELECT id, name FROM entities WHERE project_id = ?", (project_id,)
).fetchall() ).fetchall()
for entity in entities: for entity in entities:
@@ -1711,7 +1714,7 @@ class KnowledgeGapDetection:
# 获取实体已有的属性 # 获取实体已有的属性
existing_attrs = conn.execute( existing_attrs = conn.execute(
"SELECT template_id FROM entity_attributes WHERE entity_id = ?", (entity_id, ) "SELECT template_id FROM entity_attributes WHERE entity_id = ?", (entity_id,)
).fetchall() ).fetchall()
existing_template_ids = {a["template_id"] for a in existing_attrs} existing_template_ids = {a["template_id"] for a in existing_attrs}
@@ -1723,7 +1726,7 @@ class KnowledgeGapDetection:
missing_names = [] missing_names = []
for template_id in missing_templates: for template_id in missing_templates:
template = conn.execute( template = conn.execute(
"SELECT name FROM attribute_templates WHERE id = ?", (template_id, ) "SELECT name FROM attribute_templates WHERE id = ?", (template_id,)
).fetchone() ).fetchone()
if template: if template:
missing_names.append(template["name"]) missing_names.append(template["name"])
@@ -1756,7 +1759,7 @@ class KnowledgeGapDetection:
# 获取所有实体及其关系数量 # 获取所有实体及其关系数量
entities = conn.execute( entities = conn.execute(
"SELECT id, name, type FROM entities WHERE project_id = ?", (project_id, ) "SELECT id, name, type FROM entities WHERE project_id = ?", (project_id,)
).fetchall() ).fetchall()
for entity in entities: for entity in entities:
@@ -1831,7 +1834,7 @@ class KnowledgeGapDetection:
AND r1.id IS NULL AND r1.id IS NULL
AND r2.id IS NULL AND r2.id IS NULL
""", """,
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for entity in isolated: for entity in isolated:
@@ -1869,7 +1872,7 @@ class KnowledgeGapDetection:
WHERE project_id = ? WHERE project_id = ?
AND (definition IS NULL OR definition = '') AND (definition IS NULL OR definition = '')
""", """,
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for entity in incomplete: for entity in incomplete:
@@ -1897,7 +1900,7 @@ class KnowledgeGapDetection:
# 分析转录文本中频繁提及但未提取为实体的词 # 分析转录文本中频繁提及但未提取为实体的词
transcripts = conn.execute( transcripts = conn.execute(
"SELECT full_text FROM transcripts WHERE project_id = ?", (project_id, ) "SELECT full_text FROM transcripts WHERE project_id = ?", (project_id,)
).fetchall() ).fetchall()
# 合并所有文本 # 合并所有文本
@@ -1905,7 +1908,7 @@ class KnowledgeGapDetection:
# 获取现有实体名称 # 获取现有实体名称
existing_entities = conn.execute( existing_entities = conn.execute(
"SELECT name FROM entities WHERE project_id = ?", (project_id, ) "SELECT name FROM entities WHERE project_id = ?", (project_id,)
).fetchall() ).fetchall()
existing_names = {e["name"].lower() for e in existing_entities} existing_names = {e["name"].lower() for e in existing_entities}
@@ -2138,7 +2141,7 @@ class SearchManager:
# 索引转录文本 # 索引转录文本
transcripts = conn.execute( transcripts = conn.execute(
"SELECT id, project_id, full_text FROM transcripts WHERE project_id = ?", "SELECT id, project_id, full_text FROM transcripts WHERE project_id = ?",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for t in transcripts: for t in transcripts:
@@ -2152,7 +2155,7 @@ class SearchManager:
# 索引实体 # 索引实体
entities = conn.execute( entities = conn.execute(
"SELECT id, project_id, name, definition FROM entities WHERE project_id = ?", "SELECT id, project_id, name, definition FROM entities WHERE project_id = ?",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
for e in entities: for e in entities:
@@ -2191,7 +2194,7 @@ class SearchManager:
"""SELECT content_type, COUNT(*) as count """SELECT content_type, COUNT(*) as count
FROM search_indexes WHERE project_id = ? FROM search_indexes WHERE project_id = ?
GROUP BY content_type""", GROUP BY content_type""",
(project_id, ), (project_id,),
).fetchall() ).fetchall()
type_stats = {r["content_type"]: r["count"] for r in rows} type_stats = {r["content_type"]: r["count"] for r in rows}

View File

@@ -546,7 +546,7 @@ class SecurityManager:
cursor = conn.cursor() cursor = conn.cursor()
# 检查是否已存在配置 # 检查是否已存在配置
cursor.execute("SELECT id FROM encryption_configs WHERE project_id = ?", (project_id, )) cursor.execute("SELECT id FROM encryption_configs WHERE project_id = ?", (project_id,))
existing = cursor.fetchone() existing = cursor.fetchone()
if existing: if existing:
@@ -641,7 +641,7 @@ class SecurityManager:
cursor.execute( cursor.execute(
"SELECT master_key_hash, salt FROM encryption_configs WHERE project_id = ?", "SELECT master_key_hash, salt FROM encryption_configs WHERE project_id = ?",
(project_id, ), (project_id,),
) )
row = cursor.fetchone() row = cursor.fetchone()
conn.close() conn.close()
@@ -660,7 +660,7 @@ class SecurityManager:
conn = sqlite3.connect(self.db_path) conn = sqlite3.connect(self.db_path)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM encryption_configs WHERE project_id = ?", (project_id, )) cursor.execute("SELECT * FROM encryption_configs WHERE project_id = ?", (project_id,))
row = cursor.fetchone() row = cursor.fetchone()
conn.close() conn.close()
@@ -847,7 +847,7 @@ class SecurityManager:
# 获取更新后的规则 # 获取更新后的规则
conn = sqlite3.connect(self.db_path) conn = sqlite3.connect(self.db_path)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM masking_rules WHERE id = ?", (rule_id, )) cursor.execute("SELECT * FROM masking_rules WHERE id = ?", (rule_id,))
row = cursor.fetchone() row = cursor.fetchone()
conn.close() conn.close()
@@ -873,7 +873,7 @@ class SecurityManager:
conn = sqlite3.connect(self.db_path) conn = sqlite3.connect(self.db_path)
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("DELETE FROM masking_rules WHERE id = ?", (rule_id, )) cursor.execute("DELETE FROM masking_rules WHERE id = ?", (rule_id,))
success = cursor.rowcount > 0 success = cursor.rowcount > 0
conn.commit() conn.commit()
@@ -1028,7 +1028,7 @@ class SecurityManager:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute( cursor.execute(
"SELECT * FROM data_access_policies WHERE id = ? AND is_active = 1", (policy_id, ) "SELECT * FROM data_access_policies WHERE id = ? AND is_active = 1", (policy_id,)
) )
row = cursor.fetchone() row = cursor.fetchone()
conn.close() conn.close()
@@ -1184,7 +1184,7 @@ class SecurityManager:
conn.commit() conn.commit()
# 获取更新后的请求 # 获取更新后的请求
cursor.execute("SELECT * FROM access_requests WHERE id = ?", (request_id, )) cursor.execute("SELECT * FROM access_requests WHERE id = ?", (request_id,))
row = cursor.fetchone() row = cursor.fetchone()
conn.close() conn.close()
@@ -1219,7 +1219,7 @@ class SecurityManager:
conn.commit() conn.commit()
cursor.execute("SELECT * FROM access_requests WHERE id = ?", (request_id, )) cursor.execute("SELECT * FROM access_requests WHERE id = ?", (request_id,))
row = cursor.fetchone() row = cursor.fetchone()
conn.close() conn.close()

View File

@@ -572,7 +572,7 @@ class SubscriptionManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM subscription_plans WHERE id = ?", (plan_id, )) cursor.execute("SELECT * FROM subscription_plans WHERE id = ?", (plan_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -588,7 +588,7 @@ class SubscriptionManager:
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute( cursor.execute(
"SELECT * FROM subscription_plans WHERE tier = ? AND is_active = 1", (tier, ) "SELECT * FROM subscription_plans WHERE tier = ? AND is_active = 1", (tier,)
) )
row = cursor.fetchone() row = cursor.fetchone()
@@ -760,7 +760,7 @@ class SubscriptionManager:
SELECT * FROM subscriptions SELECT * FROM subscriptions
WHERE tenant_id = ? AND status IN ('active', 'trial', 'pending') WHERE tenant_id = ? AND status IN ('active', 'trial', 'pending')
""", """,
(tenant_id, ), (tenant_id,),
) )
existing = cursor.fetchone() existing = cursor.fetchone()
@@ -878,7 +878,7 @@ class SubscriptionManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM subscriptions WHERE id = ?", (subscription_id, )) cursor.execute("SELECT * FROM subscriptions WHERE id = ?", (subscription_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -899,7 +899,7 @@ class SubscriptionManager:
WHERE tenant_id = ? AND status IN ('active', 'trial', 'past_due', 'pending') WHERE tenant_id = ? AND status IN ('active', 'trial', 'past_due', 'pending')
ORDER BY created_at DESC LIMIT 1 ORDER BY created_at DESC LIMIT 1
""", """,
(tenant_id, ), (tenant_id,),
) )
row = cursor.fetchone() row = cursor.fetchone()
@@ -1389,7 +1389,7 @@ class SubscriptionManager:
def _get_payment_internal(self, conn: sqlite3.Connection, payment_id: str) -> Payment | None: def _get_payment_internal(self, conn: sqlite3.Connection, payment_id: str) -> Payment | None:
"""内部方法:获取支付记录""" """内部方法:获取支付记录"""
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM payments WHERE id = ?", (payment_id, )) cursor.execute("SELECT * FROM payments WHERE id = ?", (payment_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -1475,7 +1475,7 @@ class SubscriptionManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM invoices WHERE id = ?", (invoice_id, )) cursor.execute("SELECT * FROM invoices WHERE id = ?", (invoice_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -1490,7 +1490,7 @@ class SubscriptionManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM invoices WHERE invoice_number = ?", (invoice_number, )) cursor.execute("SELECT * FROM invoices WHERE invoice_number = ?", (invoice_number,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -1568,7 +1568,7 @@ class SubscriptionManager:
SELECT COUNT(*) as count FROM invoices SELECT COUNT(*) as count FROM invoices
WHERE invoice_number LIKE ? WHERE invoice_number LIKE ?
""", """,
(f"{prefix}%", ), (f"{prefix}%",),
) )
row = cursor.fetchone() row = cursor.fetchone()
count = row["count"] + 1 count = row["count"] + 1
@@ -1803,7 +1803,7 @@ class SubscriptionManager:
def _get_refund_internal(self, conn: sqlite3.Connection, refund_id: str) -> Refund | None: def _get_refund_internal(self, conn: sqlite3.Connection, refund_id: str) -> Refund | None:
"""内部方法:获取退款记录""" """内部方法:获取退款记录"""
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM refunds WHERE id = ?", (refund_id, )) cursor.execute("SELECT * FROM refunds WHERE id = ?", (refund_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:

View File

@@ -495,7 +495,7 @@ class TenantManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM tenants WHERE id = ?", (tenant_id, )) cursor.execute("SELECT * FROM tenants WHERE id = ?", (tenant_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -510,7 +510,7 @@ class TenantManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM tenants WHERE slug = ?", (slug, )) cursor.execute("SELECT * FROM tenants WHERE slug = ?", (slug,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -531,7 +531,7 @@ class TenantManager:
JOIN tenant_domains d ON t.id = d.tenant_id JOIN tenant_domains d ON t.id = d.tenant_id
WHERE d.domain = ? AND d.status = 'verified' WHERE d.domain = ? AND d.status = 'verified'
""", """,
(domain, ), (domain,),
) )
row = cursor.fetchone() row = cursor.fetchone()
@@ -605,7 +605,7 @@ class TenantManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("DELETE FROM tenants WHERE id = ?", (tenant_id, )) cursor.execute("DELETE FROM tenants WHERE id = ?", (tenant_id,))
conn.commit() conn.commit()
return cursor.rowcount > 0 return cursor.rowcount > 0
finally: finally:
@@ -684,7 +684,7 @@ class TenantManager:
UPDATE tenant_domains SET is_primary = 0 UPDATE tenant_domains SET is_primary = 0
WHERE tenant_id = ? WHERE tenant_id = ?
""", """,
(tenant_id, ), (tenant_id,),
) )
cursor.execute( cursor.execute(
@@ -782,7 +782,7 @@ class TenantManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM tenant_domains WHERE id = ?", (domain_id, )) cursor.execute("SELECT * FROM tenant_domains WHERE id = ?", (domain_id,))
row = cursor.fetchone() row = cursor.fetchone()
if not row: if not row:
@@ -841,7 +841,7 @@ class TenantManager:
WHERE tenant_id = ? WHERE tenant_id = ?
ORDER BY is_primary DESC, created_at DESC ORDER BY is_primary DESC, created_at DESC
""", """,
(tenant_id, ), (tenant_id,),
) )
rows = cursor.fetchall() rows = cursor.fetchall()
@@ -857,7 +857,7 @@ class TenantManager:
conn = self._get_connection() conn = self._get_connection()
try: try:
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute("SELECT * FROM tenant_branding WHERE tenant_id = ?", (tenant_id, )) cursor.execute("SELECT * FROM tenant_branding WHERE tenant_id = ?", (tenant_id,))
row = cursor.fetchone() row = cursor.fetchone()
if row: if row:
@@ -885,7 +885,7 @@ class TenantManager:
cursor = conn.cursor() cursor = conn.cursor()
# 检查是否已存在 # 检查是否已存在
cursor.execute("SELECT id FROM tenant_branding WHERE tenant_id = ?", (tenant_id, )) cursor.execute("SELECT id FROM tenant_branding WHERE tenant_id = ?", (tenant_id,))
existing = cursor.fetchone() existing = cursor.fetchone()
if existing: if existing:
@@ -1197,7 +1197,7 @@ class TenantManager:
WHERE m.user_id = ? AND m.status = 'active' WHERE m.user_id = ? AND m.status = 'active'
ORDER BY t.created_at DESC ORDER BY t.created_at DESC
""", """,
(user_id, ), (user_id,),
) )
rows = cursor.fetchall() rows = cursor.fetchall()
@@ -1388,7 +1388,7 @@ class TenantManager:
counter = 1 counter = 1
while True: while True:
cursor.execute("SELECT id FROM tenants WHERE slug = ?", (slug, )) cursor.execute("SELECT id FROM tenants WHERE slug = ?", (slug,))
if not cursor.fetchone(): if not cursor.fetchone():
break break
slug = f"{base_slug}-{counter}" slug = f"{base_slug}-{counter}"

View File

@@ -198,7 +198,7 @@ class TestOpsManager:
for channel in channels: for channel in channels:
if channel.tenant_id == self.tenant_id: if channel.tenant_id == self.tenant_id:
with self.manager._get_db() as conn: with self.manager._get_db() as conn:
conn.execute("DELETE FROM alert_channels WHERE id = ?", (channel.id, )) conn.execute("DELETE FROM alert_channels WHERE id = ?", (channel.id,))
conn.commit() conn.commit()
self.log("Deleted test alert channels") self.log("Deleted test alert channels")
@@ -320,8 +320,8 @@ class TestOpsManager:
# 清理 # 清理
self.manager.delete_alert_rule(rule.id) self.manager.delete_alert_rule(rule.id)
with self.manager._get_db() as conn: with self.manager._get_db() as conn:
conn.execute("DELETE FROM alerts WHERE id = ?", (alert_id, )) conn.execute("DELETE FROM alerts WHERE id = ?", (alert_id,))
conn.execute("DELETE FROM resource_metrics WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM resource_metrics WHERE tenant_id = ?", (self.tenant_id,))
conn.commit() conn.commit()
self.log("Cleaned up test data") self.log("Cleaned up test data")
@@ -381,8 +381,8 @@ class TestOpsManager:
# 清理 # 清理
with self.manager._get_db() as conn: with self.manager._get_db() as conn:
conn.execute("DELETE FROM capacity_plans WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM capacity_plans WHERE tenant_id = ?", (self.tenant_id,))
conn.execute("DELETE FROM resource_metrics WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM resource_metrics WHERE tenant_id = ?", (self.tenant_id,))
conn.commit() conn.commit()
self.log("Cleaned up capacity planning test data") self.log("Cleaned up capacity planning test data")
@@ -437,9 +437,9 @@ class TestOpsManager:
# 清理 # 清理
with self.manager._get_db() as conn: with self.manager._get_db() as conn:
conn.execute("DELETE FROM scaling_events WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM scaling_events WHERE tenant_id = ?", (self.tenant_id,))
conn.execute( conn.execute(
"DELETE FROM auto_scaling_policies WHERE tenant_id = ?", (self.tenant_id, ) "DELETE FROM auto_scaling_policies WHERE tenant_id = ?", (self.tenant_id,)
) )
conn.commit() conn.commit()
self.log("Cleaned up auto scaling test data") self.log("Cleaned up auto scaling test data")
@@ -495,7 +495,7 @@ class TestOpsManager:
# 清理 # 清理
with self.manager._get_db() as conn: with self.manager._get_db() as conn:
conn.execute("DELETE FROM health_checks WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM health_checks WHERE tenant_id = ?", (self.tenant_id,))
conn.commit() conn.commit()
self.log("Cleaned up health check test data") self.log("Cleaned up health check test data")
@@ -550,8 +550,8 @@ class TestOpsManager:
# 清理 # 清理
with self.manager._get_db() as conn: with self.manager._get_db() as conn:
conn.execute("DELETE FROM failover_events WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM failover_events WHERE tenant_id = ?", (self.tenant_id,))
conn.execute("DELETE FROM failover_configs WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM failover_configs WHERE tenant_id = ?", (self.tenant_id,))
conn.commit() conn.commit()
self.log("Cleaned up failover test data") self.log("Cleaned up failover test data")
@@ -604,8 +604,8 @@ class TestOpsManager:
# 清理 # 清理
with self.manager._get_db() as conn: with self.manager._get_db() as conn:
conn.execute("DELETE FROM backup_records WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM backup_records WHERE tenant_id = ?", (self.tenant_id,))
conn.execute("DELETE FROM backup_jobs WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM backup_jobs WHERE tenant_id = ?", (self.tenant_id,))
conn.commit() conn.commit()
self.log("Cleaned up backup test data") self.log("Cleaned up backup test data")
@@ -687,13 +687,13 @@ class TestOpsManager:
with self.manager._get_db() as conn: with self.manager._get_db() as conn:
conn.execute( conn.execute(
"DELETE FROM cost_optimization_suggestions WHERE tenant_id = ?", "DELETE FROM cost_optimization_suggestions WHERE tenant_id = ?",
(self.tenant_id, ), (self.tenant_id,),
) )
conn.execute("DELETE FROM idle_resources WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM idle_resources WHERE tenant_id = ?", (self.tenant_id,))
conn.execute( conn.execute(
"DELETE FROM resource_utilizations WHERE tenant_id = ?", (self.tenant_id, ) "DELETE FROM resource_utilizations WHERE tenant_id = ?", (self.tenant_id,)
) )
conn.execute("DELETE FROM cost_reports WHERE tenant_id = ?", (self.tenant_id, )) conn.execute("DELETE FROM cost_reports WHERE tenant_id = ?", (self.tenant_id,))
conn.commit() conn.commit()
self.log("Cleaned up cost optimization test data") self.log("Cleaned up cost optimization test data")

View File

@@ -487,7 +487,7 @@ class WorkflowManager:
"""获取工作流""" """获取工作流"""
conn = self.db.get_conn() conn = self.db.get_conn()
try: try:
row = conn.execute("SELECT * FROM workflows WHERE id = ?", (workflow_id, )).fetchone() row = conn.execute("SELECT * FROM workflows WHERE id = ?", (workflow_id,)).fetchone()
if not row: if not row:
return None return None
@@ -584,10 +584,10 @@ class WorkflowManager:
self.scheduler.remove_job(job_id) self.scheduler.remove_job(job_id)
# 删除相关任务 # 删除相关任务
conn.execute("DELETE FROM workflow_tasks WHERE workflow_id = ?", (workflow_id, )) conn.execute("DELETE FROM workflow_tasks WHERE workflow_id = ?", (workflow_id,))
# 删除工作流 # 删除工作流
conn.execute("DELETE FROM workflows WHERE id = ?", (workflow_id, )) conn.execute("DELETE FROM workflows WHERE id = ?", (workflow_id,))
conn.commit() conn.commit()
return True return True
@@ -653,7 +653,7 @@ class WorkflowManager:
"""获取任务""" """获取任务"""
conn = self.db.get_conn() conn = self.db.get_conn()
try: try:
row = conn.execute("SELECT * FROM workflow_tasks WHERE id = ?", (task_id, )).fetchone() row = conn.execute("SELECT * FROM workflow_tasks WHERE id = ?", (task_id,)).fetchone()
if not row: if not row:
return None return None
@@ -668,7 +668,7 @@ class WorkflowManager:
try: try:
rows = conn.execute( rows = conn.execute(
"SELECT * FROM workflow_tasks WHERE workflow_id = ? ORDER BY task_order", "SELECT * FROM workflow_tasks WHERE workflow_id = ? ORDER BY task_order",
(workflow_id, ), (workflow_id,),
).fetchall() ).fetchall()
return [self._row_to_task(row) for row in rows] return [self._row_to_task(row) for row in rows]
@@ -719,7 +719,7 @@ class WorkflowManager:
"""删除任务""" """删除任务"""
conn = self.db.get_conn() conn = self.db.get_conn()
try: try:
conn.execute("DELETE FROM workflow_tasks WHERE id = ?", (task_id, )) conn.execute("DELETE FROM workflow_tasks WHERE id = ?", (task_id,))
conn.commit() conn.commit()
return True return True
finally: finally:
@@ -780,7 +780,7 @@ class WorkflowManager:
conn = self.db.get_conn() conn = self.db.get_conn()
try: try:
row = conn.execute( row = conn.execute(
"SELECT * FROM webhook_configs WHERE id = ?", (webhook_id, ) "SELECT * FROM webhook_configs WHERE id = ?", (webhook_id,)
).fetchone() ).fetchone()
if not row: if not row:
@@ -843,7 +843,7 @@ class WorkflowManager:
"""删除 Webhook 配置""" """删除 Webhook 配置"""
conn = self.db.get_conn() conn = self.db.get_conn()
try: try:
conn.execute("DELETE FROM webhook_configs WHERE id = ?", (webhook_id, )) conn.execute("DELETE FROM webhook_configs WHERE id = ?", (webhook_id,))
conn.commit() conn.commit()
return True return True
finally: finally:
@@ -951,7 +951,7 @@ class WorkflowManager:
"""获取日志""" """获取日志"""
conn = self.db.get_conn() conn = self.db.get_conn()
try: try:
row = conn.execute("SELECT * FROM workflow_logs WHERE id = ?", (log_id, )).fetchone() row = conn.execute("SELECT * FROM workflow_logs WHERE id = ?", (log_id,)).fetchone()
if not row: if not row:
return None return None

View File

@@ -11,231 +11,264 @@ from pathlib import Path
from typing import Any from typing import Any
# 项目路径 # 项目路径
PROJECT_PATH = Path("/root/.openclaw/workspace/projects/insightflow") PROJECT_PATH = Path("/root/.openclaw/workspace/projects/insightflow")
# 修复报告 # 修复报告
report = { report = {"fixed": [], "manual_review": [], "errors": []}
"fixed": [],
"manual_review": [],
"errors": []
}
def find_python_files() -> list[Path]: def find_python_files() -> list[Path]:
"""查找所有 Python 文件""" """查找所有 Python 文件"""
py_files = [] py_files = []
for py_file in PROJECT_PATH.rglob("*.py"): for py_file in PROJECT_PATH.rglob("*.py"):
if "__pycache__" not in str(py_file): if "__pycache__" not in str(py_file):
py_files.append(py_file) py_files.append(py_file)
return py_files return py_files
def check_duplicate_imports(content: str, file_path: Path) -> list[dict]: def check_duplicate_imports(content: str, file_path: Path) -> list[dict]:
"""检查重复导入""" """检查重复导入"""
issues = [] issues = []
lines = content.split('\n') lines = content.split("\n")
imports = {} imports = {}
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
line_stripped = line.strip() line_stripped = line.strip()
if line_stripped.startswith('import ') or line_stripped.startswith('from '): if line_stripped.startswith("import ") or line_stripped.startswith("from "):
if line_stripped in imports: if line_stripped in imports:
issues.append({ issues.append(
"line": i, {
"type": "duplicate_import", "line": i,
"content": line_stripped, "type": "duplicate_import",
"original_line": imports[line_stripped] "content": line_stripped,
}) "original_line": imports[line_stripped],
}
)
else: else:
imports[line_stripped] = i imports[line_stripped] = i
return issues return issues
def check_bare_excepts(content: str, file_path: Path) -> list[dict]: def check_bare_excepts(content: str, file_path: Path) -> list[dict]:
"""检查裸异常捕获""" """检查裸异常捕获"""
issues = [] issues = []
lines = content.split('\n') lines = content.split("\n")
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
stripped = line.strip() stripped = line.strip()
# 检查 except Exception: 或 except Exception: # 检查 except Exception: 或 except Exception:
if re.match(r'^except\s*:', stripped): if re.match(r"^except\s*:", stripped):
issues.append({ issues.append({"line": i, "type": "bare_except", "content": stripped})
"line": i,
"type": "bare_except",
"content": stripped
})
return issues return issues
def check_line_length(content: str, file_path: Path) -> list[dict]: def check_line_length(content: str, file_path: Path) -> list[dict]:
"""检查行长度PEP8: 79字符这里放宽到 100""" """检查行长度PEP8: 79字符这里放宽到 100"""
issues = [] issues = []
lines = content.split('\n') lines = content.split("\n")
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
if len(line) > 100: if len(line) > 100:
issues.append({ issues.append(
"line": i, {
"type": "line_too_long", "line": i,
"length": len(line), "type": "line_too_long",
"content": line[:80] + "..." "length": len(line),
}) "content": line[:80] + "...",
}
)
return issues return issues
def check_unused_imports(content: str, file_path: Path) -> list[dict]: def check_unused_imports(content: str, file_path: Path) -> list[dict]:
"""检查未使用的导入""" """检查未使用的导入"""
issues = [] issues = []
try: try:
tree = ast.parse(content) tree = ast.parse(content)
imports = {} imports = {}
used_names = set() used_names = set()
for node in ast.walk(tree): for node in ast.walk(tree):
if isinstance(node, ast.Import): if isinstance(node, ast.Import):
for alias in node.names: for alias in node.names:
imports[alias.asname or alias.name] = node imports[alias.asname or alias.name] = node
elif isinstance(node, ast.ImportFrom): elif isinstance(node, ast.ImportFrom):
for alias in node.names: for alias in node.names:
name = alias.asname or alias.name name = alias.asname or alias.name
if name != '*': if name != "*":
imports[name] = node imports[name] = node
elif isinstance(node, ast.Name): elif isinstance(node, ast.Name):
used_names.add(node.id) used_names.add(node.id)
for name, node in imports.items(): for name, node in imports.items():
if name not in used_names and not name.startswith('_'): if name not in used_names and not name.startswith("_"):
issues.append({ issues.append(
"line": node.lineno, {"line": node.lineno, "type": "unused_import", "name": name}
"type": "unused_import", )
"name": name
})
except SyntaxError: except SyntaxError:
pass pass
return issues return issues
def check_string_formatting(content: str, file_path: Path) -> list[dict]: def check_string_formatting(content: str, file_path: Path) -> list[dict]:
"""检查混合字符串格式化(建议使用 f-string""" """检查混合字符串格式化(建议使用 f-string"""
issues = [] issues = []
lines = content.split('\n') lines = content.split("\n")
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
# 检查 % 格式化 # 检查 % 格式化
if re.search(r'["\'].*%\s*\w+', line) and '%' in line: if re.search(r'["\'].*%\s*\w+', line) and "%" in line:
if not line.strip().startswith('#'): if not line.strip().startswith("#"):
issues.append({ issues.append(
"line": i, {
"type": "percent_formatting", "line": i,
"content": line.strip()[:60] "type": "percent_formatting",
}) "content": line.strip()[:60],
}
)
# 检查 .format() # 检查 .format()
if '.format(' in line: if ".format(" in line:
if not line.strip().startswith('#'): if not line.strip().startswith("#"):
issues.append({ issues.append(
"line": i, {"line": i, "type": "format_method", "content": line.strip()[:60]}
"type": "format_method", )
"content": line.strip()[:60]
})
return issues return issues
def check_magic_numbers(content: str, file_path: Path) -> list[dict]: def check_magic_numbers(content: str, file_path: Path) -> list[dict]:
"""检查魔法数字""" """检查魔法数字"""
issues = [] issues = []
lines = content.split('\n') lines = content.split("\n")
# 常见魔法数字模式(排除常见索引和简单值) # 常见魔法数字模式(排除常见索引和简单值)
magic_pattern = re.compile(r'(?<![\w\d_])(\d{3, })(?![\w\d_])') magic_pattern = re.compile(r"(?<![\w\d_])(\d{3, })(?![\w\d_])")
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
if line.strip().startswith('#'): if line.strip().startswith("#"):
continue continue
matches = magic_pattern.findall(line) matches = magic_pattern.findall(line)
for match in matches: for match in matches:
num = int(match) num = int(match)
# 排除常见值 # 排除常见值
if num not in [200, 201, 204, 301, 302, 400, 401, 403, 404, 429, 500, 502, 503, 3600, 86400]: if num not in [
issues.append({ 200,
"line": i, 201,
"type": "magic_number", 204,
"value": match, 301,
"content": line.strip()[:60] 302,
}) 400,
401,
403,
404,
429,
500,
502,
503,
3600,
86400,
]:
issues.append(
{
"line": i,
"type": "magic_number",
"value": match,
"content": line.strip()[:60],
}
)
return issues return issues
def check_sql_injection(content: str, file_path: Path) -> list[dict]: def check_sql_injection(content: str, file_path: Path) -> list[dict]:
"""检查 SQL 注入风险""" """检查 SQL 注入风险"""
issues = [] issues = []
lines = content.split('\n') lines = content.split("\n")
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
# 检查字符串拼接的 SQL # 检查字符串拼接的 SQL
if 'execute(' in line or 'executescript(' in line or 'executemany(' in line: if "execute(" in line or "executescript(" in line or "executemany(" in line:
# 检查是否有 f-string 或 .format 在 SQL 中 # 检查是否有 f-string 或 .format 在 SQL 中
if 'f"' in line or "f'" in line or '.format(' in line or '%' in line: if 'f"' in line or "f'" in line or ".format(" in line or "%" in line:
if 'SELECT' in line.upper() or 'INSERT' in line.upper() or 'UPDATE' in line.upper() or 'DELETE' in line.upper(): if (
issues.append({ "SELECT" in line.upper()
"line": i, or "INSERT" in line.upper()
"type": "sql_injection_risk", or "UPDATE" in line.upper()
"content": line.strip()[:80], or "DELETE" in line.upper()
"severity": "high" ):
}) issues.append(
{
"line": i,
"type": "sql_injection_risk",
"content": line.strip()[:80],
"severity": "high",
}
)
return issues return issues
def check_cors_config(content: str, file_path: Path) -> list[dict]: def check_cors_config(content: str, file_path: Path) -> list[dict]:
"""检查 CORS 配置""" """检查 CORS 配置"""
issues = [] issues = []
lines = content.split('\n') lines = content.split("\n")
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
if 'allow_origins' in line and '["*"]' in line: if "allow_origins" in line and '["*"]' in line:
issues.append({ issues.append(
"line": i, {
"type": "cors_wildcard", "line": i,
"content": line.strip(), "type": "cors_wildcard",
"severity": "medium" "content": line.strip(),
}) "severity": "medium",
}
)
return issues return issues
def fix_bare_excepts(content: str) -> str: def fix_bare_excepts(content: str) -> str:
"""修复裸异常捕获""" """修复裸异常捕获"""
lines = content.split('\n') lines = content.split("\n")
new_lines = [] new_lines = []
for line in lines: for line in lines:
stripped = line.strip() stripped = line.strip()
if re.match(r'^except\s*:', stripped): if re.match(r"^except\s*:", stripped):
# 替换为具体异常 # 替换为具体异常
indent = len(line) - len(line.lstrip()) indent = len(line) - len(line.lstrip())
new_line = ' ' * indent + 'except (RuntimeError, ValueError, TypeError):' new_line = " " * indent + "except (RuntimeError, ValueError, TypeError):"
new_lines.append(new_line) new_lines.append(new_line)
else: else:
new_lines.append(line) new_lines.append(line)
return '\n'.join(new_lines) return "\n".join(new_lines)
def fix_line_length(content: str) -> str: def fix_line_length(content: str) -> str:
"""修复行长度问题(简单折行)""" """修复行长度问题(简单折行)"""
lines = content.split('\n') lines = content.split("\n")
new_lines = [] new_lines = []
for line in lines: for line in lines:
if len(line) > 100: if len(line) > 100:
# 尝试在逗号或运算符处折行 # 尝试在逗号或运算符处折行
if ', ' in line[80:]: if ", " in line[80:]:
# 简单处理:截断并添加续行 # 简单处理:截断并添加续行
indent = len(line) - len(line.lstrip()) indent = len(line) - len(line.lstrip())
new_lines.append(line) new_lines.append(line)
else: else:
new_lines.append(line) new_lines.append(line)
else: else:
new_lines.append(line) new_lines.append(line)
return '\n'.join(new_lines) return "\n".join(new_lines)
def analyze_file(file_path: Path) -> dict: def analyze_file(file_path: Path) -> dict:
"""分析单个文件""" """分析单个文件"""
try: try:
content = file_path.read_text(encoding = 'utf-8') content = file_path.read_text(encoding="utf-8")
except Exception as e: except Exception as e:
return {"error": str(e)} return {"error": str(e)}
issues = { issues = {
"duplicate_imports": check_duplicate_imports(content, file_path), "duplicate_imports": check_duplicate_imports(content, file_path),
"bare_excepts": check_bare_excepts(content, file_path), "bare_excepts": check_bare_excepts(content, file_path),
"line_length": check_line_length(content, file_path), "line_length": check_line_length(content, file_path),
@@ -248,35 +281,37 @@ def analyze_file(file_path: Path) -> dict:
return issues return issues
def fix_file(file_path: Path, issues: dict) -> bool: def fix_file(file_path: Path, issues: dict) -> bool:
"""自动修复文件问题""" """自动修复文件问题"""
try: try:
content = file_path.read_text(encoding = 'utf-8') content = file_path.read_text(encoding="utf-8")
original_content = content original_content = content
# 修复裸异常 # 修复裸异常
if issues.get("bare_excepts"): if issues.get("bare_excepts"):
content = fix_bare_excepts(content) content = fix_bare_excepts(content)
# 如果有修改,写回文件 # 如果有修改,写回文件
if content != original_content: if content != original_content:
file_path.write_text(content, encoding = 'utf-8') file_path.write_text(content, encoding="utf-8")
return True return True
return False return False
except Exception as e: except Exception as e:
report["errors"].append(f"{file_path}: {e}") report["errors"].append(f"{file_path}: {e}")
return False return False
def generate_report(all_issues: dict) -> str: def generate_report(all_issues: dict) -> str:
"""生成修复报告""" """生成修复报告"""
lines = [] lines = []
lines.append("# InsightFlow 代码审查报告") lines.append("# InsightFlow 代码审查报告")
lines.append(f"\n生成时间: {__import__('datetime').datetime.now().isoformat()}") lines.append(f"\n生成时间: {__import__('datetime').datetime.now().isoformat()}")
lines.append("\n## 自动修复的问题\n") lines.append("\n## 自动修复的问题\n")
total_fixed = 0 total_fixed = 0
for file_path, issues in all_issues.items(): for file_path, issues in all_issues.items():
fixed_count = 0 fixed_count = 0
for issue_type, issue_list in issues.items(): for issue_type, issue_list in issues.items():
if issue_type in ["bare_excepts"] and issue_list: if issue_type in ["bare_excepts"] and issue_list:
fixed_count += len(issue_list) fixed_count += len(issue_list)
@@ -293,9 +328,9 @@ def generate_report(all_issues: dict) -> str:
lines.append("\n## 需要人工确认的问题\n") lines.append("\n## 需要人工确认的问题\n")
total_manual = 0 total_manual = 0
for file_path, issues in all_issues.items(): for file_path, issues in all_issues.items():
manual_issues = [] manual_issues = []
if issues.get("sql_injection"): if issues.get("sql_injection"):
manual_issues.extend(issues["sql_injection"]) manual_issues.extend(issues["sql_injection"])
@@ -305,7 +340,9 @@ def generate_report(all_issues: dict) -> str:
if manual_issues: if manual_issues:
lines.append(f"### {file_path}") lines.append(f"### {file_path}")
for issue in manual_issues: for issue in manual_issues:
lines.append(f"- **{issue['type']}** (第 {issue['line']} 行): {issue.get('content', '')}") lines.append(
f"- **{issue['type']}** (第 {issue['line']} 行): {issue.get('content', '')}"
)
total_manual += len(manual_issues) total_manual += len(manual_issues)
if total_manual == 0: if total_manual == 0:
@@ -316,7 +353,7 @@ def generate_report(all_issues: dict) -> str:
lines.append("\n## 代码风格建议\n") lines.append("\n## 代码风格建议\n")
for file_path, issues in all_issues.items(): for file_path, issues in all_issues.items():
style_issues = [] style_issues = []
if issues.get("line_length"): if issues.get("line_length"):
style_issues.extend(issues["line_length"]) style_issues.extend(issues["line_length"])
if issues.get("string_formatting"): if issues.get("string_formatting"):
@@ -331,7 +368,8 @@ def generate_report(all_issues: dict) -> str:
if len(style_issues) > 5: if len(style_issues) > 5:
lines.append(f"- ... 还有 {len(style_issues) - 5} 个类似问题") lines.append(f"- ... 还有 {len(style_issues) - 5} 个类似问题")
return '\n'.join(lines) return "\n".join(lines)
def git_commit_and_push() -> None: def git_commit_and_push() -> None:
"""提交并推送代码""" """提交并推送代码"""
@@ -339,31 +377,34 @@ def git_commit_and_push() -> None:
os.chdir(PROJECT_PATH) os.chdir(PROJECT_PATH)
# 检查是否有修改 # 检查是否有修改
result = subprocess.run( result = subprocess.run(
["git", "status", "--porcelain"], ["git", "status", "--porcelain"], capture_output=True, text=True
capture_output = True,
text = True
) )
if not result.stdout.strip(): if not result.stdout.strip():
return "没有需要提交的更改" return "没有需要提交的更改"
# 添加所有修改 # 添加所有修改
subprocess.run(["git", "add", "-A"], check = True) subprocess.run(["git", "add", "-A"], check=True)
# 提交 # 提交
subprocess.run( subprocess.run(
["git", "commit", "-m", """fix: auto-fix code issues (cron) [
"git",
"commit",
"-m",
"""fix: auto-fix code issues (cron)
- 修复重复导入/字段 - 修复重复导入/字段
- 修复异常处理 - 修复异常处理
- 修复PEP8格式问题 - 修复PEP8格式问题
- 添加类型注解"""], - 添加类型注解""",
check = True ],
check=True,
) )
# 推送 # 推送
subprocess.run(["git", "push"], check = True) subprocess.run(["git", "push"], check=True)
return "✅ 提交并推送成功" return "✅ 提交并推送成功"
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
@@ -371,42 +412,44 @@ def git_commit_and_push() -> None:
except Exception as e: except Exception as e:
return f"❌ 错误: {e}" return f"❌ 错误: {e}"
def main() -> None: def main() -> None:
"""主函数""" """主函数"""
print("🔍 开始代码审查...") print("🔍 开始代码审查...")
py_files = find_python_files() py_files = find_python_files()
print(f"📁 找到 {len(py_files)} 个 Python 文件") print(f"📁 找到 {len(py_files)} 个 Python 文件")
all_issues = {} all_issues = {}
for py_file in py_files: for py_file in py_files:
print(f" 分析: {py_file.name}") print(f" 分析: {py_file.name}")
issues = analyze_file(py_file) issues = analyze_file(py_file)
all_issues[py_file] = issues all_issues[py_file] = issues
# 自动修复 # 自动修复
if fix_file(py_file, issues): if fix_file(py_file, issues):
report["fixed"].append(str(py_file)) report["fixed"].append(str(py_file))
# 生成报告 # 生成报告
report_content = generate_report(all_issues) report_content = generate_report(all_issues)
report_path = PROJECT_PATH / "AUTO_CODE_REVIEW_REPORT.md" report_path = PROJECT_PATH / "AUTO_CODE_REVIEW_REPORT.md"
report_path.write_text(report_content, encoding = 'utf-8') report_path.write_text(report_content, encoding="utf-8")
print("\n📄 报告已生成:", report_path) print("\n📄 报告已生成:", report_path)
# Git 提交 # Git 提交
print("\n🚀 提交代码...") print("\n🚀 提交代码...")
git_result = git_commit_and_push() git_result = git_commit_and_push()
print(git_result) print(git_result)
# 追加提交结果到报告 # 追加提交结果到报告
with open(report_path, 'a', encoding = 'utf-8') as f: with open(report_path, "a", encoding="utf-8") as f:
f.write(f"\n\n## Git 提交结果\n\n{git_result}\n") f.write(f"\n\n## Git 提交结果\n\n{git_result}\n")
print("\n✅ 代码审查完成!") print("\n✅ 代码审查完成!")
return report_content return report_content
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View File

@@ -4,7 +4,9 @@ InsightFlow 代码审查与自动修复脚本
""" """
import ast import ast
import os
import re import re
import subprocess
from pathlib import Path from pathlib import Path
@@ -15,25 +17,25 @@ class CodeIssue:
line_no: int, line_no: int,
issue_type: str, issue_type: str,
message: str, message: str,
severity: str = "info", severity: str = "info",
) -> None: ) -> None:
self.file_path = file_path self.file_path = file_path
self.line_no = line_no self.line_no = line_no
self.issue_type = issue_type self.issue_type = issue_type
self.message = message self.message = message
self.severity = severity # info, warning, error self.severity = severity # info, warning, error
self.fixed = False self.fixed = False
def __repr__(self) -> None: def __repr__(self) -> str:
return f"{self.severity.upper()}: {self.file_path}:{self.line_no} - {self.issue_type}: {self.message}" return f"{self.severity.upper()}: {self.file_path}:{self.line_no} - {self.issue_type}: {self.message}"
class CodeReviewer: class CodeReviewer:
def __init__(self, base_path: str) -> None: def __init__(self, base_path: str) -> None:
self.base_path = Path(base_path) self.base_path = Path(base_path)
self.issues: list[CodeIssue] = [] self.issues: list[CodeIssue] = []
self.fixed_issues: list[CodeIssue] = [] self.fixed_issues: list[CodeIssue] = []
self.manual_review_issues: list[CodeIssue] = [] self.manual_review_issues: list[CodeIssue] = []
def scan_all(self) -> None: def scan_all(self) -> None:
"""扫描所有 Python 文件""" """扫描所有 Python 文件"""
@@ -45,14 +47,14 @@ class CodeReviewer:
def scan_file(self, file_path: Path) -> None: def scan_file(self, file_path: Path) -> None:
"""扫描单个文件""" """扫描单个文件"""
try: try:
with open(file_path, "r", encoding = "utf-8") as f: with open(file_path, "r", encoding="utf-8") as f:
content = f.read() content = f.read()
lines = content.split("\n") lines = content.split("\n")
except Exception as e: except Exception as e:
print(f"Error reading {file_path}: {e}") print(f"Error reading {file_path}: {e}")
return return
rel_path = str(file_path.relative_to(self.base_path)) rel_path = str(file_path.relative_to(self.base_path))
# 1. 检查裸异常捕获 # 1. 检查裸异常捕获
self._check_bare_exceptions(content, lines, rel_path) self._check_bare_exceptions(content, lines, rel_path)
@@ -92,7 +94,7 @@ class CodeReviewer:
# 跳过有注释说明的情况 # 跳过有注释说明的情况
if "# noqa" in line or "# intentional" in line.lower(): if "# noqa" in line or "# intentional" in line.lower():
continue continue
issue = CodeIssue( issue = CodeIssue(
file_path, file_path,
i, i,
"bare_exception", "bare_exception",
@@ -105,17 +107,17 @@ class CodeReviewer:
self, content: str, lines: list[str], file_path: str self, content: str, lines: list[str], file_path: str
) -> None: ) -> None:
"""检查重复导入""" """检查重复导入"""
imports = {} imports = {}
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
match = re.match(r"^(?:from\s+(\S+)\s+)?import\s+(.+)$", line.strip()) match = re.match(r"^(?:from\s+(\S+)\s+)?import\s+(.+)$", line.strip())
if match: if match:
module = match.group(1) or "" module = match.group(1) or ""
names = match.group(2).split(", ") names = match.group(2).split(", ")
for name in names: for name in names:
name = name.strip().split()[0] # 处理 'as' 别名 name = name.strip().split()[0] # 处理 'as' 别名
key = f"{module}.{name}" if module else name key = f"{module}.{name}" if module else name
if key in imports: if key in imports:
issue = CodeIssue( issue = CodeIssue(
file_path, file_path,
i, i,
"duplicate_import", "duplicate_import",
@@ -123,7 +125,7 @@ class CodeReviewer:
"warning", "warning",
) )
self.issues.append(issue) self.issues.append(issue)
imports[key] = i imports[key] = i
def _check_pep8_issues( def _check_pep8_issues(
self, content: str, lines: list[str], file_path: str self, content: str, lines: list[str], file_path: str
@@ -132,7 +134,7 @@ class CodeReviewer:
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
# 行长度超过 120 # 行长度超过 120
if len(line) > 120: if len(line) > 120:
issue = CodeIssue( issue = CodeIssue(
file_path, file_path,
i, i,
"line_too_long", "line_too_long",
@@ -143,7 +145,7 @@ class CodeReviewer:
# 行尾空格 # 行尾空格
if line.rstrip() != line: if line.rstrip() != line:
issue = CodeIssue( issue = CodeIssue(
file_path, i, "trailing_whitespace", "行尾有空格", "info" file_path, i, "trailing_whitespace", "行尾有空格", "info"
) )
self.issues.append(issue) self.issues.append(issue)
@@ -151,7 +153,7 @@ class CodeReviewer:
# 多余的空行 # 多余的空行
if i > 1 and line.strip() == "" and lines[i - 2].strip() == "": if i > 1 and line.strip() == "" and lines[i - 2].strip() == "":
if i < len(lines) and lines[i].strip() == "": if i < len(lines) and lines[i].strip() == "":
issue = CodeIssue( issue = CodeIssue(
file_path, i, "extra_blank_line", "多余的空行", "info" file_path, i, "extra_blank_line", "多余的空行", "info"
) )
self.issues.append(issue) self.issues.append(issue)
@@ -161,23 +163,23 @@ class CodeReviewer:
) -> None: ) -> None:
"""检查未使用的导入""" """检查未使用的导入"""
try: try:
tree = ast.parse(content) tree = ast.parse(content)
except SyntaxError: except SyntaxError:
return return
imported_names = {} imported_names = {}
used_names = set() used_names = set()
for node in ast.walk(tree): for node in ast.walk(tree):
if isinstance(node, ast.Import): if isinstance(node, ast.Import):
for alias in node.names: for alias in node.names:
name = alias.asname if alias.asname else alias.name name = alias.asname if alias.asname else alias.name
imported_names[name] = node.lineno imported_names[name] = node.lineno
elif isinstance(node, ast.ImportFrom): elif isinstance(node, ast.ImportFrom):
for alias in node.names: for alias in node.names:
name = alias.asname if alias.asname else alias.name name = alias.asname if alias.asname else alias.name
if name != "*": if name != "*":
imported_names[name] = node.lineno imported_names[name] = node.lineno
elif isinstance(node, ast.Name): elif isinstance(node, ast.Name):
used_names.add(node.id) used_names.add(node.id)
@@ -186,7 +188,7 @@ class CodeReviewer:
# 排除一些常见例外 # 排除一些常见例外
if name in ["annotations", "TYPE_CHECKING"]: if name in ["annotations", "TYPE_CHECKING"]:
continue continue
issue = CodeIssue( issue = CodeIssue(
file_path, lineno, "unused_import", f"未使用的导入: {name}", "info" file_path, lineno, "unused_import", f"未使用的导入: {name}", "info"
) )
self.issues.append(issue) self.issues.append(issue)
@@ -195,20 +197,20 @@ class CodeReviewer:
self, content: str, lines: list[str], file_path: str self, content: str, lines: list[str], file_path: str
) -> None: ) -> None:
"""检查混合字符串格式化""" """检查混合字符串格式化"""
has_fstring = False has_fstring = False
has_percent = False has_percent = False
has_format = False has_format = False
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
if re.search(r'f["\']', line): if re.search(r'f["\']', line):
has_fstring = True has_fstring = True
if re.search(r"%[sdfr]", line) and not re.search(r"\d+%", line): if re.search(r"%[sdfr]", line) and not re.search(r"\d+%", line):
has_percent = True has_percent = True
if ".format(" in line: if ".format(" in line:
has_format = True has_format = True
if has_fstring and (has_percent or has_format): if has_fstring and (has_percent or has_format):
issue = CodeIssue( issue = CodeIssue(
file_path, file_path,
0, 0,
"mixed_formatting", "mixed_formatting",
@@ -222,7 +224,7 @@ class CodeReviewer:
) -> None: ) -> None:
"""检查魔法数字""" """检查魔法数字"""
# 常见的魔法数字模式 # 常见的魔法数字模式
magic_patterns = [ magic_patterns = [
(r" = \s*(\d{3, })\s*[^:]", "可能的魔法数字"), (r" = \s*(\d{3, })\s*[^:]", "可能的魔法数字"),
(r"timeout\s* = \s*(\d+)", "timeout 魔法数字"), (r"timeout\s* = \s*(\d+)", "timeout 魔法数字"),
(r"limit\s* = \s*(\d+)", "limit 魔法数字"), (r"limit\s* = \s*(\d+)", "limit 魔法数字"),
@@ -231,16 +233,16 @@ class CodeReviewer:
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
# 跳过注释和字符串 # 跳过注释和字符串
code_part = line.split("#")[0] code_part = line.split("#")[0]
if not code_part.strip(): if not code_part.strip():
continue continue
for pattern, msg in magic_patterns: for pattern, msg in magic_patterns:
if re.search(pattern, code_part, re.IGNORECASE): if re.search(pattern, code_part, re.IGNORECASE):
# 排除常见的合理数字 # 排除常见的合理数字
match = re.search(r"(\d{3, })", code_part) match = re.search(r"(\d{3, })", code_part)
if match: if match:
num = int(match.group(1)) num = int(match.group(1))
if num in [ if num in [
200, 200,
404, 404,
@@ -257,7 +259,7 @@ class CodeReviewer:
8000, 8000,
]: ]:
continue continue
issue = CodeIssue( issue = CodeIssue(
file_path, i, "magic_number", f"{msg}: {num}", "info" file_path, i, "magic_number", f"{msg}: {num}", "info"
) )
self.issues.append(issue) self.issues.append(issue)
@@ -272,7 +274,7 @@ class CodeReviewer:
r'execute\s*\(\s*f["\']', line r'execute\s*\(\s*f["\']', line
): ):
if "?" not in line and "%s" in line: if "?" not in line and "%s" in line:
issue = CodeIssue( issue = CodeIssue(
file_path, file_path,
i, i,
"sql_injection_risk", "sql_injection_risk",
@@ -287,7 +289,7 @@ class CodeReviewer:
"""检查 CORS 配置""" """检查 CORS 配置"""
for i, line in enumerate(lines, 1): for i, line in enumerate(lines, 1):
if "allow_origins" in line and '["*"]' in line: if "allow_origins" in line and '["*"]' in line:
issue = CodeIssue( issue = CodeIssue(
file_path, file_path,
i, i,
"cors_wildcard", "cors_wildcard",
@@ -316,7 +318,7 @@ class CodeReviewer:
if not re.search(r'["\']\*+["\']', line) and not re.search( if not re.search(r'["\']\*+["\']', line) and not re.search(
r'["\']<[^"\']*>["\']', line r'["\']<[^"\']*>["\']', line
): ):
issue = CodeIssue( issue = CodeIssue(
file_path, file_path,
i, i,
"hardcoded_secret", "hardcoded_secret",
@@ -328,62 +330,64 @@ class CodeReviewer:
def auto_fix(self) -> None: def auto_fix(self) -> None:
"""自动修复问题""" """自动修复问题"""
# 按文件分组问题 # 按文件分组问题
issues_by_file: dict[str, list[CodeIssue]] = {} issues_by_file: dict[str, list[CodeIssue]] = {}
for issue in self.issues: for issue in self.issues:
if issue.file_path not in issues_by_file: if issue.file_path not in issues_by_file:
issues_by_file[issue.file_path] = [] issues_by_file[issue.file_path] = []
issues_by_file[issue.file_path].append(issue) issues_by_file[issue.file_path].append(issue)
for file_path, issues in issues_by_file.items(): for file_path, issues in issues_by_file.items():
full_path = self.base_path / file_path full_path = self.base_path / file_path
if not full_path.exists(): if not full_path.exists():
continue continue
try: try:
with open(full_path, "r", encoding = "utf-8") as f: with open(full_path, "r", encoding="utf-8") as f:
content = f.read() content = f.read()
lines = content.split("\n") lines = content.split("\n")
except Exception as e: except Exception as e:
print(f"Error reading {full_path}: {e}") print(f"Error reading {full_path}: {e}")
continue continue
original_lines = lines.copy() original_lines = lines.copy()
# 修复行尾空格 # 修复行尾空格
for issue in issues: for issue in issues:
if issue.issue_type == "trailing_whitespace": if issue.issue_type == "trailing_whitespace":
idx = issue.line_no - 1 idx = issue.line_no - 1
if 0 <= idx < len(lines): if 0 <= idx < len(lines):
lines[idx] = lines[idx].rstrip() lines[idx] = lines[idx].rstrip()
issue.fixed = True issue.fixed = True
# 修复裸异常 # 修复裸异常
for issue in issues: for issue in issues:
if issue.issue_type == "bare_exception": if issue.issue_type == "bare_exception":
idx = issue.line_no - 1 idx = issue.line_no - 1
if 0 <= idx < len(lines): if 0 <= idx < len(lines):
line = lines[idx] line = lines[idx]
# 将 except Exception: 改为 except Exception: # 将 except Exception: 改为 except Exception:
if re.search(r"except\s*:\s*$", line.strip()): if re.search(r"except\s*:\s*$", line.strip()):
lines[idx] = line.replace("except Exception:", "except Exception:") lines[idx] = line.replace(
issue.fixed = True "except Exception:", "except Exception:"
)
issue.fixed = True
elif re.search(r"except\s+Exception\s*:\s*$", line.strip()): elif re.search(r"except\s+Exception\s*:\s*$", line.strip()):
# 已经是 Exception但可能需要更具体 # 已经是 Exception但可能需要更具体
pass pass
# 如果文件有修改,写回 # 如果文件有修改,写回
if lines != original_lines: if lines != original_lines:
with open(full_path, "w", encoding = "utf-8") as f: with open(full_path, "w", encoding="utf-8") as f:
f.write("\n".join(lines)) f.write("\n".join(lines))
print(f"Fixed issues in {file_path}") print(f"Fixed issues in {file_path}")
# 移动到已修复列表 # 移动到已修复列表
self.fixed_issues = [i for i in self.issues if i.fixed] self.fixed_issues = [i for i in self.issues if i.fixed]
self.issues = [i for i in self.issues if not i.fixed] self.issues = [i for i in self.issues if not i.fixed]
def generate_report(self) -> str: def generate_report(self) -> str:
"""生成审查报告""" """生成审查报告"""
report = [] report = []
report.append("# InsightFlow 代码审查报告") report.append("# InsightFlow 代码审查报告")
report.append(f"\n扫描路径: {self.base_path}") report.append(f"\n扫描路径: {self.base_path}")
report.append(f"扫描时间: {__import__('datetime').datetime.now().isoformat()}") report.append(f"扫描时间: {__import__('datetime').datetime.now().isoformat()}")
@@ -422,8 +426,8 @@ class CodeReviewer:
def main() -> None: def main() -> None:
base_path = "/root/.openclaw/workspace/projects/insightflow/backend" base_path = "/root/.openclaw/workspace/projects/insightflow/backend"
reviewer = CodeReviewer(base_path) reviewer = CodeReviewer(base_path)
print("开始扫描代码...") print("开始扫描代码...")
reviewer.scan_all() reviewer.scan_all()
@@ -437,9 +441,9 @@ def main() -> None:
print(f"\n已修复 {len(reviewer.fixed_issues)} 个问题") print(f"\n已修复 {len(reviewer.fixed_issues)} 个问题")
# 生成报告 # 生成报告
report = reviewer.generate_report() report = reviewer.generate_report()
report_path = Path(base_path).parent / "CODE_REVIEW_REPORT.md" report_path = Path(base_path).parent / "CODE_REVIEW_REPORT.md"
with open(report_path, "w", encoding = "utf-8") as f: with open(report_path, "w", encoding="utf-8") as f:
f.write(report) f.write(report)
print(f"\n报告已保存到: {report_path}") print(f"\n报告已保存到: {report_path}")