feat(collect): show per-item collection activity timer

This commit is contained in:
chengma
2026-07-14 11:10:36 +08:00
parent da1da13fdf
commit 0abd7ffdff
4 changed files with 494 additions and 9 deletions
+115 -1
View File
@@ -7,6 +7,11 @@ import re
import threading
import time
try:
from PySide6.QtCore import Signal
except ModuleNotFoundError: # pragma: no cover - GUI import guard
Signal = None
from .. import ai, image_studio, image_studio_export, image_studio_generation, image_studio_images
from ..collect_skip import ALIAS_UNMATCHED, LOGIN_REQUIRED, empty_skip_reason_counts
from .widgets import *
@@ -1743,6 +1748,9 @@ class ApplyWorker(BaseWorker):
class CollectWorker(BaseWorker):
"""Collect old title and cover for imported tasks."""
if Signal is not None:
activity = Signal(dict)
LOGIN_CHECK_ATTEMPTS = 3
LOGIN_CHECK_RETRY_DELAY_SECONDS = 2.0
@@ -1785,6 +1793,11 @@ class CollectWorker(BaseWorker):
skip_reason_counts = empty_skip_reason_counts()
self._run_id = self._create_run_log(eligible, batch_ids)
self._emit_activity(
"preflight_started",
total=total,
step="preflight",
)
self._log_run_event(
f"step=preflight result=start detail=采集运行开始 total={total}"
)
@@ -1822,9 +1835,16 @@ class CollectWorker(BaseWorker):
level="warning",
)
for task in eligible:
for index, task in enumerate(eligible, start=1):
if self.should_cancel():
break
self._emit_activity(
"task_started",
task=task,
index=index,
total=total,
step="match_account",
)
account = account_by_alias.get(str(task.alias).strip())
if account is None:
skipped += 1
@@ -1842,6 +1862,14 @@ class CollectWorker(BaseWorker):
task=task,
level="warning",
)
self._emit_activity(
"task_finished",
task=task,
index=index,
total=total,
step="match_account",
result="skipped",
)
self._emit_progress(done, total, collected, skipped, failed)
continue
@@ -1862,9 +1890,24 @@ class CollectWorker(BaseWorker):
task=task,
level="warning",
)
self._emit_activity(
"task_finished",
task=task,
index=index,
total=total,
step="check_login",
result="skipped",
)
self._emit_progress(done, total, collected, skipped, failed)
continue
self._emit_activity(
"task_step",
task=task,
index=index,
total=total,
step="check_login",
)
status = self._confirmed_login_status(account, context="midrun", task=task)
if self._is_definitive_logged_out(status):
alias = str(task.alias).strip()
@@ -1885,6 +1928,14 @@ class CollectWorker(BaseWorker):
task=task,
level="warning",
)
self._emit_activity(
"task_finished",
task=task,
index=index,
total=total,
step="check_login",
result="skipped",
)
self._emit_progress(done, total, collected, skipped, failed)
continue
if not status.get("logged_in"):
@@ -1900,10 +1951,18 @@ class CollectWorker(BaseWorker):
started = time.monotonic()
current_step = "db_write"
activity_result = "success"
def on_step(step):
nonlocal current_step
current_step = str(step)
self._emit_activity(
"task_step",
task=task,
index=index,
total=total,
step=current_step,
)
self._log_run_event(
"step={step} result=start detail=任务 {task_id} 商品 {item_id}".format(
step=current_step,
@@ -1914,6 +1973,13 @@ class CollectWorker(BaseWorker):
)
try:
self._emit_activity(
"task_step",
task=task,
index=index,
total=total,
step="prepare_task",
)
self._log_run_event(
"step=db_write result=start detail=任务 {task_id} 商品 {item_id} 标记采集运行".format(
task_id=task.id,
@@ -1932,6 +1998,13 @@ class CollectWorker(BaseWorker):
on_step=on_step,
)
current_step = "db_write"
self._emit_activity(
"task_step",
task=task,
index=index,
total=total,
step="save_result",
)
self._log_run_event(
"step=db_write result=start detail=任务 {task_id} 商品 {item_id} 保存采集结果".format(
task_id=task.id,
@@ -1965,6 +2038,7 @@ class CollectWorker(BaseWorker):
task=task,
)
except Exception as exc:
activity_result = "failed"
failed += 1
error = str(exc) or exc.__class__.__name__
safe_error = diagnostics.redact_log_text(error)
@@ -1993,6 +2067,14 @@ class CollectWorker(BaseWorker):
)
finally:
done += 1
self._emit_activity(
"task_finished",
task=task,
index=index,
total=total,
step=current_step,
result=activity_result,
)
self._emit_progress(done, total, collected, skipped, failed)
summary = self._summary(
@@ -2115,6 +2197,38 @@ class CollectWorker(BaseWorker):
payload["reason"] = reason
return payload
def _emit_activity(
self,
state,
*,
task=None,
index=0,
total=0,
step=None,
result=None,
):
signal = getattr(self, "activity", None)
if signal is None:
return
payload = {
"state": str(state),
"index": int(index or 0),
"total": int(total or 0),
}
if task is not None:
payload.update(
{
"task_id": getattr(task, "id", None),
"item_id": str(getattr(task, "item_id", "") or ""),
"alias": str(getattr(task, "alias", "") or ""),
}
)
if step:
payload["step"] = str(step)
if result:
payload["result"] = str(result)
signal.emit(payload)
def _emit_progress(self, done, total, collected, skipped, failed):
self.progress.emit(
{