Skip to content

Commit c0fc13d

Browse files
committed
Refactor contest ranking
1 parent 326b3d5 commit c0fc13d

File tree

4 files changed

+62
-116
lines changed

4 files changed

+62
-116
lines changed

dmoj/urls.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,11 +609,6 @@ def paged_list_view(view, name, **kwargs):
609609
contests.ContestFinalRanking.as_view(),
610610
name="contest_final_ranking",
611611
),
612-
url(
613-
r"^/ranking/ajax$",
614-
contests.contest_ranking_ajax,
615-
name="contest_ranking_ajax",
616-
),
617612
url(r"^/join$", contests.ContestJoin.as_view(), name="contest_join"),
618613
url(r"^/leave$", contests.ContestLeave.as_view(), name="contest_leave"),
619614
url(r"^/stats$", contests.ContestStats.as_view(), name="contest_stats"),

judge/views/contests.py

Lines changed: 38 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@
101101
"ContestStats",
102102
"ContestMossView",
103103
"ContestMossDelete",
104-
"contest_ranking_ajax",
105104
"ContestParticipationList",
106105
"ContestParticipationDisqualify",
107106
"get_contest_ranking_list",
@@ -1148,54 +1147,6 @@ def get_contest_ranking_list(
11481147
return users, problems
11491148

11501149

1151-
def contest_ranking_ajax(request, contest, participation=None):
1152-
contest, exists = _find_contest(request, contest)
1153-
show_final = bool(request.GET.get("final", False))
1154-
if not exists:
1155-
return HttpResponseBadRequest("Invalid contest", content_type="text/plain")
1156-
1157-
if not contest.can_see_full_scoreboard(request.user):
1158-
raise Http404()
1159-
1160-
if show_final:
1161-
if (
1162-
not contest.is_editable_by(request.user)
1163-
or not contest.format.has_hidden_subtasks
1164-
):
1165-
raise Http404()
1166-
1167-
if participation is None:
1168-
participation = _get_current_virtual_participation(request, contest)
1169-
1170-
queryset = contest.users.filter(virtual__gte=0)
1171-
if request.GET.get("friend") == "true" and request.profile:
1172-
friends = request.profile.get_friends()
1173-
queryset = queryset.filter(user_id__in=friends)
1174-
if request.GET.get("virtual") != "true":
1175-
queryset = queryset.filter(virtual=0)
1176-
1177-
users, problems = get_contest_ranking_list(
1178-
request,
1179-
contest,
1180-
participation,
1181-
ranking_list=partial(
1182-
contest_ranking_list, queryset=queryset, extra_participation=participation
1183-
),
1184-
show_final=show_final,
1185-
)
1186-
return render(
1187-
request,
1188-
"contest/ranking-table.html",
1189-
{
1190-
"users": users,
1191-
"problems": problems,
1192-
"contest": contest,
1193-
"has_rating": contest.ratings.exists(),
1194-
"can_edit": contest.is_editable_by(request.user),
1195-
},
1196-
)
1197-
1198-
11991150
def _get_current_virtual_participation(request, contest):
12001151
# Return None if not eligible
12011152
if not request.user.is_authenticated:
@@ -1237,6 +1188,7 @@ def get_context_data(self, **kwargs):
12371188

12381189
class ContestRanking(ContestRankingBase):
12391190
page_type = "ranking"
1191+
show_final = False
12401192

12411193
def should_bypass_access_check(self, contest):
12421194
return contest.public_scoreboard
@@ -1256,23 +1208,58 @@ def get_ranking_list(self):
12561208
ranker=lambda users, key: ((_("???"), user) for user in users),
12571209
)
12581210

1259-
return get_contest_ranking_list(self.request, self.object)
1211+
queryset = self.object.users
1212+
if self.friend_only:
1213+
friends = self.request.profile.get_friends()
1214+
queryset = queryset.filter(user_id__in=friends)
1215+
if not self.include_virtual:
1216+
queryset = queryset.filter(virtual=0)
1217+
else:
1218+
queryset = queryset.filter(virtual__gte=0)
1219+
1220+
return get_contest_ranking_list(
1221+
self.request,
1222+
self.object,
1223+
ranking_list=partial(contest_ranking_list, queryset=queryset),
1224+
show_final=self.show_final,
1225+
)
1226+
1227+
def _get_default_include_virtual(self):
1228+
if hasattr(self.object, "official"):
1229+
return "1"
1230+
return "0"
1231+
1232+
def setup_filters(self):
1233+
if self.request.profile:
1234+
self.friend_only = bool(self.request.GET.get("friend") == "1")
1235+
self.include_virtual = bool(
1236+
self.request.GET.get("virtual", self._get_default_include_virtual()) == "1"
1237+
)
1238+
self.ajax_only = bool(self.request.GET.get("ajax") == "1")
1239+
1240+
if self.ajax_only:
1241+
self.template_name = "contest/ranking-table.html"
12601242

12611243
def get_context_data(self, **kwargs):
1244+
self.setup_filters()
12621245
context = super().get_context_data(**kwargs)
12631246
context["has_rating"] = self.object.ratings.exists()
1247+
if not self.ajax_only:
1248+
context["include_virtual"] = self.include_virtual
1249+
context["friend_only"] = self.friend_only
12641250
return context
12651251

12661252

12671253
class ContestFinalRanking(LoginRequiredMixin, ContestRanking):
12681254
page_type = "final_ranking"
1255+
show_final = True
12691256

