在过去的几天时间里面,我主要集中精力实现Contest
的的Rank
以及Status
功能
Rank实现代码####
###前端
<br>
<table class="table table-bordered table-hover text-center" id = "rank_table">
<thead>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript">
function str_pad_left(string,pad,length) {
return (new Array(length+1).join(pad)+string).slice(-length);
}
function secondsToTime(secs)
{
var hours = Math.floor(secs / (60 * 60));
var divisor_for_minutes = secs % (60 * 60);
var minutes = Math.floor(divisor_for_minutes / 60);
var divisor_for_seconds = divisor_for_minutes % 60;
var seconds = Math.ceil(divisor_for_seconds);
return hours + ":" + str_pad_left(minutes,'0',2)+':'+str_pad_left(seconds,'0',2);;
}
function refreshRankList(){
$.ajax({
type: "post",
url: "/contest/" + {{ contest.id }} + "/rank/",
dataType: "json",
success: function(data){
$("#rank_table tr").remove();
thHTML = "<tr><th class=\"text-center\">Rank</th><th class=\"text-center\">ID</th><th class=\"text-center\">Solve</th><th class=\"text-center\">Penalty</th>"
$.each(data.statsinfo, function(i, item){
thHTML += "<th class=\"text-center\">" + item.probid + "</th>";
});
thHTML += "</tr>";
$("#rank_table thead").append(thHTML);
rank_num = 0;
var last_solved = -1;
var last_penalty = -1;
var rank_list=[];
$.each(data, function(i, item) {
if (item != data.statsinfo) {
rank_list.push(item);
}
});
rank_list.sort(function(a,b){return a.solved==b.solved?a.penalty-b.penalty:b.solved-a.solved;});
$.each(rank_list, function(i, item) {
if (item != data.statsinfo) {
if(item.solved!=last_solved || item.penalty!=last_penalty)
rank_num += 1;
last_solved=item.solved;
last_penalty=item.penalty;
trHTML = "<tr><td style=\"align:center;\">" + rank_num +
"</td><td class=\"text-center\">" + item.name +
"</td><td>" + item.solved +
"</td><td>" + item.penalty + "</td>";
$.each(item.probs, function(i, pitem){
if (pitem.acNum == 0) {
if (pitem.failNum == 0) {
trHTML += "<td></td>";
} else {
trHTML += "<td style=\"background-color: red; color:white;\"><br><span>(-" + pitem.failNum + ")</span></td>";
}
} else {
if (pitem.failNum == 0) {
trHTML += "<td style=\"background-color: #99FF66;\">" + secondsToTime(pitem.acTime) + "</td>";
} else {
trHTML += "<td style=\"background-color: #99FF66;\">" + secondsToTime(pitem.acTime) + "<br><span>(-" + pitem.failNum + ")</span></td>";
}
}
});
trHTML += "</tr>"
$("#rank_table tbody").append(trHTML);
}
});
thHTML = "<tr><td></td><td></td><td></td><td></td>";
$.each(data.statsinfo, function(i, item){
thHTML += "<td style=\"background-color: #D0D0D0;\">" + item.acNum + "/" + item.tryNum + "</td>";
});
thHTML += "<tr>"
$("#rank_table tbody").append(thHTML);
}
});
}
$(document).ready(function () {
refreshRankList();
//setInterval(function(){refreshRankList();},10000);
})
</script>
###后台
def contest_rank(req, cid):
if req.is_ajax():
contest = Contest.objects.get(id = cid)
if contest.private:
if req.user.is_superuser==False and req.user.info not in contest.accounts.all() :
return JsonResponse("{}")
rank_cache = contest.rank
# print("rank_cache:")
# print(rank_cache)
status_list = Status.objects.filter(cid = cid).filter(runid__gt = contest.last_submit_id).order_by("time")
# print("status_list")
# print(status_list)
rank_dict = json.loads(rank_cache)
# print("rank_dict")
# print(rank_dict)
statsinfo = {}
pos = 0
problem_list = contest.get_problem_list()
length = len(problem_list)
if contest.last_submit_id==0:
rank_dict["statsinfo"] = [{} for i in range(length)]
for item in problem_list:
rank_dict["statsinfo"][pos] = {"probid" : chr(pos + 65) ,"acNum" : 0, "tryNum" : 0}
statsinfo[item[2].title] = {"pos" : pos}
pos += 1
else:
for item in problem_list:
statsinfo[item[2].title] = {"pos" : pos}
pos += 1
for item in status_list:
if item.user.is_staff :
continue
name = item.user.username
contest.last_submit_id = max(contest.last_submit_id, item.runid)
if name not in rank_dict.keys():
rank_dict[name] = {"name" : name, "solved":0, "penalty":0, "probs" : [{"failNum" : 0, "acNum" : 0, "acTime" : 0} for i in range(length)]}
pos = statsinfo[item.pro.title]["pos"]
if item.result == 3: #Waiting
break
if item.result == 0: #Accepted
rank_dict["statsinfo"][pos]["acNum"] += 1
rank_dict["statsinfo"][pos]["tryNum"] += 1
if rank_dict[name]["probs"][pos]["acNum"] == 0:
if item.result == 0:
rank_dict[name]["probs"][pos]["acNum"] += 1
rank_dict[name]["probs"][pos]["acTime"] = dateToInt(item.timec - contest.start_time, 1)
rank_dict[name]["penalty"] += 20 * rank_dict[name]["probs"][pos]["failNum"] + dateToInt(item.timec - contest.start_time, 0)
rank_dict[name]["solved"] += 1
else:
rank_dict[name]["probs"][pos]["failNum"] += 1
contest.rank = json.dumps(rank_dict)
# print("contest.rank")
# print(contest.rank)
contest.save()
return JsonResponse(rank_dict)
Status实现代码####
###前端
</br>
<table class="table">
<thead>
<tr>
<th>RunID</th>
<th>Problem</th>
<th>Status</th>
<th>Language</th>
<th>User</th>
<th>SubmitTime</th>
</tr>
</thead>
<tbody>
{% for item in status_list %}
<tr
{% ifequal item.result 'Waiting' %}
class="info"
{% endifequal %}
{% ifequal item.result 'Accepted' %}
class="success"
{% else %}
class="danger"
{% endifequal %}
>
<td>{{ item.runid }}</td>
<td><a href="//www.greatytc.com/problem/{{ item.pro.proid}}">{{ item.pro.title }}</a></td>
{% ifequal item.pro.isCCF True %}
<td>{{ item.score }}</td>
{% else %}
{% ifequal item.result "Compilation Error"%}
<td><a href="/show_source?solution_id={{ item.runid }}" target="_blank">{{ item.result }}</a></td>
{% else %}
<td>{{ item.result }}</td>
{% endifequal %}
{% endifequal %}
{% ifequal item.user.id user.id %}
<td><a href="/show_source?solution_id={{ item.runid }}" target="_blank">{{ item.result }}</a></td>
{% else %}
{% ifequal user.is_staff True %}
<td><a href="/show_source?solution_id={{ item.runid }}" target="_blank">{{ item.result }}</a></td>
{% else %}
<td>{{ item.lang }}</td>
{% endifequal %}
{% endifequal %}
<td>{{ item.user.username }}</td>
<td>{{ item.time | date:"Y-m-d H:i:s" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<center>
<ul class="pagination">
<script type="text/javascript">
//$(document).ready(function () {
function request_contest_status(pg){
$.ajax({
type: 'get',
url: "/contest/" + {{ contest_id }} + "/status/?pg=" + pg,
success: function (responseData) {
$('#panel-status').html(responseData);
}
})
}
</script>
{% for id in page %}
<li><a class="{% if pg == id %}active{% else %}disabled{% endif %}"
href="javascript:request_contest_status({{ id }});">
{{ id }}
</a>
</li>
{% endfor %}
</ul>
</center>
###后台
def contest_status(req, cid):#has understood
if req.is_ajax():
contest = Contest.objects.get(id=cid)
t = loader.get_template('contest/contest_status.html')
status_list = Status.objects.filter(cid=cid).order_by('-time')#need change
if contest.private:
if req.user.is_superuser==False and req.user.info not in contest.accounts.all() :
status_list = []
pg = req.GET.get('pg')
if not pg:
pg = 1
pg = int(pg)
max_cnt = status_list.count() // 20 + 1
start = max(pg - PAGE_NUMBER_EVERY_PAGE, 1)
end = min(pg + PAGE_NUMBER_EVERY_PAGE, max_cnt)
lst = status_list[(pg - 1) * LIST_NUMBER_EVERY_PAGE:pg * LIST_NUMBER_EVERY_PAGE]
# content_html = t.render(Context({'status_list': lst, 'page': range(start, end + 1), 'contest_id': cid, 'user': req.user}))
# return HttpResponse(content_html)
return render(req,'contest/contest_status.html',{'status_list': lst, 'page': range(start, end + 1), 'contest_id': cid, 'user': req.user})
else:
raise Http404