Files
OnlineJudge/flowchart/views/oj.py
2026-05-26 21:25:26 -06:00

214 lines
7.5 KiB
Python

from account.decorators import login_required
from flowchart.models import FlowchartSubmission, FlowchartSubmissionStatus
from flowchart.serializers import (
CreateFlowchartSubmissionSerializer,
FlowchartSubmissionListSerializer,
FlowchartSubmissionSerializer,
)
from flowchart.tasks import evaluate_flowchart_task
from problem.models import Problem
from utils.api import AsyncAPIView
class FlowchartSubmissionAPI(AsyncAPIView):
@login_required
async def post(self, request):
serializer = CreateFlowchartSubmissionSerializer(data=request.data)
if not serializer.is_valid():
return self.error(serializer.errors)
data = serializer.validated_data
try:
problem = await Problem.objects.aget(id=data["problem_id"])
except Problem.DoesNotExist:
return self.error("Problem doesn't exist")
if not problem.allow_flowchart:
return self.error("This problem does not allow flowchart submission")
submission = await FlowchartSubmission.objects.acreate(
user=request.user,
problem=problem,
mermaid_code=data["mermaid_code"],
flowchart_data=data.get("flowchart_data", {}),
)
evaluate_flowchart_task.send(submission.id)
return self.success({"submission_id": submission.id, "status": "pending"})
@login_required
async def get(self, request):
submission_id = request.GET.get("id")
if not submission_id:
return self.error("submission_id is required")
try:
submission = await (
FlowchartSubmission.objects.select_related("user", "problem")
.filter(id=submission_id)
.afirst()
)
if submission is None:
raise FlowchartSubmission.DoesNotExist
except FlowchartSubmission.DoesNotExist:
return self.error("Submission doesn't exist")
if not submission.check_user_permission(request.user):
return self.error("No permission for this submission")
return self.success(await self.async_serialize_data(FlowchartSubmissionSerializer, submission))
class FlowchartSubmissionListAPI(AsyncAPIView):
@login_required
async def get(self, request):
username = request.GET.get("username")
problem_id = request.GET.get("problem_id")
myself = request.GET.get("myself")
queryset = FlowchartSubmission.objects.select_related("user", "problem")
if problem_id:
try:
problem = await Problem.objects.aget(
_id__iexact=problem_id, contest_id__isnull=True, visible=True
)
except Problem.DoesNotExist:
return self.error("Problem doesn't exist")
queryset = queryset.filter(problem=problem)
if myself and myself == "1":
queryset = queryset.filter(user=request.user)
elif username:
queryset = queryset.filter(user__username__icontains=username)
elif request.user.is_regular_user():
queryset = queryset.filter(user=request.user)
data = await self.async_paginate_data(request, queryset)
data["results"] = await self.async_serialize_data(
FlowchartSubmissionListSerializer,
data["results"],
many=True,
)
return self.success(data)
class FlowchartSubmissionRetryAPI(AsyncAPIView):
@login_required
async def post(self, request):
submission_id = request.data.get("submission_id")
if not submission_id:
return self.error("submission_id is required")
try:
submission = await (
FlowchartSubmission.objects.select_related("problem")
.filter(id=submission_id)
.afirst()
)
if submission is None:
raise FlowchartSubmission.DoesNotExist
except FlowchartSubmission.DoesNotExist:
return self.error("Submission doesn't exist")
if not submission.check_user_permission(request.user):
return self.error("No permission for this submission")
if submission.status not in [
FlowchartSubmissionStatus.FAILED,
FlowchartSubmissionStatus.COMPLETED,
]:
return self.error("Submission is not in a state that allows retry")
submission.status = FlowchartSubmissionStatus.PENDING
submission.ai_score = None
submission.ai_grade = None
submission.ai_feedback = None
submission.ai_suggestions = None
submission.ai_criteria_details = {}
submission.processing_time = None
submission.evaluation_time = None
await submission.asave()
evaluate_flowchart_task.send(submission.id)
return self.success(
{
"submission_id": submission.id,
"status": "pending",
"message": "AI evaluation restarted",
}
)
class FlowchartSubmissionDetailAPI(AsyncAPIView):
@login_required
async def get(self, request):
problem_id = request.GET.get("problem_id")
if not problem_id:
return self.error("problem_id is required")
try:
problem = await Problem.objects.aget(id=problem_id)
except Problem.DoesNotExist:
return self.error("Problem doesn't exist")
try:
page = int(request.GET.get("page", 0))
except ValueError:
return self.error("page must be an integer")
submissions = (
FlowchartSubmission.objects.select_related("user", "problem")
.filter(
user=request.user,
problem=problem,
status=FlowchartSubmissionStatus.COMPLETED,
)
.order_by("create_time")
)
count = await submissions.acount()
if count == 0:
return self.success({"submission": None, "count": 0})
if page == 0:
submission = await submissions.alast()
else:
if page < 0 or page > count:
return self.error("Page out of range")
result = [s async for s in submissions[page - 1:page]]
submission = result[0]
data = await self.async_serialize_data(FlowchartSubmissionSerializer, submission)
return self.success({"submission": data, "count": count})
class FlowchartSubmissionCurrentAPI(AsyncAPIView):
@login_required
async def get(self, request):
problem_id = request.GET.get("problem_id")
if not problem_id:
return self.error("problem_id is required")
try:
problem = await Problem.objects.aget(id=problem_id)
except Problem.DoesNotExist:
return self.error("Problem doesn't exist")
submissions = (
FlowchartSubmission.objects.filter(
user=request.user,
problem=problem,
status=FlowchartSubmissionStatus.COMPLETED,
)
.values("ai_score", "ai_grade")
.order_by("-create_time")
)
count = await submissions.acount()
if count == 0:
return self.success({"count": 0, "score": 0, "grade": ""})
submission = await submissions.afirst()
return self.success(
{
"count": count,
"score": submission["ai_score"],
"grade": submission["ai_grade"],
}
)