121 lines
4.9 KiB
Python
121 lines
4.9 KiB
Python
"""
|
|
Copy 任务处理器
|
|
==============
|
|
|
|
管理 AnyToCopy 文案提取的提交与轮询。
|
|
"""
|
|
|
|
import logging
|
|
from typing import Any
|
|
|
|
from app.scheduler.handlers.base import AsyncHandler
|
|
from app.scheduler.models import StateChange
|
|
from app.scheduler.registry import JobRegistry
|
|
from app.scheduler.slot_manager import SlotManager
|
|
from app.services.anytocopy_service import get_anytocopy_service
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
SLOT_KEY = "anytocopy:slots"
|
|
MAX_SLOTS = 5
|
|
|
|
|
|
class CopyHandler(AsyncHandler):
|
|
name = "copy"
|
|
slot_key = SLOT_KEY
|
|
max_slots = MAX_SLOTS
|
|
|
|
async def tick(
|
|
self, jobs: list[Any], registry: JobRegistry, slots: SlotManager
|
|
) -> list[StateChange]:
|
|
changes: list[StateChange] = []
|
|
|
|
for job in jobs:
|
|
params = job.params or {}
|
|
anytocopy_task_id = params.get("anytocopy_task_id")
|
|
video_url = params.get("url", params.get("video_url", ""))
|
|
|
|
if anytocopy_task_id:
|
|
try:
|
|
service = get_anytocopy_service()
|
|
result = await service.query_task(anytocopy_task_id)
|
|
if result.get("code") != 200:
|
|
continue
|
|
data = result.get("data", {})
|
|
status = data.get("status")
|
|
|
|
if status == "SUCCESS":
|
|
result_data = {
|
|
"video_url": video_url,
|
|
"title": data.get("title", ""),
|
|
"content": data.get("content", ""),
|
|
"text_content": data.get("textContent", ""),
|
|
"platform": data.get("platform", ""),
|
|
"duration": data.get("duration", 0),
|
|
}
|
|
await slots.release(SLOT_KEY, job.job_id)
|
|
changes.append(
|
|
StateChange(job_id=job.job_id, field_path="status", value="completed")
|
|
)
|
|
changes.append(
|
|
StateChange(
|
|
job_id=job.job_id, field_path="message", value="文案提取完成"
|
|
)
|
|
)
|
|
changes.append(
|
|
StateChange(job_id=job.job_id, field_path="completed", value=1)
|
|
)
|
|
changes.append(StateChange(job_id=job.job_id, field_path="total", value=1))
|
|
changes.append(
|
|
StateChange(job_id=job.job_id, field_path="result", value=result_data)
|
|
)
|
|
elif status in ("FAILED", "FAILURE"):
|
|
await slots.release(SLOT_KEY, job.job_id)
|
|
changes.append(
|
|
StateChange(job_id=job.job_id, field_path="status", value="failed")
|
|
)
|
|
changes.append(
|
|
StateChange(
|
|
job_id=job.job_id,
|
|
field_path="message",
|
|
value=f"提取失败: {data.get('errorMessage', '未知错误')}",
|
|
)
|
|
)
|
|
changes.append(
|
|
StateChange(
|
|
job_id=job.job_id,
|
|
field_path="error",
|
|
value=data.get("errorMessage", ""),
|
|
)
|
|
)
|
|
except Exception as e:
|
|
logger.error(f"[Copy {job.job_id}] poll error: {e}")
|
|
continue
|
|
|
|
acquired = await slots.acquire(SLOT_KEY, job.job_id, MAX_SLOTS)
|
|
if not acquired:
|
|
continue
|
|
|
|
try:
|
|
service = get_anytocopy_service()
|
|
submit_result = await service.submit_task(video_url)
|
|
if submit_result.get("code") != 200:
|
|
raise Exception(f"提交失败: {submit_result.get('msg')}")
|
|
anytocopy_task_id = submit_result["data"]
|
|
params["anytocopy_task_id"] = anytocopy_task_id
|
|
changes.append(StateChange(job_id=job.job_id, field_path="params", value=params))
|
|
changes.append(
|
|
StateChange(job_id=job.job_id, field_path="message", value="文案提取任务已提交")
|
|
)
|
|
except Exception as e:
|
|
await slots.release(SLOT_KEY, job.job_id)
|
|
changes.append(StateChange(job_id=job.job_id, field_path="status", value="failed"))
|
|
changes.append(
|
|
StateChange(job_id=job.job_id, field_path="message", value=str(e)[:200])
|
|
)
|
|
changes.append(
|
|
StateChange(job_id=job.job_id, field_path="error", value=str(e)[:500])
|
|
)
|
|
|
|
return changes
|