from __future__ import annotations import threading from datetime import datetime from pathlib import Path from uuid import uuid4 from app.core.files import import_root, load_import_records, save_import_records from app.services.import_worker_service import import_domains_from_path _IMPORT_TASK_LOCK = threading.Lock() def _now() -> str: return datetime.now().isoformat(sep=" ", timespec="seconds") def list_import_tasks() -> list[dict]: return load_import_records() def _save_tasks(tasks: list[dict]) -> None: save_import_records(tasks) def _update_task(task_id: str, **patch: object) -> dict | None: with _IMPORT_TASK_LOCK: tasks = load_import_records() target = next((item for item in tasks if item["task_id"] == task_id), None) if not target: return None target.update(patch) target["updated_at"] = _now() _save_tasks(tasks) return dict(target) def _run_import_task(task_id: str, file_path: str, source_type: int = 7) -> None: _update_task(task_id, status="running", started_at=_now(), message="导入任务开始执行") try: result = import_domains_from_path(Path(file_path), source_type=source_type) stats = result.get("stats", {}) _update_task( task_id, status="completed", completed_at=_now(), result=result, message=( f"导入完成:总数 {stats.get('total', 0)},有效 {stats.get('valid', 0)}," f"新增 {stats.get('added', 0)},已存在 {stats.get('exists', 0)},无效 {stats.get('invalid', 0)}" ), ) except Exception as exc: _update_task( task_id, status="failed", completed_at=_now(), message=f"导入失败:{exc}", ) def create_import_task(content: bytes, filename: str, source_type: int = 7) -> dict: task_id = uuid4().hex safe_name = Path(filename).name or "domains.txt" target = import_root() / f"{task_id}_{safe_name}" target.write_bytes(content) record = { "task_id": task_id, "filename": safe_name, "stored_path": str(target), "source_type": source_type, "status": "queued", "message": "文件已接收,等待处理", "created_at": _now(), "updated_at": _now(), "started_at": "", "completed_at": "", "result": None, } with _IMPORT_TASK_LOCK: tasks = load_import_records() tasks.insert(0, record) _save_tasks(tasks) worker = threading.Thread(target=_run_import_task, args=(task_id, str(target), source_type), daemon=True) worker.start() return record def retry_import_task(task_id: str) -> dict: with _IMPORT_TASK_LOCK: tasks = load_import_records() target = next((item for item in tasks if item["task_id"] == task_id), None) if not target: raise ValueError("导入任务不存在") if target.get("status") == "running": raise ValueError("导入任务正在运行,不能重复执行") target["status"] = "queued" target["message"] = "任务已重新加入队列" target["started_at"] = "" target["completed_at"] = "" target["updated_at"] = _now() target["result"] = None _save_tasks(tasks) stored_path = target["stored_path"] source_type = int(target.get("source_type", 7)) record = dict(target) worker = threading.Thread(target=_run_import_task, args=(task_id, stored_path, source_type), daemon=True) worker.start() return record