dev
This commit is contained in:
114
domain-api/app/services/import_task_service.py
Normal file
114
domain-api/app/services/import_task_service.py
Normal file
@@ -0,0 +1,114 @@
|
||||
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
|
||||
Reference in New Issue
Block a user