chore: auto release commit (2026-09-15 00:49:52)
All checks were successful
技能自动化发布 / release (push) Successful in 4s
All checks were successful
技能自动化发布 / release (push) Successful in 4s
This commit is contained in:
@@ -763,11 +763,21 @@ def collect_all(
|
||||
ctx.close()
|
||||
|
||||
saved = _persist_contracts(contracts)
|
||||
logger.info(
|
||||
"platform_collector: contracts 落库完成 saved=%d / total_fetched=%d",
|
||||
saved, len(contracts),
|
||||
)
|
||||
|
||||
# v1.1.18:每个合同入队 download_tasks(独立事务,失败不影响主流程)
|
||||
contract_ids = [c["contract_id"] for c in contracts if c.get("contract_id")]
|
||||
enqueue_summary = _enqueue_download_tasks_safe(contract_ids)
|
||||
|
||||
return {
|
||||
"platform_url": PLATFORM_URL,
|
||||
"fetched_rows": fetched_rows,
|
||||
"saved_contracts": saved,
|
||||
"downloaded_materials": downloaded,
|
||||
"download_queue": enqueue_summary,
|
||||
"contracts": contracts,
|
||||
}
|
||||
|
||||
@@ -865,14 +875,78 @@ def _persist_contracts(contracts: list[dict]) -> int:
|
||||
datetime.now().isoformat(timespec="seconds"),
|
||||
),
|
||||
)
|
||||
# v1.1.18:每个合同入队 download_tasks(即使已抓到卡片也入队,
|
||||
# process_queue 失败时可用作重试锚点;enqueue_download_task 幂等)
|
||||
repo.enqueue_download_task(conn, c["contract_id"], "platform_button")
|
||||
# v1.1.18 入队 download_tasks 已移到 collect_all 末尾的独立事务,
|
||||
# 见 _enqueue_download_tasks_safe()
|
||||
return len(contracts)
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
def _enqueue_download_tasks_safe(
|
||||
contract_ids: list[str], conn: sqlite3.Connection | None = None,
|
||||
) -> dict:
|
||||
"""v1.1.18:每个合同入队 download_tasks。
|
||||
|
||||
在独立事务里完成,不影响 _persist_contracts 主流程(contracts / materials_content)。
|
||||
任一入队失败 → 记 warning + 计入 failed,但不影响整体返回。
|
||||
|
||||
conn: 可选传入连接(用于测试 in-memory DB)。None → 走 get_connection()。
|
||||
若传入 conn,调用方负责生命周期(不会 close)。
|
||||
|
||||
Returns:
|
||||
{enqueued: N, skipped: M, failed: K, errors: [...]}
|
||||
"""
|
||||
if not contract_ids:
|
||||
return {"enqueued": 0, "skipped": 0, "failed": 0, "errors": []}
|
||||
|
||||
from db.connection import get_connection
|
||||
|
||||
enqueued = 0
|
||||
skipped = 0
|
||||
failed = 0
|
||||
errors: list[str] = []
|
||||
|
||||
owns_conn = conn is None
|
||||
if owns_conn:
|
||||
conn = get_connection()
|
||||
try:
|
||||
for cid in contract_ids:
|
||||
try:
|
||||
# 入队前查一下是否已存在 pending/running → 决定计入 skipped 还是 enqueued
|
||||
pre_existing = conn.execute(
|
||||
"""SELECT 1 FROM download_tasks
|
||||
WHERE contract_id = ? AND kind = ?
|
||||
AND status IN ('pending', 'running') LIMIT 1""",
|
||||
(cid, "platform_button"),
|
||||
).fetchone()
|
||||
repo.enqueue_download_task(conn, cid, "platform_button")
|
||||
if pre_existing:
|
||||
skipped += 1
|
||||
else:
|
||||
enqueued += 1
|
||||
except Exception as e:
|
||||
failed += 1
|
||||
err = f"{cid}: {type(e).__name__}: {e}"
|
||||
errors.append(err)
|
||||
logger.warning(
|
||||
"platform_collector.enqueue: 入队 %s 失败: %s", cid, e,
|
||||
)
|
||||
if owns_conn:
|
||||
conn.commit()
|
||||
finally:
|
||||
if owns_conn:
|
||||
conn.close()
|
||||
|
||||
logger.info(
|
||||
"platform_collector.enqueue: 入队结果 enqueued=%d skipped=%d failed=%d (total=%d)",
|
||||
enqueued, skipped, failed, len(contract_ids),
|
||||
)
|
||||
return {
|
||||
"enqueued": enqueued, "skipped": skipped,
|
||||
"failed": failed, "errors": errors[:10],
|
||||
}
|
||||
|
||||
|
||||
def _download_materials_for_row(
|
||||
page, row_idx: int, contract_id: str, mat_btn_count: int,
|
||||
) -> list[dict]:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"""
|
||||
|
||||
SKILL_SLUG = "alert-contract-expiring-hr"
|
||||
SKILL_VERSION = "1.1.18"
|
||||
SKILL_VERSION = "1.1.19"
|
||||
LOG_LOGGER_NAME = "openclaw.skill.alert_contract_expiring_hr"
|
||||
PLATFORM_KIT_MIN_VERSION = "1.2.11"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user