sprint/Checker/views.py
Administrator 81388144aa minio
2022-08-21 15:20:34 +03:00

121 lines
4.6 KiB
Python

from os.path import join
from tempfile import TemporaryDirectory
from zipfile import ZipFile
from django.core.exceptions import ObjectDoesNotExist
from django.http import JsonResponse, HttpResponse
from django.utils import timezone
from Checker.models import Checker
from Main.models import Solution, SolutionFile, ExtraFile, Progress
from SprintLib.queue import send_to_queue
from SprintLib.redis import lock
from SprintLib.utils import generate_token
def get_dynamic(request):
try:
checker = Checker.objects.get(token=request.GET['token'])
if checker.status == 'Active':
return JsonResponse({"status": "Another checker is working"}, status=403)
checker.dynamic_token = generate_token()
checker.save()
return JsonResponse({"token": checker.dynamic_token})
except ObjectDoesNotExist:
return JsonResponse({"status": "incorrect token"}, status=403)
def status(request):
try:
checker = Checker.objects.get(dynamic_token=request.GET['token'])
now = timezone.now()
checker.last_request = now
checker.save()
return JsonResponse({"status": "ok"})
except ObjectDoesNotExist:
return JsonResponse({"status": "incorrect token"}, status=403)
@lock('checker')
def available(request):
try:
checker = Checker.objects.get(dynamic_token=request.GET['token'])
solution = Solution.objects.filter(set=checker.set, result="In queue").order_by('time_sent').first()
if solution is None:
return JsonResponse({"id": None})
solution.result = "Testing"
solution.save()
checker.testing_solution = solution
checker.save()
with TemporaryDirectory() as tempdir:
with ZipFile(join(tempdir, "package.zip"), 'w') as zip_file:
for sf in SolutionFile.objects.filter(solution=solution):
zip_file.writestr(join('solution', sf.path), sf.bytes)
for ef in ExtraFile.objects.filter(task=solution.task):
zip_file.writestr(ef.filename, ef.bytes)
response = HttpResponse(open(join(tempdir, 'package.zip'), 'rb').read(), content_type='application/octet-stream', status=201)
response.headers['language_id'] = solution.language_id
response.headers['solution_id'] = solution.id
response.headers['timeout'] = solution.task.time_limit
return response
except ObjectDoesNotExist:
return JsonResponse({"status": "incorrect token"}, status=403)
def save_solution(request):
try:
checker = Checker.objects.get(dynamic_token=request.GET['token'])
solution = Solution.objects.get(id=request.GET['solution_id'])
result = request.GET['result']
test = request.GET.get("test")
extras = request.GET.get('extras')
if checker.set != solution.set:
return JsonResponse({"status": "incorrect solution"}, status=403)
solution.result = result
solution.test = test
solution.extras = extras
if result == 'OK':
solution.test = None
solution.save()
if not result.startswith('Testing'):
checker.testing_solution = None
checker.save()
return JsonResponse({"status": True})
except ObjectDoesNotExist:
return JsonResponse({"status": "incorrect token"}, status=403)
def notify(request):
try:
checker = Checker.objects.get(dynamic_token=request.GET['token'])
solution = Solution.objects.get(id=request.GET['solution_id'])
if checker.set != solution.set:
return JsonResponse({"status": "incorrect solution"}, status=403)
send_to_queue("notification", {
"type": "solution",
"solution_id": solution.id
})
return JsonResponse({"status": True})
except ObjectDoesNotExist:
return JsonResponse({"status": "incorrect token"}, status=403)
def save_progress(request):
try:
checker = Checker.objects.get(dynamic_token=request.GET['token'])
solution = Solution.objects.get(id=request.GET['solution_id'])
if checker.set != solution.set:
return JsonResponse({"status": "incorrect solution"}, status=403)
progress = Progress.objects.get(
user=solution.user, task=solution.task
)
if progress.finished_time is None:
progress.finished_time = solution.time_sent
progress.finished = True
progress.save()
progress.increment_rating()
return JsonResponse({"status": True})
except ObjectDoesNotExist:
return JsonResponse({"status": "incorrect token"}, status=403)