feat: add contest clone API endpoint
This commit is contained in:
@@ -107,3 +107,7 @@ class ACMContesHelperSerializer(serializers.Serializer):
|
|||||||
problem_id = serializers.CharField()
|
problem_id = serializers.CharField()
|
||||||
rank_id = serializers.IntegerField()
|
rank_id = serializers.IntegerField()
|
||||||
checked = serializers.BooleanField()
|
checked = serializers.BooleanField()
|
||||||
|
|
||||||
|
|
||||||
|
class ContestCloneSerializer(serializers.Serializer):
|
||||||
|
contest_id = serializers.IntegerField()
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from ..views.admin import ACMContestHelper, ContestAnnouncementAPI, ContestAPI, DownloadContestSubmissions
|
from ..views.admin import ACMContestHelper, ContestAnnouncementAPI, ContestAPI, ContestCloneAPI, DownloadContestSubmissions
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("contest", ContestAPI.as_view()),
|
path("contest", ContestAPI.as_view()),
|
||||||
|
path("contest/clone", ContestCloneAPI.as_view()),
|
||||||
path("contest/announcement", ContestAnnouncementAPI.as_view()),
|
path("contest/announcement", ContestAnnouncementAPI.as_view()),
|
||||||
path("contest/acm_helper", ACMContestHelper.as_view()),
|
path("contest/acm_helper", ACMContestHelper.as_view()),
|
||||||
path("download_submissions", DownloadContestSubmissions.as_view()),
|
path("download_submissions", DownloadContestSubmissions.as_view()),
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
import zipfile
|
import zipfile
|
||||||
|
from datetime import timedelta
|
||||||
from ipaddress import ip_network
|
from ipaddress import ip_network
|
||||||
|
|
||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
from django.http import FileResponse
|
from django.http import FileResponse
|
||||||
|
from django.utils.timezone import now
|
||||||
|
|
||||||
from account.decorators import super_admin_required
|
from account.decorators import super_admin_required
|
||||||
from account.models import User
|
from account.models import User
|
||||||
@@ -21,6 +23,7 @@ from ..serializers import (
|
|||||||
ACMContesHelperSerializer,
|
ACMContesHelperSerializer,
|
||||||
ContestAdminSerializer,
|
ContestAdminSerializer,
|
||||||
ContestAnnouncementSerializer,
|
ContestAnnouncementSerializer,
|
||||||
|
ContestCloneSerializer,
|
||||||
CreateConetestSeriaizer,
|
CreateConetestSeriaizer,
|
||||||
CreateContestAnnouncementSerializer,
|
CreateContestAnnouncementSerializer,
|
||||||
EditConetestSeriaizer,
|
EditConetestSeriaizer,
|
||||||
@@ -279,3 +282,68 @@ class DownloadContestSubmissions(APIView):
|
|||||||
f"attachment;filename={os.path.basename(zip_path)}"
|
f"attachment;filename={os.path.basename(zip_path)}"
|
||||||
)
|
)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
|
|
||||||
|
class ContestCloneAPI(APIView):
|
||||||
|
@validate_serializer(ContestCloneSerializer)
|
||||||
|
@super_admin_required
|
||||||
|
def post(self, request):
|
||||||
|
try:
|
||||||
|
original = Contest.objects.get(id=request.data["contest_id"])
|
||||||
|
except Contest.DoesNotExist:
|
||||||
|
return self.error("Contest does not exist")
|
||||||
|
|
||||||
|
duration = original.end_time - original.start_time
|
||||||
|
new_start = now() + timedelta(minutes=10)
|
||||||
|
new_end = new_start + duration
|
||||||
|
|
||||||
|
new_contest = Contest.objects.create(
|
||||||
|
title=original.title,
|
||||||
|
description=original.description,
|
||||||
|
tag=original.tag,
|
||||||
|
rule_type=original.rule_type,
|
||||||
|
password=original.password,
|
||||||
|
real_time_rank=original.real_time_rank,
|
||||||
|
visible=original.visible,
|
||||||
|
allowed_ip_ranges=original.allowed_ip_ranges,
|
||||||
|
start_time=new_start,
|
||||||
|
end_time=new_end,
|
||||||
|
created_by=request.user,
|
||||||
|
)
|
||||||
|
|
||||||
|
for problem in Problem.objects.filter(contest=original):
|
||||||
|
new_problem = Problem.objects.create(
|
||||||
|
_id=problem._id,
|
||||||
|
contest=new_contest,
|
||||||
|
is_public=problem.is_public,
|
||||||
|
title=problem.title,
|
||||||
|
description=problem.description,
|
||||||
|
input_description=problem.input_description,
|
||||||
|
output_description=problem.output_description,
|
||||||
|
samples=problem.samples,
|
||||||
|
test_case_id=problem.test_case_id,
|
||||||
|
test_case_score=problem.test_case_score,
|
||||||
|
hint=problem.hint,
|
||||||
|
languages=problem.languages,
|
||||||
|
template=problem.template,
|
||||||
|
created_by=request.user,
|
||||||
|
time_limit=problem.time_limit,
|
||||||
|
memory_limit=problem.memory_limit,
|
||||||
|
io_mode=problem.io_mode,
|
||||||
|
rule_type=problem.rule_type,
|
||||||
|
visible=problem.visible,
|
||||||
|
difficulty=problem.difficulty,
|
||||||
|
source=problem.source,
|
||||||
|
prompt=problem.prompt,
|
||||||
|
answers=problem.answers,
|
||||||
|
total_score=problem.total_score,
|
||||||
|
share_submission=problem.share_submission,
|
||||||
|
allow_flowchart=problem.allow_flowchart,
|
||||||
|
mermaid_code=problem.mermaid_code,
|
||||||
|
flowchart_data=problem.flowchart_data,
|
||||||
|
flowchart_hint=problem.flowchart_hint,
|
||||||
|
show_flowchart=problem.show_flowchart,
|
||||||
|
)
|
||||||
|
new_problem.tags.set(problem.tags.all())
|
||||||
|
|
||||||
|
return self.success(ContestAdminSerializer(new_contest).data)
|
||||||
|
|||||||
Reference in New Issue
Block a user