from django.shortcuts import get_object_or_404, redirect
from django.urls import re_path, reverse
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django.views.decorators.http import require_POST
from oioioi.base.permissions import enforce_condition
from oioioi.contests.admin import ProblemInstanceAdmin
from oioioi.contests.models import ProblemInstance, Submission
from oioioi.contests.utils import contest_exists, is_contest_basicadmin
from oioioi.evalmgr.models import QueuedJob
from oioioi.suspendjudge.models import SuspendedProblem
from oioioi.suspendjudge.utils import is_suspended, is_suspended_on_init
[docs]
class SuspendJudgeProblemInstanceAdminMixin(object):
"""Sets up admin panel for suspendjudge app."""
def __init__(self, *args, **kwargs):
super(SuspendJudgeProblemInstanceAdminMixin, self).__init__(*args, **kwargs)
self.list_display = self.list_display + (
'suspended_on_init_display',
'suspended_on_final_display',
)
[docs]
def _resume(self, instance_id):
get_object_or_404(SuspendedProblem, problem_instance=instance_id).delete()
[docs]
def _rejudge(self, instance_id):
suspended = Submission.objects.filter(
queuedjob__state="SUSPENDED", problem_instance=instance_id
)
for submission in suspended:
QueuedJob.objects.filter(submission=submission).delete()
submission.problem_instance.controller.judge(submission)
[docs]
def _clear_queue(self, instance_id):
QueuedJob.objects.filter(
submission__problem_instance=instance_id, state="SUSPENDED"
).delete()
[docs]
def _suspend(self, problem_instance_id, suspend_init_tests=True):
problem_instance = get_object_or_404(ProblemInstance, pk=problem_instance_id)
SuspendedProblem.objects.get_or_create(
problem_instance=problem_instance, suspend_init_tests=suspend_init_tests
)
[docs]
@method_decorator(enforce_condition(contest_exists & is_contest_basicadmin))
@method_decorator(require_POST)
def resume_and_rejudge_view(self, request, problem_instance_id):
self._resume(problem_instance_id)
self._rejudge(problem_instance_id)
return redirect('oioioiadmin:contests_probleminstance_changelist')
[docs]
@method_decorator(enforce_condition(contest_exists & is_contest_basicadmin))
@method_decorator(require_POST)
def resume_and_clear_view(self, request, problem_instance_id):
self._resume(problem_instance_id)
self._clear_queue(problem_instance_id)
return redirect('oioioiadmin:contests_probleminstance_changelist')
[docs]
@method_decorator(enforce_condition(contest_exists & is_contest_basicadmin))
@method_decorator(require_POST)
def suspend_all_view(self, request, problem_instance_id):
self._suspend(problem_instance_id)
return redirect('oioioiadmin:contests_probleminstance_changelist')
[docs]
@method_decorator(enforce_condition(contest_exists & is_contest_basicadmin))
@method_decorator(require_POST)
def suspend_all_but_init_view(self, request, problem_instance_id):
self._suspend(problem_instance_id, False)
return redirect('oioioiadmin:contests_probleminstance_changelist')
[docs]
def _view_href(self, instance, view_name):
return reverse(
'oioioiadmin:suspendjudge_' + view_name,
kwargs={'problem_instance_id': instance.pk},
)
[docs]
def inline_actions(self, instance):
if is_suspended(instance):
actions = [
(
self._view_href(instance, 'resume_and_rejudge'),
_("Resume and rejudge"),
'POST',
),
(
self._view_href(instance, 'resume_and_clear'),
_("Resume and clear queue"),
'POST',
),
]
else:
actions = [
(
self._view_href(instance, 'suspend_all'),
_("Suspend all tests"),
'POST',
),
(
self._view_href(instance, 'suspend_all_but_init'),
_("Suspend final tests"),
'POST',
),
]
return (
super(SuspendJudgeProblemInstanceAdminMixin, self).inline_actions(instance)
+ actions
)
[docs]
def suspended_on_init_display(self, instance):
return not is_suspended_on_init(instance)
suspended_on_init_display.short_description = _("Judge initial")
suspended_on_init_display.boolean = True
[docs]
def suspended_on_final_display(self, instance):
return not is_suspended(instance)
suspended_on_final_display.short_description = _("Judge final")
suspended_on_final_display.boolean = True
[docs]
def get_urls(self):
urls = super(SuspendJudgeProblemInstanceAdminMixin, self).get_urls()
extra_urls = [
re_path(
r'(?P<problem_instance_id>\d+)/resume_and_rejudge/$',
self.resume_and_rejudge_view,
name='suspendjudge_resume_and_rejudge',
),
re_path(
r'(?P<problem_instance_id>\d+)/resume_and_clear/$',
self.resume_and_clear_view,
name='suspendjudge_resume_and_clear',
),
re_path(
r'(?P<problem_instance_id>\d+)/suspend_all/$',
self.suspend_all_view,
name='suspendjudge_suspend_all',
),
re_path(
r'(?P<problem_instance_id>\d+)/suspend_all_but_init/$',
self.suspend_all_but_init_view,
name='suspendjudge_suspend_all_but_init',
),
]
return extra_urls + urls
ProblemInstanceAdmin.mix_in(SuspendJudgeProblemInstanceAdminMixin)