Files
webmanager-mvp/webui/backend/app/services/task_service.py
T
2026-03-15 13:06:48 +01:00

85 lines
3.2 KiB
Python

from __future__ import annotations
from backend.app.api.errors import AppError
from backend.app.api.schemas import TaskDetailResponse, TaskListItem, TaskListResponse
from backend.app.db.history_repository import HistoryRepository
from backend.app.db.task_repository import TaskRepository
FILE_ACTION_CANCELLABLE_OPERATIONS = {"copy", "move", "duplicate", "delete"}
class TaskService:
def __init__(self, repository: TaskRepository, history_repository: HistoryRepository | None = None):
self._repository = repository
self._history_repository = history_repository
def create_task(self, operation: str, source: str, destination: str) -> TaskDetailResponse:
task = self._repository.create_task(operation=operation, source=source, destination=destination)
return TaskDetailResponse(**task)
def get_task(self, task_id: str) -> TaskDetailResponse:
task = self._repository.get_task(task_id)
if not task:
raise AppError(
code="task_not_found",
message="Task was not found",
status_code=404,
details={"task_id": task_id},
)
return TaskDetailResponse(**task)
def list_tasks(self) -> TaskListResponse:
tasks = self._repository.list_tasks()
return TaskListResponse(
items=[
TaskListItem(
id=task["id"],
operation=task["operation"],
status=task["status"],
source=task["source"],
destination=task["destination"],
created_at=task["created_at"],
finished_at=task["finished_at"],
)
for task in tasks
]
)
def cancel_task(self, task_id: str) -> TaskDetailResponse:
task = self._repository.get_task(task_id)
if not task:
raise AppError(
code="task_not_found",
message="Task was not found",
status_code=404,
details={"task_id": task_id},
)
if task["operation"] not in FILE_ACTION_CANCELLABLE_OPERATIONS:
raise AppError(
code="task_not_cancellable",
message="Task cannot be cancelled",
status_code=409,
details={"task_id": task_id, "status": task["status"]},
)
if task["status"] not in {"queued", "running", "cancelling"}:
raise AppError(
code="task_not_cancellable",
message="Task cannot be cancelled",
status_code=409,
details={"task_id": task_id, "status": task["status"]},
)
updated = self._repository.request_cancellation(task_id)
if not updated:
raise AppError(
code="task_not_cancellable",
message="Task cannot be cancelled",
status_code=409,
details={"task_id": task_id, "status": task["status"]},
)
if updated["status"] == "cancelled" and self._history_repository:
self._history_repository.update_entry(entry_id=task_id, status="cancelled")
return TaskDetailResponse(**updated)