NDOJ/judge/views/resolver.py

156 lines
6 KiB
Python
Raw Normal View History

2022-12-19 01:01:02 +00:00
from django.views.generic import TemplateView
2022-12-18 23:53:28 +00:00
from django.utils.translation import gettext as _
2023-11-17 02:16:22 +00:00
from django.http import HttpResponseForbidden, JsonResponse
2022-12-20 11:27:04 +00:00
from judge.models import Contest
from django.utils.safestring import mark_safe
import json
2022-12-18 23:53:28 +00:00
2022-12-20 08:24:24 +00:00
2022-12-19 01:01:02 +00:00
class Resolver(TemplateView):
title = _("Resolver")
template_name = "resolver/resolver.html"
2022-12-20 11:27:04 +00:00
def get_contest_json(self):
problems = self.contest.contest_problems.values_list("order", "id")
order_to_id = {}
id_to_order = {}
for order, problem_id in problems:
id_to_order[str(problem_id)] = order
2023-01-02 23:22:45 +00:00
hidden_subtasks = self.contest.format.get_hidden_subtasks()
2022-12-20 11:27:04 +00:00
num_problems = len(problems)
problem_sub = [0] * num_problems
2023-11-17 02:16:22 +00:00
sub_frozen = [[] for _ in range(num_problems)]
2022-12-20 11:27:04 +00:00
problems_json = {str(i): {} for i in range(1, num_problems + 1)}
users = {}
cnt_user = 0
total_subtask_points_map = {}
for participation in self.contest.users.filter(virtual=0):
cnt_user += 1
users[str(cnt_user)] = {
2023-10-11 00:37:36 +00:00
"username": participation.user.username,
"name": participation.user.first_name or participation.user.username,
"school": participation.user.last_name,
2022-12-29 00:37:40 +00:00
"last_submission": participation.cumtime_final,
2022-12-20 11:27:04 +00:00
"problems": {},
}
for (
problem_id,
problem_points,
time,
subtask_points,
total_subtask_points,
subtask,
sub_id,
) in self.contest.format.get_results_by_subtask(participation, True):
2023-03-17 16:53:19 +00:00
subtask = subtask or 1
2022-12-20 11:27:04 +00:00
problem_id = str(problem_id)
order = id_to_order[problem_id]
problem_sub[order - 1] = max(problem_sub[order - 1], subtask)
if total_subtask_points:
total_subtask_points_map[(order, subtask)] = total_subtask_points
cnt_user = 0
for participation in self.contest.users.filter(virtual=0):
cnt_user += 1
total_points = {}
points_map = {}
frozen_points_map = {}
problem_points_map = {}
for (
problem_id,
problem_points,
time,
subtask_points,
total_subtask_points,
subtask,
sub_id,
) in self.contest.format.get_results_by_subtask(participation, True):
2023-03-17 16:53:19 +00:00
subtask = subtask or 1
2022-12-20 11:27:04 +00:00
problem_id = str(problem_id)
order = id_to_order[problem_id]
points_map[(order, subtask)] = subtask_points
if order not in total_points:
total_points[order] = 0
total_points[order] += total_subtask_points
problem_points_map[order] = problem_points
for (
problem_id,
problem_points,
time,
subtask_points,
total_subtask_points,
subtask,
sub_id,
) in self.contest.format.get_results_by_subtask(participation, False):
2023-03-17 16:53:19 +00:00
subtask = subtask or 1
2022-12-20 11:27:04 +00:00
problem_id = str(problem_id)
order = id_to_order[problem_id]
frozen_points_map[(order, subtask)] = subtask_points
for order in range(1, num_problems + 1):
for subtask in range(1, problem_sub[order - 1] + 1):
if not total_points.get(order, 0):
continue
if str(order) not in users[str(cnt_user)]["problems"]:
users[str(cnt_user)]["problems"][str(order)] = {
"points": {},
"frozen_points": {},
}
problems_json[str(order)][str(subtask)] = round(
total_subtask_points_map[(order, subtask)]
/ total_points[order]
* problem_points_map[order],
self.contest.points_precision,
)
users[str(cnt_user)]["problems"][str(order)]["points"][
str(subtask)
] = round(
points_map.get((order, subtask), 0)
/ total_points[order]
* problem_points_map[order],
self.contest.points_precision,
)
users[str(cnt_user)]["problems"][str(order)]["frozen_points"][
str(subtask)
] = round(
frozen_points_map.get((order, subtask), 0)
/ total_points[order]
* problem_points_map[order],
self.contest.points_precision,
)
2023-01-02 23:22:45 +00:00
for i in hidden_subtasks:
2022-12-20 11:27:04 +00:00
order = id_to_order[i]
2023-11-17 02:16:22 +00:00
sub_frozen[order - 1] = list(hidden_subtasks[i])
2022-12-20 11:27:04 +00:00
return {
"problem_sub": problem_sub,
"sub_frozen": sub_frozen,
"problems": problems_json,
"users": users,
}
2022-12-19 01:01:02 +00:00
def get_context_data(self, **kwargs):
context = super(Resolver, self).get_context_data(**kwargs)
2022-12-20 11:27:04 +00:00
context["contest_json"] = mark_safe(json.dumps(self.get_contest_json()))
2022-12-19 01:01:02 +00:00
return context
def get(self, request, *args, **kwargs):
2023-11-17 02:16:22 +00:00
if not request.user.is_superuser:
return HttpResponseForbidden()
self.contest = Contest.objects.get(key=kwargs.get("contest"))
if not self.contest.format.has_hidden_subtasks:
return HttpResponseForbidden()
if self.request.GET.get("json"):
json_dumps_params = {"ensure_ascii": False}
return JsonResponse(
self.get_contest_json(), json_dumps_params=json_dumps_params
)
return super(Resolver, self).get(request, *args, **kwargs)