You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

72 lines
2.7 KiB

from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import CrawlTask, CrawlRun
from .serializers import CrawlTaskSerializer, CrawlRunSerializer
class CrawlTaskViewSet(viewsets.ModelViewSet):
"""
ViewSet for CrawlTask models. Supports CRUD and custom trigger/runs actions.
"""
queryset = CrawlTask.objects.all().order_by('-created_at')
serializer_class = CrawlTaskSerializer
@action(detail=True, methods=['post'], url_path='trigger')
def trigger(self, request, pk=None):
task = self.get_object()
# Create a new CrawlRun with status RUNNING
run = CrawlRun.objects.create(
crawl_task=task,
status='RUNNING'
)
# Check if tasks can be imported.
try:
from crawler.tasks import run_crawl_pipeline
# run asynchronously
run_crawl_pipeline.delay(str(run.id), force=True)
is_queued = True
except ImportError:
# Fallback if tasks.py doesn't exist yet or run_crawl_pipeline is not defined
is_queued = False
return Response({
"status": "queued" if is_queued else "queued_stub",
"run_id": str(run.id)
}, status=status.HTTP_202_ACCEPTED)
@action(detail=True, methods=['get'], url_path='runs')
def runs(self, request, pk=None):
task = self.get_object()
runs = task.runs.all().order_by('-started_at')
page = self.paginate_queryset(runs)
if page is not None:
serializer = CrawlRunSerializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = CrawlRunSerializer(runs, many=True)
return Response(serializer.data)
from django.utils import timezone
class CrawlRunViewSet(viewsets.ModelViewSet):
"""
ViewSet for CrawlRun models. Supports CRUD (including DELETE) and stopping active runs.
"""
queryset = CrawlRun.objects.all().order_by('-started_at')
serializer_class = CrawlRunSerializer
@action(detail=True, methods=['post'], url_path='stop')
def stop_run(self, request, pk=None):
run = self.get_object()
if run.status == 'RUNNING':
run.status = 'FAILED'
run.finished_at = timezone.now()
run.error_log = "اجرا توسط کاربر متوقف شد."
run.save()
return Response({"status": "stopped", "run_id": str(run.id)}, status=status.HTTP_200_OK)
return Response({"status": "not_running", "run_id": str(run.id)}, status=status.HTTP_400_BAD_REQUEST)