feat: add parser source dashboard and scheduling
All checks were successful
CI/CD Pipeline / Code Quality Checks (pull_request) Successful in 1m55s
CI/CD Pipeline / Run Tests (pull_request) Successful in 3m6s
CI/CD Pipeline / Run API Inventory E2E Tests (pull_request) Successful in 2m48s
CI/CD Pipeline / Telegram Notify Success (pull_request) Successful in 19s

This commit is contained in:
2026-04-28 01:08:51 +02:00
parent 1249071a33
commit 26d61f7181
58 changed files with 7713 additions and 141 deletions

View File

@@ -21,6 +21,7 @@ from apps.core.serializers import (
from django.conf import settings
from django.db import connection
from django.http import StreamingHttpResponse
from drf_yasg import openapi
from drf_yasg.utils import swagger_auto_schema
from rest_framework import status
from rest_framework.exceptions import ValidationError
@@ -354,6 +355,59 @@ class BackgroundJobStreamView(BackgroundJobStatusView):
return response
class BackgroundJobControlView(BackgroundJobStatusView):
"""Управление фоновой задачей: сейчас поддерживается revoke."""
@swagger_auto_schema(
tags=[JOBS_TAG],
operation_summary="Управление задачей",
operation_description="Отзывает Celery задачу по action=revoke.",
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
"action": openapi.Schema(
type=openapi.TYPE_STRING,
enum=["revoke"],
),
"terminate": openapi.Schema(type=openapi.TYPE_BOOLEAN),
},
),
responses={
200: BackgroundJobSerializer,
400: CommonResponses.BAD_REQUEST,
403: CommonResponses.FORBIDDEN,
404: CommonResponses.NOT_FOUND,
**ErrorResponses.AUTHENTICATED,
},
)
def post(self, request: Request, task_id: str) -> Response:
from apps.core.models import JobStatus
from apps.core.services import BackgroundJobService
from celery import current_app
job = BackgroundJobService.get_by_task_id(task_id)
access_error = self._check_access(request, job)
if access_error is not None:
return access_error
action = request.data.get("action", "revoke")
if action != "revoke":
return Response(
{"detail": "Поддерживается только action=revoke"},
status=status.HTTP_400_BAD_REQUEST,
)
current_app.control.revoke(
task_id,
terminate=bool(request.data.get("terminate", False)),
)
if not job.is_finished:
job.status = JobStatus.REVOKED
job.progress_message = "Задача отозвана пользователем"
job.save(update_fields=["status", "progress_message", "updated_at"])
return Response(BackgroundJobSerializer(job).data)
class BackgroundJobListView(APIView):
"""
Список фоновых задач пользователя.