TellmeStpToGlb/services/task_manager.py
sladro b5e18c5c7a feat: 重构转换系统,默认启用层级转换和组件名称保留
## 主要变更
- 创建新的STP文件文本解析器,直接读取文件内容提取组件名称
- 简化CLI和API接口,移除层级和名称保留参数
- 所有转换默认使用层级模式并保留原始组件名称
- 重构转换器类,清理冗余代码

## 技术改进
- 新增 core/stp_parser.py:直接解析PRODUCT和PRODUCT_DEFINITION实体
- 优化 converter.py:统一转换流程,默认层级转换
- 更新 main.py:简化命令行参数,移除 --hierarchy 和 --preserve-names
- 修复 API 错误处理:全局异常处理器返回正确的JSON响应
- 完善 API 精度参数传递:支持自定义精度选项

## 接口变更
- CLI:`python main.py input.stp output.glb` 即可获得层级转换结果
- API:移除 preserve_hierarchy 和 preserve_original_names 参数
- 保持向后兼容:原有的基本用法不变

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-15 10:25:14 +08:00

144 lines
4.7 KiB
Python

#!/usr/bin/env python3
"""
任务管理服务
负责任务的创建、跟踪和状态管理
"""
import asyncio
import uuid
from datetime import datetime
from typing import Dict, Optional
from core.models import ConvertTask, TaskStatus, ConvertOptions
from core.converter import StpToGlbConverter
class TaskManager:
"""任务管理器"""
def __init__(self):
self.tasks: Dict[str, ConvertTask] = {}
self.running_tasks: Dict[str, asyncio.Task] = {}
def create_task(self, input_path: str, output_path: str, options: ConvertOptions) -> ConvertTask:
"""创建新任务"""
task_id = str(uuid.uuid4())
task = ConvertTask(
task_id=task_id,
input_path=input_path,
output_path=output_path,
options=options
)
self.tasks[task_id] = task
return task
def get_task(self, task_id: str) -> Optional[ConvertTask]:
"""获取任务"""
return self.tasks.get(task_id)
def get_all_tasks(self) -> Dict[str, ConvertTask]:
"""获取所有任务"""
return self.tasks.copy()
async def process_task(self, task_id: str) -> None:
"""处理转换任务"""
task = self.tasks.get(task_id)
if not task:
return
# 更新任务状态
task.status = TaskStatus.PROCESSING
task.started_at = datetime.now()
task.message = "开始处理转换任务"
converter = StpToGlbConverter()
# 设置进度回调
def progress_callback(progress: int, message: str):
task.progress = progress
task.message = message
converter.set_progress_callback(progress_callback)
try:
# 默认使用层级转换
await asyncio.get_event_loop().run_in_executor(
None,
converter.convert,
task.input_path,
task.output_path,
task.options.auto_scale,
task.options.auto_center,
task.options.precision.linear_deflection,
task.options.precision.angular_deflection
)
# 标记完成
task.status = TaskStatus.COMPLETED
task.completed_at = datetime.now()
task.progress = 100
task.message = "转换完成"
except Exception as e:
# 标记失败
task.status = TaskStatus.FAILED
task.completed_at = datetime.now()
task.error_message = str(e)
task.message = f"转换失败: {str(e)}"
finally:
# 清理运行任务记录
if task_id in self.running_tasks:
del self.running_tasks[task_id]
async def start_task(self, task_id: str) -> bool:
"""启动任务处理"""
if task_id not in self.tasks:
return False
if task_id in self.running_tasks:
return False # 任务已在运行
# 创建异步任务
asyncio_task = asyncio.create_task(self.process_task(task_id))
self.running_tasks[task_id] = asyncio_task
return True
def cancel_task(self, task_id: str) -> bool:
"""取消任务"""
if task_id in self.running_tasks:
self.running_tasks[task_id].cancel()
del self.running_tasks[task_id]
task = self.tasks.get(task_id)
if task:
task.status = TaskStatus.FAILED
task.error_message = "任务被取消"
task.message = "任务已取消"
task.completed_at = datetime.now()
return True
return False
def cleanup_completed_tasks(self, max_tasks: int = 100) -> None:
"""清理已完成的任务,保持任务数量在限制内"""
if len(self.tasks) <= max_tasks:
return
# 按完成时间排序,保留最新的任务
completed_tasks = [
(task_id, task) for task_id, task in self.tasks.items()
if task.status in [TaskStatus.COMPLETED, TaskStatus.FAILED] and task.completed_at
]
if len(completed_tasks) > max_tasks // 2:
# 删除最老的已完成任务
completed_tasks.sort(key=lambda x: x[1].completed_at)
to_remove = completed_tasks[:len(completed_tasks) - max_tasks // 2]
for task_id, _ in to_remove:
del self.tasks[task_id]
# 全局任务管理器实例
task_manager = TaskManager()