feat(phase7): align generated video storage paths
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from app.config import get_settings
|
||||
from app.core.storage import get_minio_service
|
||||
from .celery_app import celery_app
|
||||
from packages.adapters.sqlalchemy_impl.session import SessionLocal, build_session_factory
|
||||
from packages.adapters.sqlalchemy_impl.generation_task_repository import SQLAlchemyGenerationTaskRepository
|
||||
@@ -18,6 +19,7 @@ def generate_video(task_id: str) -> dict:
|
||||
try:
|
||||
task_repo = SQLAlchemyGenerationTaskRepository(session)
|
||||
video_repo = SQLAlchemyGeneratedVideoRepository(session)
|
||||
storage_service = get_minio_service()
|
||||
|
||||
task = task_repo.get(task_id)
|
||||
if task is None:
|
||||
@@ -28,12 +30,16 @@ def generate_video(task_id: str) -> dict:
|
||||
task.started_at = task.started_at or datetime.now(timezone.utc)
|
||||
task_repo.update(task)
|
||||
|
||||
file_name = f"{task.id}.mp4"
|
||||
storage_key = f"workspaces/{task.workspace_id}/projects/{task.project_id}/generated/{task.id}/{file_name}"
|
||||
file_url = storage_service.get_url(storage_key)
|
||||
|
||||
video = GeneratedVideo.create(
|
||||
workspace_id=task.workspace_id,
|
||||
project_id=task.project_id,
|
||||
generation_task_id=task.id,
|
||||
name=f"{task.id}.mp4",
|
||||
file_url=f"https://example.invalid/generated/{task.id}.mp4",
|
||||
name=file_name,
|
||||
file_url=file_url,
|
||||
file_size=1024,
|
||||
duration=10.0,
|
||||
width=1920,
|
||||
@@ -48,7 +54,7 @@ def generate_video(task_id: str) -> dict:
|
||||
task.completed_at = datetime.now(timezone.utc)
|
||||
task_repo.update(task)
|
||||
|
||||
return {"ok": True, "task_id": task.id, "video_id": video.id}
|
||||
return {"ok": True, "task_id": task.id, "video_id": video.id, "file_url": file_url}
|
||||
except Exception as error:
|
||||
try:
|
||||
task_repo = SQLAlchemyGenerationTaskRepository(session)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Phase**: Phase 7 - 核心视频剪辑业务
|
||||
**状态**: 🔄 进行中
|
||||
**最后更新**: 2026-06-18 20:48 GMT+8
|
||||
**最后更新**: 2026-06-18 20:55 GMT+8
|
||||
|
||||
---
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
- [x] 生成结果最小闭环测试已落地
|
||||
- [x] 生成结果下载地址接口已落地
|
||||
- [x] 下载地址已升级为 MinIO 预签名优先策略
|
||||
- [x] 生成结果输出路径已对齐 workspace/project/task 结构
|
||||
- [ ] 前端主链路联调完成
|
||||
|
||||
### 4. 本轮已完成的具体验证
|
||||
@@ -60,7 +61,7 @@
|
||||
- [x] `tests/integration/test_upload_pipeline.py` 通过
|
||||
- [x] `tests/integration/test_classification_pipeline.py` 通过
|
||||
- [x] `tests/integration/test_projects.py` 通过
|
||||
- [x] `tests/integration/test_generation_pipeline.py` 通过(含生成结果最小闭环、下载地址查询、下载源 URL 稳定性)
|
||||
- [x] `tests/integration/test_generation_pipeline.py` 通过(含生成结果最小闭环、下载地址查询、下载源 URL 稳定性、输出路径结构)
|
||||
- [x] 素材与生成主线相关目录编译检查通过
|
||||
|
||||
---
|
||||
@@ -101,6 +102,7 @@
|
||||
- [x] API / Adapter / Worker 的生成结果流第一轮联调
|
||||
- [x] GeneratedVideo 查询 / 下载地址第一轮打通
|
||||
- [x] 下载地址已接入 MinIO 预签名优先策略
|
||||
- [x] 生成 worker 输出路径已对齐正式目录结构
|
||||
- [ ] 测试补齐与回归验证
|
||||
|
||||
### Step 3:保留 Agent 体系设计,等待 runtime 修复后再恢复实跑
|
||||
@@ -111,7 +113,7 @@
|
||||
|
||||
## 五、当前判断
|
||||
|
||||
**当前 Phase 7 已完成素材前半主链打通,并把生成链推进到“最小可运行闭环 + 结果查询/下载接口可用(预签名优先)”,整体仍保持在既定规则内推进。**
|
||||
**当前 Phase 7 已完成素材前半主链打通,并把生成链推进到“最小可运行闭环 + 结果查询/下载接口可用(预签名优先)+ 输出路径结构对齐”,整体仍保持在既定规则内推进。**
|
||||
|
||||
当前执行策略是:
|
||||
- 暂停 Agent 实跑
|
||||
@@ -129,7 +131,7 @@
|
||||
- 答:Phase 7 - 核心视频剪辑业务
|
||||
|
||||
2. **当前 Phase 主要在做什么?**
|
||||
- 答:已切入 Phase 7 第一批业务开发,当前已完成素材前半主链收口,并把生成链推进到最小可运行闭环与结果查询/下载可用(预签名优先),正在持续提交与 CI/CD 验证
|
||||
- 答:已切入 Phase 7 第一批业务开发,当前已完成素材前半主链收口,并把生成链推进到最小可运行闭环与结果查询/下载可用(预签名优先),输出路径结构也已对齐正式目录,正在持续提交与 CI/CD 验证
|
||||
|
||||
3. **当前最重要的阻塞点是什么?**
|
||||
- 答:OpenClaw 子 Agent runtime 暂不稳定,因此暂停 Agent 实跑;另外数据库字段命名仍有历史包袱,但已通过映射兼容,不阻断主线开发
|
||||
@@ -156,4 +158,4 @@
|
||||
|
||||
---
|
||||
|
||||
**状态结论**:Phase 7 未跑偏,已暂停 Agent 实跑并切回主会话直开;当前素材前半主链已打通,生成链已进入最小可运行闭环且结果查询/下载可用(预签名优先),现继续通过提交与 CI/CD 验证推进。
|
||||
**状态结论**:Phase 7 未跑偏,已暂停 Agent 实跑并切回主会话直开;当前素材前半主链已打通,生成链已进入最小可运行闭环且结果查询/下载可用(预签名优先),输出路径结构已对齐正式目录,现继续通过提交与 CI/CD 验证推进。
|
||||
|
||||
@@ -51,12 +51,16 @@ def simulate_generate_video(task_id: str, task_repo: DummyGenerationTaskReposito
|
||||
task.started_at = task.started_at or datetime.now(timezone.utc)
|
||||
task_repo.update(task)
|
||||
|
||||
file_url = (
|
||||
f"http://localhost:9000/xiaoxia-assets/workspaces/{task.workspace_id}"
|
||||
f"/projects/{task.project_id}/generated/{task.id}/{task.id}.mp4"
|
||||
)
|
||||
video = GeneratedVideo.create(
|
||||
workspace_id=task.workspace_id,
|
||||
project_id=task.project_id,
|
||||
generation_task_id=task.id,
|
||||
name=f"{task.id}.mp4",
|
||||
file_url=f"https://example.invalid/generated/{task.id}.mp4",
|
||||
file_url=file_url,
|
||||
file_size=2048,
|
||||
duration=12.5,
|
||||
width=1920,
|
||||
@@ -71,7 +75,7 @@ def simulate_generate_video(task_id: str, task_repo: DummyGenerationTaskReposito
|
||||
task.completed_at = datetime.now(timezone.utc)
|
||||
task_repo.update(task)
|
||||
|
||||
return {"status": "completed", "task_id": task.id, "video_id": video.id}
|
||||
return {"status": "completed", "task_id": task.id, "video_id": video.id, "file_url": file_url}
|
||||
|
||||
|
||||
def test_create_generation_task_smoke():
|
||||
@@ -112,6 +116,7 @@ def test_generation_pipeline_smoke():
|
||||
result = simulate_generate_video(task.id, task_repo, video_repo)
|
||||
|
||||
assert result["status"] == "completed"
|
||||
assert "/workspaces/ws-1/projects/proj-1/generated/" in result["file_url"]
|
||||
updated_task = task_repo.get(task.id)
|
||||
assert updated_task is not None
|
||||
assert updated_task.status == GenerationTaskStatus.COMPLETED
|
||||
|
||||
Reference in New Issue
Block a user