12701257
def get_ranking_list(self):
12711258
if not self.object.is_editable_by(self.request.user):
12721259
raise Http404()
12731260
if not self.object.format.has_hidden_subtasks:
12741261
raise Http404()
1275-
return get_contest_ranking_list(self.request, self.object, show_final=True)
1262+
return super().get_ranking_list()
12761263

12771264

12781265
class ContestParticipationList(LoginRequiredMixin, ContestRankingBase):

templates/contest/media-js.html

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -56,39 +56,6 @@
5656
}
5757
}
5858

59-
function renew_filter(need_update=true) {
60-
var checkboxes = [
61-
'#show-schools-checkbox',
62-
'#show-fullnames-checkbox',
63-
'#show-total-score-checkbox',
64-
];
65-
66-
var checkboxes2 = [
67-
'#show-friends-checkbox',
68-
'#show-virtual-checkbox'
69-
]
70-
71-
for (var i of checkboxes) {
72-
var $box = $(i);
73-
if ($box.is(':checked')) {
74-
$box.prop('checked', false);
75-
$box.click();
76-
$box.prop('checked', true);
77-
}
78-
}
79-
80-
var to_update = false;
81-
for (var i of checkboxes2) {
82-
var $box = $(i);
83-
if ($box.is(':checked')) {
84-
to_update = true;
85-
}
86-
}
87-
if (to_update && need_update) {
88-
update_ranking();
89-
}
90-
}
91-
9259
function get_initial_rank() {
9360
var ranks = $('.rank-td').map(function() {return this.innerHTML}).get();
9461
var usernames = $('.user-name .rating a').map(function() {return this.text}).get();
@@ -118,16 +85,13 @@
11885
var friend = $('#show-friends-checkbox').is(':checked');
11986
var virtual = $('#show-virtual-checkbox').is(':checked');
12087
$('#loading-gif').show();
121-
var url = `{{url('contest_ranking_ajax', contest.key)}}?friend=${friend}&virtual=${virtual}`;
122-
{% if page_type == 'final_ranking' %}
123-
url += "&final=true";
124-
{% endif %}
88+
var url = `?friend=${friend ? 1 : 0}&virtual=${virtual ? 1 : 0}&ajax=1`;
89+
12590
$.get({
12691
url: url,
12792
success: function(HTML) {
12893
$('#users-table').html(HTML);
12994
highlightFirstSolve();
130-
renew_filter(false);
13195
$('#loading-gif').hide();
13296
if (!virtual && !friend) {
13397
get_initial_rank();
@@ -201,7 +165,6 @@
201165
})
202166

203167
highlightFirstSolve();
204-
renew_filter();
205168
get_initial_rank();
206169

207170
{% if participation_tab %}

templates/contest/ranking.html

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -134,28 +134,29 @@
134134
<input id="search-contest" type="text" placeholder="{{ _('View user participation') }}">
135135
</div>
136136
{% endif %}
137+
{% else %}
138+
<div style="margin-bottom: 0.5em">
139+
<input id="show-schools-checkbox" type="checkbox" style="vertical-align: bottom">
140+
<label for="show-schools-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show schools') }}</label>
141+
142+
<input id="show-fullnames-checkbox" type="checkbox" style="vertical-align: bottom">
143+
144+
<label for="show-fullnames-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show full name') }}</label>
145+
{% if request.user.is_authenticated %}
146+
<input id="show-friends-checkbox" type="checkbox" style="vertical-align: bottom;" {{"checked" if friend_only}}>
147+
<label for="show-friends-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show friends only') }}</label>
148+
{% endif %}
149+
<input id="show-total-score-checkbox" type="checkbox" style="vertical-align: bottom; ">
150+
<label for="show-total-score-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Total score only') }}</label>
151+
<input id="show-virtual-checkbox" type="checkbox" style="vertical-align: bottom;" {{"checked" if include_virtual}}>
152+
<label id="show-virtual-label" for="show-virtual-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show virtual participation') }}</label>
153+
<i class="fa fa-spinner fa-pulse" style="display: none" id="loading-gif"></i>
154+
<a href="#" onclick="download_ranking_as_csv()">
155+
<i class="fa fa-download" aria-hidden="true"></i>
156+
{{ _('Download as CSV') }}
157+
</a>
158+
</div>
137159
{% endif %}
138-
<div style="margin-bottom: 0.5em">
139-
<input id="show-schools-checkbox" type="checkbox" style="vertical-align: bottom">
140-
<label for="show-schools-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show schools') }}</label>
141-
142-
<input id="show-fullnames-checkbox" type="checkbox" style="vertical-align: bottom">
143-
144-
<label for="show-fullnames-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show full name') }}</label>
145-
{% if request.user.is_authenticated %}
146-
<input id="show-friends-checkbox" type="checkbox" style="vertical-align: bottom;">
147-
<label for="show-friends-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show friends only') }}</label>
148-
{% endif %}
149-
<input id="show-total-score-checkbox" type="checkbox" style="vertical-align: bottom; ">
150-
<label for="show-total-score-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Total score only') }}</label>
151-
<input id="show-virtual-checkbox" type="checkbox" style="vertical-align: bottom;">
152-
<label id="show-virtual-label" for="show-virtual-checkbox" style="vertical-align: bottom; margin-right: 1em;">{{ _('Show virtual participation') }}</label>
153-
<i class="fa fa-spinner fa-pulse" style="display: none" id="loading-gif"></i>
154-
<a href="#" onclick="download_ranking_as_csv()">
155-
<i class="fa fa-download" aria-hidden="true"></i>
156-
{{ _('Download as CSV') }}
157-
</a>
158-
</div>
159160
{% endblock %}
160161

161162
{% block users_table %}

0 commit comments

Comments
 (0)