#!/usr/bin/env python3 """ 自动代码修复脚本 - 修复 InsightFlow 项目中的常见问题 """ import os import re import subprocess from pathlib import Path def get_python_files(directory): """获取目录下所有 Python 文件""" python_files = [] for root, _, files in os.walk(directory): for file in files: if file.endswith('.py'): python_files.append(os.path.join(root, file)) return python_files def fix_missing_imports(content, filepath): """修复缺失的导入""" fixes = [] # 检查是否使用了 re 但没有导入 if 're.search(' in content or 're.sub(' in content or 're.match(' in content: if 'import re' not in content: # 找到合适的位置添加导入 lines = content.split('\n') import_idx = 0 for i, line in enumerate(lines): if line.startswith('import ') or line.startswith('from '): import_idx = i + 1 lines.insert(import_idx, 'import re') content = '\n'.join(lines) fixes.append("添加缺失的 'import re'") # 检查是否使用了 csv 但没有导入 if 'csv.' in content and 'import csv' not in content: lines = content.split('\n') import_idx = 0 for i, line in enumerate(lines): if line.startswith('import ') or line.startswith('from '): import_idx = i + 1 lines.insert(import_idx, 'import csv') content = '\n'.join(lines) fixes.append("添加缺失的 'import csv'") # 检查是否使用了 urllib 但没有导入 if 'urllib.' in content and 'import urllib' not in content: lines = content.split('\n') import_idx = 0 for i, line in enumerate(lines): if line.startswith('import ') or line.startswith('from '): import_idx = i + 1 lines.insert(import_idx, 'import urllib.parse') content = '\n'.join(lines) fixes.append("添加缺失的 'import urllib.parse'") return content, fixes def fix_bare_excepts(content): """修复裸异常捕获""" fixes = [] # 替换裸 except: bare_except_pattern = r'except\s*:\s*$' lines = content.split('\n') new_lines = [] for line in lines: if re.match(bare_except_pattern, line.strip()): # 缩进保持一致 indent = len(line) - len(line.lstrip()) new_line = ' ' * indent + 'except Exception:' new_lines.append(new_line) fixes.append(f"修复裸异常捕获: {line.strip()}") else: new_lines.append(line) content = '\n'.join(new_lines) return content, fixes def fix_unused_imports(content): """修复未使用的导入 - 简单版本""" fixes = [] # 查找导入语句 import_pattern = r'^from\s+(\S+)\s+import\s+(.+)$' lines = content.split('\n') new_lines = [] for line in lines: match = re.match(import_pattern, line) if match: module = match.group(1) imports = match.group(2) # 检查每个导入是否被使用 imported_items = [i.strip() for i in imports.split(',')] used_items = [] for item in imported_items: # 简单的使用检查 item_name = item.split(' as ')[-1].strip() if ' as ' in item else item.strip() if item_name in content.replace(line, ''): used_items.append(item) else: fixes.append(f"移除未使用的导入: {item}") if used_items: new_lines.append(f"from {module} import {', '.join(used_items)}") else: fixes.append(f"移除整行导入: {line.strip()}") else: new_lines.append(line) content = '\n'.join(new_lines) return content, fixes def fix_string_formatting(content): """统一字符串格式化为 f-string""" fixes = [] # 修复 .format() 调用 format_pattern = r'["\']([^"\']*)\{([^}]+)\}[^"\']*["\']\.format\(([^)]+)\)' def replace_format(match): template = match.group(1) + '{' + match.group(2) + '}' format_args = match.group(3) # 简单替换,实际可能需要更复杂的处理 return f'f"{template}"' new_content = re.sub(format_pattern, replace_format, content) if new_content != content: fixes.append("统一字符串格式化为 f-string") content = new_content return content, fixes def fix_pep8_formatting(content): """修复 PEP8 格式问题""" fixes = [] lines = content.split('\n') new_lines = [] for line in lines: original = line # 修复 E221: multiple spaces before operator line = re.sub(r'(\w+)\s{2,}=\s', r'\1 = ', line) # 修复 E251: unexpected spaces around keyword / parameter equals line = re.sub(r'(\w+)\s*=\s{2,}', r'\1 = ', line) line = re.sub(r'(\w+)\s{2,}=\s*', r'\1 = ', line) if line != original: fixes.append(f"修复 PEP8 格式: {original.strip()[:50]}") new_lines.append(line) content = '\n'.join(new_lines) return content, fixes def fix_file(filepath): """修复单个文件""" print(f"\n处理文件: {filepath}") try: with open(filepath, 'r', encoding='utf-8') as f: content = f.read() except Exception as e: print(f" 无法读取文件: {e}") return [] original_content = content all_fixes = [] # 应用各种修复 content, fixes = fix_missing_imports(content, filepath) all_fixes.extend(fixes) content, fixes = fix_bare_excepts(content) all_fixes.extend(fixes) content, fixes = fix_pep8_formatting(content) all_fixes.extend(fixes) # 保存修改 if content != original_content: try: with open(filepath, 'w', encoding='utf-8') as f: f.write(content) print(f" 已修复 {len(all_fixes)} 个问题") for fix in all_fixes[:5]: # 只显示前5个 print(f" - {fix}") if len(all_fixes) > 5: print(f" ... 还有 {len(all_fixes) - 5} 个修复") except Exception as e: print(f" 保存文件失败: {e}") else: print(" 无需修复") return all_fixes def main(): """主函数""" base_dir = '/root/.openclaw/workspace/projects/insightflow' backend_dir = os.path.join(base_dir, 'backend') print("=" * 60) print("InsightFlow 代码自动修复工具") print("=" * 60) # 获取所有 Python 文件 files = get_python_files(backend_dir) print(f"\n找到 {len(files)} 个 Python 文件") total_fixes = 0 fixed_files = 0 for filepath in files: fixes = fix_file(filepath) if fixes: total_fixes += len(fixes) fixed_files += 1 print("\n" + "=" * 60) print(f"修复完成: {fixed_files} 个文件, {total_fixes} 个问题") print("=" * 60) if __name__ == '__main__': main()