2020-01-21 06:35:58 +00:00
|
|
|
from django.urls import reverse
|
|
|
|
from django.utils.html import format_html
|
|
|
|
from django.utils.translation import gettext as _
|
|
|
|
|
|
|
|
from judge.models import Submission
|
|
|
|
from judge.utils.problems import get_result_data
|
|
|
|
from judge.utils.raw_sql import join_sql_subquery
|
|
|
|
from judge.views.submission import ForceContestMixin, ProblemSubmissions
|
|
|
|
|
2022-05-14 17:57:27 +00:00
|
|
|
__all__ = ["RankedSubmissions", "ContestRankedSubmission"]
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
class RankedSubmissions(ProblemSubmissions):
|
2022-05-14 17:57:27 +00:00
|
|
|
tab = "best_submissions_list"
|
2022-09-02 05:39:45 +00:00
|
|
|
page_type = "best_submissions_list"
|
2020-01-21 06:35:58 +00:00
|
|
|
dynamic_update = False
|
|
|
|
|
|
|
|
def get_queryset(self):
|
|
|
|
if self.in_contest:
|
2022-05-14 17:57:27 +00:00
|
|
|
contest_join = """INNER JOIN judge_contestsubmission AS cs ON (sub.id = cs.submission_id)
|
|
|
|
INNER JOIN judge_contestparticipation AS cp ON (cs.participation_id = cp.id)"""
|
|
|
|
points = "cs.points"
|
|
|
|
constraint = "AND cp.contest_id = %s"
|
2020-01-21 06:35:58 +00:00
|
|
|
else:
|
2022-05-14 17:57:27 +00:00
|
|
|
contest_join = ""
|
|
|
|
points = "sub.points"
|
|
|
|
constraint = ""
|
|
|
|
queryset = (
|
|
|
|
super(RankedSubmissions, self)
|
2022-11-01 01:43:06 +00:00
|
|
|
._get_queryset()
|
2022-05-14 17:57:27 +00:00
|
|
|
.filter(user__is_unlisted=False)
|
|
|
|
)
|
2020-01-21 06:35:58 +00:00
|
|
|
join_sql_subquery(
|
|
|
|
queryset,
|
2022-05-14 17:57:27 +00:00
|
|
|
subquery="""
|
2020-01-21 06:35:58 +00:00
|
|
|
SELECT sub.id AS id
|
|
|
|
FROM (
|
|
|
|
SELECT sub.user_id AS uid, MAX(sub.points) AS points
|
|
|
|
FROM judge_submission AS sub {contest_join}
|
|
|
|
WHERE sub.problem_id = %s AND {points} > 0 {constraint}
|
|
|
|
GROUP BY sub.user_id
|
|
|
|
) AS highscore STRAIGHT_JOIN (
|
|
|
|
SELECT sub.user_id AS uid, sub.points, MIN(sub.time) as time
|
|
|
|
FROM judge_submission AS sub {contest_join}
|
|
|
|
WHERE sub.problem_id = %s AND {points} > 0 {constraint}
|
|
|
|
GROUP BY sub.user_id, {points}
|
|
|
|
) AS fastest ON (highscore.uid = fastest.uid AND highscore.points = fastest.points)
|
|
|
|
STRAIGHT_JOIN judge_submission AS sub
|
|
|
|
ON (sub.user_id = fastest.uid AND sub.time = fastest.time) {contest_join}
|
|
|
|
WHERE sub.problem_id = %s AND {points} > 0 {constraint}
|
|
|
|
GROUP BY sub.user_id
|
2022-05-14 17:57:27 +00:00
|
|
|
""".format(
|
|
|
|
points=points, contest_join=contest_join, constraint=constraint
|
|
|
|
),
|
|
|
|
params=[self.problem.id, self.contest.id] * 3
|
|
|
|
if self.in_contest
|
|
|
|
else [self.problem.id] * 3,
|
|
|
|
alias="best_subs",
|
|
|
|
join_fields=[("id", "id")],
|
2022-11-01 01:43:06 +00:00
|
|
|
related_model=Submission,
|
2020-01-21 06:35:58 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
if self.in_contest:
|
2022-05-14 17:57:27 +00:00
|
|
|
return queryset.order_by("-contest__points", "time")
|
2020-01-21 06:35:58 +00:00
|
|
|
else:
|
2022-05-14 17:57:27 +00:00
|
|
|
return queryset.order_by("-points", "time")
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def get_title(self):
|
2022-05-14 17:57:27 +00:00
|
|
|
return _("Best solutions for %s") % self.problem_name
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def get_content_title(self):
|
2022-05-14 17:57:27 +00:00
|
|
|
return format_html(
|
|
|
|
_('Best solutions for <a href="{1}">{0}</a>'),
|
|
|
|
self.problem_name,
|
|
|
|
reverse("problem_detail", args=[self.problem.code]),
|
|
|
|
)
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def _get_result_data(self):
|
2022-11-01 01:43:06 +00:00
|
|
|
return get_result_data(
|
|
|
|
super(RankedSubmissions, self)._get_queryset().order_by()
|
|
|
|
)
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ContestRankedSubmission(ForceContestMixin, RankedSubmissions):
|
|
|
|
def get_title(self):
|
|
|
|
if self.problem.is_accessible_by(self.request.user):
|
2022-05-14 17:57:27 +00:00
|
|
|
return _("Best solutions for %(problem)s in %(contest)s") % {
|
|
|
|
"problem": self.problem_name,
|
|
|
|
"contest": self.contest.name,
|
2020-01-21 06:35:58 +00:00
|
|
|
}
|
2022-05-14 17:57:27 +00:00
|
|
|
return _("Best solutions for problem %(number)s in %(contest)s") % {
|
|
|
|
"number": self.get_problem_number(self.problem),
|
|
|
|
"contest": self.contest.name,
|
2020-01-21 06:35:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def get_content_title(self):
|
|
|
|
if self.problem.is_accessible_by(self.request.user):
|
2022-05-14 17:57:27 +00:00
|
|
|
return format_html(
|
|
|
|
_('Best solutions for <a href="{1}">{0}</a> in <a href="{3}">{2}</a>'),
|
|
|
|
self.problem_name,
|
|
|
|
reverse("problem_detail", args=[self.problem.code]),
|
|
|
|
self.contest.name,
|
|
|
|
reverse("contest_view", args=[self.contest.key]),
|
|
|
|
)
|
|
|
|
return format_html(
|
|
|
|
_('Best solutions for problem {0} in <a href="{2}">{1}</a>'),
|
|
|
|
self.get_problem_number(self.problem),
|
|
|
|
self.contest.name,
|
|
|
|
reverse("contest_view", args=[self.contest.key]),
|
|
|
|
)
|
2020-01-21 06:35:58 +00:00
|
|
|
|
|
|
|
def _get_result_data(self):
|
2022-05-14 17:57:27 +00:00
|
|
|
return get_result_data(
|
|
|
|
Submission.objects.filter(
|
|
|
|
problem_id=self.problem.id,
|
|
|
|
contest__participation__contest_id=self.contest.id,
|
|
|
|
)
|
|
|
|
)
|