#!/usr/bin/env python3 """检查 crawler-plugin 的 Plan 任务是否全部完成。""" from __future__ import annotations import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parent PROGRESS_PATH = ROOT / "progress.json" def main() -> int: if not PROGRESS_PATH.is_file(): print("progress.json not found", file=sys.stderr) return 2 try: data = json.loads(PROGRESS_PATH.read_text(encoding="utf-8")) except Exception as exc: print(f"invalid progress.json: {exc}", file=sys.stderr) return 2 total = data.get("total_tasks") tasks = data.get("tasks") if not isinstance(total, int) or total <= 0 or not isinstance(tasks, list): print("invalid progress shape", file=sys.stderr) return 2 if len(tasks) != total: print(f"task count mismatch: total_tasks={total}, tasks={len(tasks)}", file=sys.stderr) return 2 ids = [task.get("id") for task in tasks if isinstance(task, dict)] if ids != list(range(1, total + 1)): print("task ids are not contiguous from 1", file=sys.stderr) return 2 pending = [task for task in tasks if task.get("status") != "done"] completed = total - len(pending) if pending: print(f"{len(pending)} tasks remaining out of {total}") for task in pending[:20]: print(f" task {task.get('id')}: {task.get('status')}") if len(pending) > 20: print(f" ... and {len(pending) - 20} more") print("all tasks done: false") return 1 print("all tasks done") print(f"total: {total}, completed: {completed}, rounds: {data.get('rounds', 0)}") return 0 if __name__ == "__main__": raise SystemExit(main())