197 lines
6.4 KiB
Python
197 lines
6.4 KiB
Python
import logging
|
|
import uuid
|
|
|
|
from aiohttp import web
|
|
from aiohttp.web import Request, Response
|
|
|
|
from app.library.config import Config
|
|
from app.library.encoder import Encoder
|
|
from app.library.router import route
|
|
from app.library.Tasks import Task, TaskFailure, TaskResult, Tasks
|
|
from app.library.Utils import init_class, validate_url, validate_uuid
|
|
|
|
LOG: logging.Logger = logging.getLogger(__name__)
|
|
|
|
|
|
@route("POST", "api/tasks/inspect", "task_handler_inspect")
|
|
async def task_handler_inspect(request: Request, tasks: Tasks, encoder: Encoder, config: Config) -> Response:
|
|
data = await request.json()
|
|
|
|
url: str | None = data.get("url") if isinstance(data, dict) else None
|
|
if not url:
|
|
return web.json_response({"error": "url is required."}, status=web.HTTPBadRequest.status_code)
|
|
try:
|
|
validate_url(url, allow_internal=config.allow_internal_urls)
|
|
except ValueError as e:
|
|
return web.json_response({"error": str(e)}, status=web.HTTPBadRequest.status_code)
|
|
|
|
preset: str = data.get("preset", "") if isinstance(data, dict) else ""
|
|
handler_name: str | None = data.get("handler") if isinstance(data, dict) else None
|
|
|
|
try:
|
|
result: TaskResult | TaskFailure = await tasks.get_handler().inspect(
|
|
url=url, preset=preset, handler_name=handler_name
|
|
)
|
|
except Exception as e:
|
|
LOG.exception(e)
|
|
return web.json_response(
|
|
{"error": "Failed to inspect handler.", "message": str(e)},
|
|
status=web.HTTPInternalServerError.status_code,
|
|
)
|
|
|
|
return web.json_response(
|
|
data=result,
|
|
status=web.HTTPBadRequest.status_code if isinstance(result, TaskFailure) else web.HTTPOk.status_code,
|
|
dumps=encoder.encode,
|
|
)
|
|
|
|
|
|
@route("GET", "api/tasks/", "tasks")
|
|
async def tasks(encoder: Encoder) -> Response:
|
|
"""
|
|
Get the tasks.
|
|
|
|
Args:
|
|
encoder (Encoder): The encoder instance.
|
|
|
|
Returns:
|
|
Response: The response object.
|
|
|
|
"""
|
|
return web.json_response(data=Tasks.get_instance().get_all(), status=web.HTTPOk.status_code, dumps=encoder.encode)
|
|
|
|
|
|
@route("PUT", "api/tasks/", "tasks_add")
|
|
async def tasks_add(request: Request, encoder: Encoder) -> Response:
|
|
"""
|
|
Add tasks to the queue.
|
|
|
|
Args:
|
|
request (Request): The request object.
|
|
encoder (Encoder): The encoder instance.
|
|
|
|
Returns:
|
|
Response: The response object
|
|
|
|
"""
|
|
data = await request.json()
|
|
|
|
if not isinstance(data, list):
|
|
return web.json_response(
|
|
{"error": "Invalid request body expecting list with dicts."},
|
|
status=web.HTTPBadRequest.status_code,
|
|
)
|
|
|
|
tasks: list = []
|
|
|
|
ins = Tasks.get_instance()
|
|
|
|
for item in data:
|
|
if not isinstance(item, dict):
|
|
return web.json_response(
|
|
{"error": "Invalid request body expecting list with dicts."},
|
|
status=web.HTTPBadRequest.status_code,
|
|
)
|
|
|
|
if not item.get("url"):
|
|
return web.json_response({"error": "url is required.", "data": item}, status=web.HTTPBadRequest.status_code)
|
|
|
|
if not item.get("id", None) or not validate_uuid(item.get("id"), version=4):
|
|
item["id"] = str(uuid.uuid4())
|
|
|
|
if not item.get("template", None):
|
|
item["template"] = ""
|
|
|
|
if not item.get("cli", None):
|
|
item["cli"] = ""
|
|
|
|
try:
|
|
Tasks.validate(item)
|
|
except ValueError as e:
|
|
return web.json_response(
|
|
{"error": f"Failed to validate task '{item.get('name', '??')}'. '{e!s}'"},
|
|
status=web.HTTPBadRequest.status_code,
|
|
)
|
|
|
|
tasks.append(init_class(Task, item))
|
|
|
|
try:
|
|
tasks = ins.save(tasks=tasks).load().get_all()
|
|
except Exception as e:
|
|
LOG.exception(e)
|
|
return web.json_response(
|
|
{"error": "Failed to save tasks.", "message": str(e)},
|
|
status=web.HTTPInternalServerError.status_code,
|
|
)
|
|
|
|
return web.json_response(data=tasks, status=web.HTTPOk.status_code, dumps=encoder.encode)
|
|
|
|
|
|
@route("POST", "api/tasks/{id}/mark", "tasks_mark")
|
|
async def task_mark(request: Request, encoder: Encoder) -> Response:
|
|
"""
|
|
Mark all items from task as downloaded.
|
|
|
|
Args:
|
|
request (Request): The request object.
|
|
encoder (Encoder): The encoder instance.
|
|
|
|
Returns:
|
|
Response: The response object
|
|
|
|
"""
|
|
task_id: str = request.match_info.get("id", None)
|
|
|
|
if not task_id:
|
|
return web.json_response(data={"error": "No task id."}, status=web.HTTPBadRequest.status_code)
|
|
|
|
tasks: Tasks = Tasks.get_instance()
|
|
try:
|
|
task: Task | None = tasks.get(task_id)
|
|
if not task:
|
|
return web.json_response(
|
|
data={"error": f"Task '{task_id}' does not exist."}, status=web.HTTPNotFound.status_code
|
|
)
|
|
|
|
_status, _message = task.mark()
|
|
if not _status:
|
|
return web.json_response(data={"error": _message}, status=web.HTTPBadRequest.status_code)
|
|
|
|
return web.json_response(data={"message": _message}, status=web.HTTPOk.status_code, dumps=encoder.encode)
|
|
except ValueError as e:
|
|
return web.json_response(data={"error": str(e)}, status=web.HTTPBadRequest.status_code)
|
|
|
|
|
|
@route("DELETE", "api/tasks/{id}/mark", "tasks_unmark")
|
|
async def task_unmark(request: Request, encoder: Encoder) -> Response:
|
|
"""
|
|
Remove All tasks items from download archive.
|
|
|
|
Args:
|
|
request (Request): The request object.
|
|
encoder (Encoder): The encoder instance.
|
|
|
|
Returns:
|
|
Response: The response object
|
|
|
|
"""
|
|
task_id: str = request.match_info.get("id", None)
|
|
|
|
if not task_id:
|
|
return web.json_response(data={"error": "No task id."}, status=web.HTTPBadRequest.status_code)
|
|
|
|
tasks: Tasks = Tasks.get_instance()
|
|
try:
|
|
task: Task | None = tasks.get(task_id)
|
|
if not task:
|
|
return web.json_response(
|
|
data={"error": f"Task '{task_id}' does not exist."}, status=web.HTTPNotFound.status_code
|
|
)
|
|
|
|
_status, _message = task.unmark()
|
|
if not _status:
|
|
return web.json_response(data={"error": _message}, status=web.HTTPBadRequest.status_code)
|
|
|
|
return web.json_response(data={"message": _message}, status=web.HTTPOk.status_code, dumps=encoder.encode)
|
|
except ValueError as e:
|
|
return web.json_response(data={"error": str(e)}, status=web.HTTPBadRequest.status_code)
|