T-564 async cmhub image tasks
This commit is contained in:
@@ -46,6 +46,7 @@ FAILURE_STEP_LABELS = {
|
||||
"cover_submit": "提交封面任务",
|
||||
"cover_build_request": "构建封面请求",
|
||||
"cover_request": "请求生成封面",
|
||||
"cover_poll": "等待封面结果",
|
||||
"cover_download": "下载新封面",
|
||||
"cover_save": "保存新封面",
|
||||
"cover_parse_response": "解析封面响应",
|
||||
@@ -138,6 +139,8 @@ class Task:
|
||||
old_cover_path: Optional[str]
|
||||
new_title: Optional[str]
|
||||
new_cover_path: Optional[str]
|
||||
image_task_id: Optional[str]
|
||||
image_task_key: Optional[str]
|
||||
committed: int
|
||||
stage: str
|
||||
status: str
|
||||
@@ -231,6 +234,8 @@ CREATE TABLE IF NOT EXISTS tasks (
|
||||
old_cover_path TEXT,
|
||||
new_title TEXT,
|
||||
new_cover_path TEXT,
|
||||
image_task_id TEXT,
|
||||
image_task_key TEXT,
|
||||
committed INTEGER NOT NULL DEFAULT 0,
|
||||
stage TEXT NOT NULL DEFAULT 'imported',
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
@@ -355,6 +360,7 @@ def init_db(path=None, conn=None) -> None:
|
||||
with database:
|
||||
database.executescript(SCHEMA_SQL)
|
||||
_ensure_batch_delete_columns(database)
|
||||
_ensure_task_image_task_columns(database)
|
||||
|
||||
|
||||
def _ensure_batch_delete_columns(database):
|
||||
@@ -364,6 +370,14 @@ def _ensure_batch_delete_columns(database):
|
||||
if "deleted_reason" not in columns:
|
||||
database.execute("ALTER TABLE batches ADD COLUMN deleted_reason TEXT")
|
||||
|
||||
|
||||
def _ensure_task_image_task_columns(database):
|
||||
columns = {row["name"] for row in database.execute("PRAGMA table_info(tasks)").fetchall()}
|
||||
if "image_task_id" not in columns:
|
||||
database.execute("ALTER TABLE tasks ADD COLUMN image_task_id TEXT")
|
||||
if "image_task_key" not in columns:
|
||||
database.execute("ALTER TABLE tasks ADD COLUMN image_task_key TEXT")
|
||||
|
||||
def create_batch(file_paths: Iterable[str], note=None, path=None, conn=None) -> str:
|
||||
batch_id = datetime.now().strftime("%Y%m%d_%H%M%S_") + uuid.uuid4().hex[:8]
|
||||
files = [os.path.abspath(file_path) for file_path in file_paths]
|
||||
@@ -688,6 +702,79 @@ def mark_skipped(task_id, reason, path=None, conn=None) -> None:
|
||||
)
|
||||
|
||||
|
||||
def ensure_image_task_key(task_id, path=None, conn=None) -> str:
|
||||
"""Return a stable cmhub image idempotency key for the current cover attempt."""
|
||||
|
||||
task_id = int(task_id)
|
||||
with _connection(conn, path) as database:
|
||||
with database:
|
||||
row = database.execute(
|
||||
"SELECT image_task_key FROM tasks WHERE id = ?",
|
||||
(task_id,),
|
||||
).fetchone()
|
||||
if row is None:
|
||||
raise DbError(f"任务不存在: {task_id}")
|
||||
key = str(row["image_task_key"] or "").strip()
|
||||
if not key:
|
||||
key = f"cmshopee-task-{task_id}-{uuid.uuid4().hex}"
|
||||
database.execute(
|
||||
"""
|
||||
UPDATE tasks
|
||||
SET image_task_key = ?, updated_at = ?
|
||||
WHERE id = ?
|
||||
""",
|
||||
(key, _now(), task_id),
|
||||
)
|
||||
return key
|
||||
|
||||
|
||||
def set_image_task_submitted(task_id, image_task_id, image_task_key=None, path=None, conn=None) -> None:
|
||||
"""Persist the cmhub image task id immediately after submit succeeds."""
|
||||
|
||||
task_id = int(task_id)
|
||||
image_task_id = str(image_task_id or "").strip()
|
||||
if not image_task_id:
|
||||
raise DbError("缺少 cmhub 生图任务ID")
|
||||
with _connection(conn, path) as database:
|
||||
with database:
|
||||
row = database.execute(
|
||||
"SELECT image_task_key FROM tasks WHERE id = ?",
|
||||
(task_id,),
|
||||
).fetchone()
|
||||
if row is None:
|
||||
raise DbError(f"任务不存在: {task_id}")
|
||||
key = str(image_task_key or row["image_task_key"] or "").strip()
|
||||
if not key:
|
||||
key = f"cmshopee-task-{task_id}-{uuid.uuid4().hex}"
|
||||
database.execute(
|
||||
"""
|
||||
UPDATE tasks
|
||||
SET image_task_id = ?,
|
||||
image_task_key = ?,
|
||||
updated_at = ?
|
||||
WHERE id = ?
|
||||
""",
|
||||
(image_task_id, key, _now(), task_id),
|
||||
)
|
||||
|
||||
|
||||
def clear_image_task(task_id, path=None, conn=None) -> None:
|
||||
"""Clear persisted cmhub image task state so the next cover run can submit anew."""
|
||||
|
||||
with _connection(conn, path) as database:
|
||||
with database:
|
||||
database.execute(
|
||||
"""
|
||||
UPDATE tasks
|
||||
SET image_task_id = NULL,
|
||||
image_task_key = NULL,
|
||||
updated_at = ?
|
||||
WHERE id = ?
|
||||
""",
|
||||
(_now(), int(task_id)),
|
||||
)
|
||||
|
||||
|
||||
def set_collected(task_id, old_title, old_cover_path, path=None, conn=None) -> None:
|
||||
now = _now()
|
||||
with _connection(conn, path) as database:
|
||||
@@ -821,19 +908,23 @@ def reset_generated(
|
||||
now = _now()
|
||||
new_title = None if reset_title else before.new_title
|
||||
new_cover = None if reset_cover else before.new_cover_path
|
||||
image_task_id = None if reset_cover else before.image_task_id
|
||||
image_task_key = None if reset_cover else before.image_task_key
|
||||
with database:
|
||||
database.execute(
|
||||
"""
|
||||
UPDATE tasks
|
||||
SET new_title = ?,
|
||||
new_cover_path = ?,
|
||||
image_task_id = ?,
|
||||
image_task_key = ?,
|
||||
stage = 'generated',
|
||||
status = 'success',
|
||||
last_error = NULL,
|
||||
updated_at = ?
|
||||
WHERE id = ?
|
||||
""",
|
||||
(new_title, new_cover, now, int(task_id)),
|
||||
(new_title, new_cover, image_task_id, image_task_key, now, int(task_id)),
|
||||
)
|
||||
after = get_task(task_id, conn=database)
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user