diff --git a/src/services/verification_service.py b/src/services/verification_service.py index 1c80064..0e5c0ac 100644 --- a/src/services/verification_service.py +++ b/src/services/verification_service.py @@ -62,6 +62,7 @@ class GeometryVerificationService: """运行验证脚本""" import tempfile import os + import shutil # 确保 stp_path 是字符串 stp_path_str = str(stp_path) @@ -74,51 +75,22 @@ class GeometryVerificationService: # 构建命令 - 使用 FreeCAD 命令行模式 cmd = None - # 尝试多种 FreeCAD 命令名称 - # AppImage 版本使用 freecad - # PPA 版本通常使用 freecadcmd - for cmd_name in ['freecad', 'freecadcmd', 'freecad-cmd', '/usr/local/bin/freecad', '/usr/bin/freecad', '/snap/bin/freecad.cmd']: - try: - result = subprocess.run(['which', cmd_name], capture_output=True, text=True) - if result.returncode == 0 and result.stdout.strip(): - # FreeCAD 1.0 直接执行脚本,不需要 -c 参数 - cmd = [cmd_name, str(self.verification_script), str(Path(stp_path_str).absolute())] - logger.info(f"找到 FreeCAD 命令: {cmd_name}") - break - except: - pass + # 使用 shutil.which 查找 FreeCAD 命令(更快) + for cmd_name in ['freecad', 'freecadcmd', 'freecad-cmd']: + cmd_path = shutil.which(cmd_name) + if cmd_path: + cmd = [cmd_path, str(self.verification_script), str(Path(stp_path_str).absolute())] + logger.info(f"找到 FreeCAD 命令: {cmd_path}") + break # 如果 which 找不到,尝试直接检查常见路径 if not cmd: for cmd_path in ['/usr/local/bin/freecad', '/usr/bin/freecad', '/usr/local/bin/freecadcmd', '/usr/bin/freecadcmd', '/snap/bin/freecad.cmd']: if Path(cmd_path).exists(): - # FreeCAD 1.0 直接执行脚本,不需要 -c 参数 cmd = [cmd_path, str(self.verification_script), str(Path(stp_path_str).absolute())] logger.info(f"找到 FreeCAD 命令路径: {cmd_path}") break - # 尝试2: freecad with offscreen - if not cmd: - try: - result = subprocess.run(['which', 'freecad'], capture_output=True, text=True) - if result.returncode == 0: - cmd = [ - 'env', 'QT_QPA_PLATFORM=offscreen', - 'freecad', '-c', - str(self.verification_script), str(Path(stp_path_str).absolute()) - ] - except: - pass - - # 尝试3: 使用 xvfb-run - if not cmd: - try: - result = subprocess.run(['which', 'xvfb-run'], capture_output=True, text=True) - if result.returncode == 0: - cmd = ['xvfb-run', 'freecad', '-c', str(self.verification_script), str(Path(stp_path_str).absolute())] - except: - pass - if not cmd: logger.warning("FreeCAD 命令行工具不可用,跳过验证") return { @@ -137,29 +109,34 @@ class GeometryVerificationService: env = os.environ.copy() env['QT_QPA_PLATFORM'] = 'offscreen' env['DISPLAY'] = '' + env['FREECAD_USER_HOME'] = '/tmp/freecad_home' + + logger.info(f"工作目录: {stp_dir}") + logger.info(f"STP 文件: {stp_abs_path}") + logger.info(f"验证脚本: {self.verification_script}") # 异步运行子进程 process = await asyncio.create_subprocess_exec( *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, - cwd=str(stp_dir), # 在 STP 文件所在目录运行 + cwd=str(stp_dir), env=env ) - # 增加超时时间到 300 秒(5分钟) + # 30秒超时 try: stdout, stderr = await asyncio.wait_for( process.communicate(), - timeout=300.0 + timeout=30.0 ) except asyncio.TimeoutError: - logger.error("验证脚本执行超时(300秒)") + logger.error("验证脚本执行超时(30秒)") process.kill() await process.wait() return { "status": "error", - "error": "验证脚本执行超时(300秒)", + "error": "验证脚本执行超时(30秒)", "timestamp": datetime.now().isoformat() }