Add public scoreboard option

This commit is contained in:
cuom1999 2023-09-16 23:55:24 -05:00
parent f3bcc25eb0
commit 8bb3812f97
11 changed files with 312 additions and 35 deletions

View file

@ -158,6 +158,7 @@ class ContestAdmin(CompareVersionAdmin):
"is_visible",
"use_clarifications",
"hide_problem_tags",
"public_scoreboard",
"scoreboard_visibility",
"run_pretests_only",
"points_precision",

View file

@ -308,6 +308,7 @@ class EditOrganizationContestForm(ModelForm):
"freeze_after",
"use_clarifications",
"hide_problem_tags",
"public_scoreboard",
"scoreboard_visibility",
"run_pretests_only",
"points_precision",

View file

@ -0,0 +1,22 @@
# Generated by Django 3.2.18 on 2023-09-17 01:55
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("judge", "0168_css_background"),
]
operations = [
migrations.AddField(
model_name="contest",
name="public_scoreboard",
field=models.BooleanField(
default=False,
help_text="Ranking page is public even for private contests.",
verbose_name="public scoreboard",
),
),
]

View file

@ -167,6 +167,11 @@ class Contest(models.Model, PageVotable, Bookmarkable):
related_name="view_contest_scoreboard",
help_text=_("These users will be able to view the scoreboard."),
)
public_scoreboard = models.BooleanField(
verbose_name=_("public scoreboard"),
help_text=_("Ranking page is public even for private contests."),
default=False,
)
use_clarifications = models.BooleanField(
verbose_name=_("no comments"),
help_text=_("Use clarification system instead of comments."),

View file

@ -107,9 +107,10 @@ __all__ = [
]
def _find_contest(request, key, private_check=True):
def _find_contest(request, key):
try:
contest = Contest.objects.get(key=key)
private_check = not contest.public_scoreboard
if private_check and not contest.is_accessible_by(request.user):
raise ObjectDoesNotExist()
except ObjectDoesNotExist:
@ -277,6 +278,9 @@ class ContestMixin(object):
def can_edit(self):
return self.object.is_editable_by(self.request.user)
def should_bypass_access_check(self, contest):
return False
def get_context_data(self, **kwargs):
context = super(ContestMixin, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
@ -338,6 +342,9 @@ class ContestMixin(object):
):
return contest
if self.should_bypass_access_check(contest):
return contest
try:
contest.access_check(self.request.user)
except Contest.PrivateContest:
@ -352,30 +359,6 @@ class ContestMixin(object):
else:
return contest
if contest.is_private or contest.is_organization_private:
private_contest_error = PrivateContestError(
contest.name,
contest.is_private,
contest.is_organization_private,
contest.organizations.all(),
)
if profile is None:
raise private_contest_error
if user.has_perm("judge.edit_all_contest"):
return contest
if not (
contest.is_organization_private
and contest.organizations.filter(
id__in=profile.organizations.all()
).exists()
) and not (
contest.is_private
and contest.private_contestants.filter(id=profile.id).exists()
):
raise private_contest_error
return contest
def dispatch(self, request, *args, **kwargs):
try:
return super(ContestMixin, self).dispatch(request, *args, **kwargs)
@ -1095,6 +1078,9 @@ class ContestRankingBase(ContestMixin, TitleMixin, DetailView):
class ContestRanking(ContestRankingBase):
page_type = "ranking"
def should_bypass_access_check(self, contest):
return contest.public_scoreboard
def get_title(self):
return _("%s Rankings") % self.object.name