mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-09-21 16:33:22 +00:00
Accept Merge Request #269 修复部分逻辑问题 : (virusdefender-dev -> dev)
Merge Request: 修复部分逻辑问题 Created By: @virusdefender Accepted By: @virusdefender URL: https://coding.net/u/virusdefender/p/qduoj/git/merge/269
This commit is contained in:
commit
807e0ed6ff
@ -120,6 +120,9 @@ class ContestRank(models.Model):
|
|||||||
# key 是比赛题目的id
|
# key 是比赛题目的id
|
||||||
submission_info = JSONField(default={})
|
submission_info = JSONField(default={})
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = "contest_rank"
|
||||||
|
|
||||||
def update_rank(self, submission):
|
def update_rank(self, submission):
|
||||||
if not submission.contest_id or submission.contest_id != self.contest_id:
|
if not submission.contest_id or submission.contest_id != self.contest_id:
|
||||||
raise ValueError("Error submission type")
|
raise ValueError("Error submission type")
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
import json
|
import json
|
||||||
import datetime
|
import datetime
|
||||||
|
import redis
|
||||||
|
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.db import IntegrityError
|
from django.db import IntegrityError
|
||||||
@ -8,6 +9,7 @@ from django.utils import dateparse
|
|||||||
from django.db.models import Q, Sum
|
from django.db.models import Q, Sum
|
||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
@ -334,7 +336,7 @@ def contest_problems_list_page(request, contest_id):
|
|||||||
比赛所有题目的列表页
|
比赛所有题目的列表页
|
||||||
"""
|
"""
|
||||||
contest = Contest.objects.get(id=contest_id)
|
contest = Contest.objects.get(id=contest_id)
|
||||||
contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index")
|
contest_problems = ContestProblem.objects.filter(contest=contest).select_related("contest").order_by("sort_index")
|
||||||
return render(request, "oj/contest/contest_problems_list.html", {"contest_problems": contest_problems,
|
return render(request, "oj/contest/contest_problems_list.html", {"contest_problems": contest_problems,
|
||||||
"contest": {"id": contest_id}})
|
"contest": {"id": contest_id}})
|
||||||
|
|
||||||
@ -384,7 +386,18 @@ def contest_list_page(request, page=1):
|
|||||||
def contest_rank_page(request, contest_id):
|
def contest_rank_page(request, contest_id):
|
||||||
contest = Contest.objects.get(id=contest_id)
|
contest = Contest.objects.get(id=contest_id)
|
||||||
contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index")
|
contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index")
|
||||||
rank = ContestRank.objects.filter(contest_id=contest_id).order_by("-total_ac_number", "total_time")
|
r = redis.Redis(host=settings.REDIS_CACHE["host"], port=settings.REDIS_CACHE["port"], db=settings.REDIS_CACHE["db"])
|
||||||
|
cache_key = str(contest_id) + "_rank_cache"
|
||||||
|
rank = r.get(cache_key)
|
||||||
|
if not rank:
|
||||||
|
rank = ContestRank.objects.filter(contest_id=contest_id).\
|
||||||
|
select_related("user").\
|
||||||
|
order_by("-total_ac_number", "total_time").\
|
||||||
|
values("id", "user__id", "user__username", "user__real_name", "contest_id", "submission_info",
|
||||||
|
"total_submission_number", "total_ac_number", "total_time")
|
||||||
|
r.set(cache_key, json.dumps([dict(item) for item in rank]))
|
||||||
|
else:
|
||||||
|
rank = json.loads(rank)
|
||||||
return render(request, "oj/contest/contest_rank.html",
|
return render(request, "oj/contest/contest_rank.html",
|
||||||
{"rank": rank, "contest": contest,
|
{"rank": rank, "contest": contest,
|
||||||
"contest_problems": contest_problems,
|
"contest_problems": contest_problems,
|
||||||
|
@ -37,5 +37,6 @@ class JoinGroupRequest(models.Model):
|
|||||||
# 是否处理
|
# 是否处理
|
||||||
status = models.BooleanField(default=False)
|
status = models.BooleanField(default=False)
|
||||||
accepted = models.BooleanField(default=False)
|
accepted = models.BooleanField(default=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "join_group_request"
|
db_table = "join_group_request"
|
||||||
|
@ -62,6 +62,8 @@ class JudgeClient(object):
|
|||||||
" --max-real-time " + str(self._max_real_time / 1000.0 * 2) + \
|
" --max-real-time " + str(self._max_real_time / 1000.0 * 2) + \
|
||||||
" --max-memory " + str(self._max_memory * 1000 * 1000) + \
|
" --max-memory " + str(self._max_memory * 1000 * 1000) + \
|
||||||
" --network false" + \
|
" --network false" + \
|
||||||
|
" --remount-dev true " + \
|
||||||
|
" --reset-env true " + \
|
||||||
" --syscalls '" + self._language["syscalls"] + "'" + \
|
" --syscalls '" + self._language["syscalls"] + "'" + \
|
||||||
" --max-nprocess 20" + \
|
" --max-nprocess 20" + \
|
||||||
" --uid " + str(lrun_uid) + \
|
" --uid " + str(lrun_uid) + \
|
||||||
|
@ -13,9 +13,10 @@ def judge(submission_id, time_limit, memory_limit, test_case_id):
|
|||||||
try:
|
try:
|
||||||
command = "%s run --privileged --rm " \
|
command = "%s run --privileged --rm " \
|
||||||
"--link mysql " \
|
"--link mysql " \
|
||||||
"-v %s:/var/judger/test_case/ " \
|
"-v %s:/var/judger/test_case/:ro " \
|
||||||
"-v %s:/var/judger/code/ " \
|
"-v %s:/var/judger/code/:ro " \
|
||||||
"-v %s:/var/judger/code/log/ " \
|
"-v %s:/var/judger/code/log/ " \
|
||||||
|
"--device /dev/null:/dev/null " \
|
||||||
"%s " \
|
"%s " \
|
||||||
"python judge/judger/run.py " \
|
"python judge/judger/run.py " \
|
||||||
"--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % \
|
"--solution_id %s --time_limit %s --memory_limit %s --test_case_id %s" % \
|
||||||
|
@ -39,8 +39,9 @@ class MessageQueue(object):
|
|||||||
logger.warning("Submission user does not exist, submission_id: " + submission_id)
|
logger.warning("Submission user does not exist, submission_id: " + submission_id)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if submission.result == result["accepted"] and not submission.contest_id:
|
if not submission.contest_id:
|
||||||
# 更新普通题目的 ac 计数器
|
# 更新普通题目的 ac 计数器
|
||||||
|
if submission.result == result["accepted"]:
|
||||||
try:
|
try:
|
||||||
problem = Problem.objects.get(id=submission.problem_id)
|
problem = Problem.objects.get(id=submission.problem_id)
|
||||||
problem.total_accepted_number += 1
|
problem.total_accepted_number += 1
|
||||||
|
@ -45,6 +45,7 @@ class AbstractProblem(models.Model):
|
|||||||
total_accepted_number = models.IntegerField(default=0)
|
total_accepted_number = models.IntegerField(default=0)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
db_table = "problem"
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"],
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
beforeSend: csrfTokenHeader,
|
beforeSend: csrfTokenHeader,
|
||||||
url: "/api/admin/announcement/",
|
url: "/api/admin/announcement/",
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
method: "put",
|
method: "put",
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
@ -209,7 +209,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "validator"],
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
beforeSend: csrfTokenHeader,
|
beforeSend: csrfTokenHeader,
|
||||||
url: "/api/admin/announcement/",
|
url: "/api/admin/announcement/",
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
title: title,
|
title: title,
|
||||||
content: content,
|
content: content,
|
||||||
|
@ -46,7 +46,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "date
|
|||||||
beforeSend: csrfTokenHeader,
|
beforeSend: csrfTokenHeader,
|
||||||
url: "/api/admin/contest/",
|
url: "/api/admin/contest/",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
data: JSON.stringify(ajaxData),
|
data: JSON.stringify(ajaxData),
|
||||||
method: "post",
|
method: "post",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
|
@ -48,10 +48,9 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
|
|||||||
beforeSend: csrfTokenHeader,
|
beforeSend: csrfTokenHeader,
|
||||||
url: "/api/admin/contest/",
|
url: "/api/admin/contest/",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
data: JSON.stringify(ajaxData),
|
data: JSON.stringify(ajaxData),
|
||||||
method: "put",
|
method: "put",
|
||||||
contentType: "application/json",
|
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
bsAlert("修改成功!");
|
bsAlert("修改成功!");
|
||||||
@ -237,7 +236,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "editor", "datetimePicker",
|
|||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: JSON.stringify(ajaxData),
|
data: JSON.stringify(ajaxData),
|
||||||
method: "post",
|
method: "post",
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
bsAlert("题目添加成功!题目现在处于隐藏状态,请到题目列表手动修改,并添加分类和难度信息!");
|
bsAlert("题目添加成功!题目现在处于隐藏状态,请到题目列表手动修改,并添加分类和难度信息!");
|
||||||
|
@ -66,7 +66,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
|
|||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: JSON.stringify(ajaxData),
|
data: JSON.stringify(ajaxData),
|
||||||
method: method,
|
method: method,
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
bsAlert("题目编辑成功!");
|
bsAlert("题目编辑成功!");
|
||||||
|
@ -45,7 +45,7 @@ require(["jquery", "avalon", "csrfToken", "bsAlert", "validator"], function ($,
|
|||||||
url: "/api/admin/group_member/",
|
url: "/api/admin/group_member/",
|
||||||
method: "put",
|
method: "put",
|
||||||
data: JSON.stringify({group_id: relation.group, members: [relation.user.id]}),
|
data: JSON.stringify({group_id: relation.group, members: [relation.user.id]}),
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
vm.memberList.remove(relation);
|
vm.memberList.remove(relation);
|
||||||
bsAlert(data.data);
|
bsAlert(data.data);
|
||||||
|
@ -59,7 +59,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
|
|||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: JSON.stringify(ajaxData),
|
data: JSON.stringify(ajaxData),
|
||||||
method: "post",
|
method: "post",
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
bsAlert("题目添加成功!");
|
bsAlert("题目添加成功!");
|
||||||
|
@ -60,7 +60,7 @@ require(["jquery", "avalon", "editor", "uploader", "bsAlert", "csrfToken", "tagE
|
|||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: JSON.stringify(ajaxData),
|
data: JSON.stringify(ajaxData),
|
||||||
method: "put",
|
method: "put",
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
bsAlert("题目编辑成功!");
|
bsAlert("题目编辑成功!");
|
||||||
|
@ -9,14 +9,14 @@ require(["jquery", "csrfToken", "bsAlert"], function ($, csrfTokenHeader, bsAler
|
|||||||
}
|
}
|
||||||
|
|
||||||
var groupId = window.location.pathname.split("/")[2];
|
var groupId = window.location.pathname.split("/")[2];
|
||||||
data = {group_id: groupId,message:message}
|
var data = {group_id: groupId,message:message};
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/api/group_join/",
|
url: "/api/group_join/",
|
||||||
method: "post",
|
method: "post",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
beforeSend: csrfTokenHeader,
|
beforeSend: csrfTokenHeader,
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (data.code) {
|
if (data.code) {
|
||||||
bsAlert(data.data);
|
bsAlert(data.data);
|
||||||
|
@ -222,7 +222,7 @@ require(["jquery", "codeMirror", "csrfToken", "bsAlert", "ZeroClipboard"],
|
|||||||
url: url,
|
url: url,
|
||||||
method: "post",
|
method: "post",
|
||||||
data: JSON.stringify(data),
|
data: JSON.stringify(data),
|
||||||
contentType: "application/json",
|
contentType: "application/json;charset=UTF-8",
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
if (!data.code) {
|
if (!data.code) {
|
||||||
submissionId = data.data.submission_id;
|
submissionId = data.data.submission_id;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
modal: "lib/bootstrap/modal",
|
modal: "lib/bootstrap/modal",
|
||||||
dropdown: "lib/bootstrap/dropdown",
|
dropdown: "lib/bootstrap/dropdown",
|
||||||
transition: "lib/bootstrap/transition",
|
transition: "lib/bootstrap/transition",
|
||||||
|
collapse: "lib/bootstrap/collapse",
|
||||||
|
|
||||||
//百度webuploader -> uploader
|
//百度webuploader -> uploader
|
||||||
webUploader: "lib/webuploader/webuploader",
|
webUploader: "lib/webuploader/webuploader",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
var require = {
|
var require = {
|
||||||
|
urlArgs: "v=2",
|
||||||
// RequireJS 通过一个相对的路径 baseUrl来加载所有代码。baseUrl通常被设置成data-main属性指定脚本的同级目录。
|
// RequireJS 通过一个相对的路径 baseUrl来加载所有代码。baseUrl通常被设置成data-main属性指定脚本的同级目录。
|
||||||
baseUrl: "/static/js/",
|
baseUrl: "/static/js/",
|
||||||
paths: {
|
paths: {
|
||||||
@ -38,6 +39,7 @@ var require = {
|
|||||||
modal: "lib/bootstrap/modal",
|
modal: "lib/bootstrap/modal",
|
||||||
dropdown: "lib/bootstrap/dropdown",
|
dropdown: "lib/bootstrap/dropdown",
|
||||||
transition: "lib/bootstrap/transition",
|
transition: "lib/bootstrap/transition",
|
||||||
|
collapse: "lib/bootstrap/collapse",
|
||||||
|
|
||||||
//百度webuploader -> uploader
|
//百度webuploader -> uploader
|
||||||
webUploader: "lib/webuploader/webuploader",
|
webUploader: "lib/webuploader/webuploader",
|
||||||
|
2
static/src/js/lib/bootstrap/bootstrap.js
vendored
2
static/src/js/lib/bootstrap/bootstrap.js
vendored
@ -1 +1 @@
|
|||||||
require(["jquery", "modal", "dropdown", "transition"]);
|
require(["jquery", "modal", "dropdown", "transition", "collapse"]);
|
214
static/src/js/lib/bootstrap/collapse.js
Normal file
214
static/src/js/lib/bootstrap/collapse.js
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
define([ 'jquery', './transition' ], function ( jQuery ) {
|
||||||
|
/* ========================================================================
|
||||||
|
* Bootstrap: collapse.js v3.3.5
|
||||||
|
* http://getbootstrap.com/javascript/#collapse
|
||||||
|
* ========================================================================
|
||||||
|
* Copyright 2011-2015 Twitter, Inc.
|
||||||
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
|
* ======================================================================== */
|
||||||
|
|
||||||
|
|
||||||
|
+function ($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// COLLAPSE PUBLIC CLASS DEFINITION
|
||||||
|
// ================================
|
||||||
|
|
||||||
|
var Collapse = function (element, options) {
|
||||||
|
this.$element = $(element)
|
||||||
|
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
||||||
|
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
|
||||||
|
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
|
||||||
|
this.transitioning = null
|
||||||
|
|
||||||
|
if (this.options.parent) {
|
||||||
|
this.$parent = this.getParent()
|
||||||
|
} else {
|
||||||
|
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.toggle) this.toggle()
|
||||||
|
}
|
||||||
|
|
||||||
|
Collapse.VERSION = '3.3.5'
|
||||||
|
|
||||||
|
Collapse.TRANSITION_DURATION = 350
|
||||||
|
|
||||||
|
Collapse.DEFAULTS = {
|
||||||
|
toggle: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Collapse.prototype.dimension = function () {
|
||||||
|
var hasWidth = this.$element.hasClass('width')
|
||||||
|
return hasWidth ? 'width' : 'height'
|
||||||
|
}
|
||||||
|
|
||||||
|
Collapse.prototype.show = function () {
|
||||||
|
if (this.transitioning || this.$element.hasClass('in')) return
|
||||||
|
|
||||||
|
var activesData
|
||||||
|
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
|
||||||
|
|
||||||
|
if (actives && actives.length) {
|
||||||
|
activesData = actives.data('bs.collapse')
|
||||||
|
if (activesData && activesData.transitioning) return
|
||||||
|
}
|
||||||
|
|
||||||
|
var startEvent = $.Event('show.bs.collapse')
|
||||||
|
this.$element.trigger(startEvent)
|
||||||
|
if (startEvent.isDefaultPrevented()) return
|
||||||
|
|
||||||
|
if (actives && actives.length) {
|
||||||
|
Plugin.call(actives, 'hide')
|
||||||
|
activesData || actives.data('bs.collapse', null)
|
||||||
|
}
|
||||||
|
|
||||||
|
var dimension = this.dimension()
|
||||||
|
|
||||||
|
this.$element
|
||||||
|
.removeClass('collapse')
|
||||||
|
.addClass('collapsing')[dimension](0)
|
||||||
|
.attr('aria-expanded', true)
|
||||||
|
|
||||||
|
this.$trigger
|
||||||
|
.removeClass('collapsed')
|
||||||
|
.attr('aria-expanded', true)
|
||||||
|
|
||||||
|
this.transitioning = 1
|
||||||
|
|
||||||
|
var complete = function () {
|
||||||
|
this.$element
|
||||||
|
.removeClass('collapsing')
|
||||||
|
.addClass('collapse in')[dimension]('')
|
||||||
|
this.transitioning = 0
|
||||||
|
this.$element
|
||||||
|
.trigger('shown.bs.collapse')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$.support.transition) return complete.call(this)
|
||||||
|
|
||||||
|
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
|
||||||
|
|
||||||
|
this.$element
|
||||||
|
.one('bsTransitionEnd', $.proxy(complete, this))
|
||||||
|
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
|
||||||
|
}
|
||||||
|
|
||||||
|
Collapse.prototype.hide = function () {
|
||||||
|
if (this.transitioning || !this.$element.hasClass('in')) return
|
||||||
|
|
||||||
|
var startEvent = $.Event('hide.bs.collapse')
|
||||||
|
this.$element.trigger(startEvent)
|
||||||
|
if (startEvent.isDefaultPrevented()) return
|
||||||
|
|
||||||
|
var dimension = this.dimension()
|
||||||
|
|
||||||
|
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
|
||||||
|
|
||||||
|
this.$element
|
||||||
|
.addClass('collapsing')
|
||||||
|
.removeClass('collapse in')
|
||||||
|
.attr('aria-expanded', false)
|
||||||
|
|
||||||
|
this.$trigger
|
||||||
|
.addClass('collapsed')
|
||||||
|
.attr('aria-expanded', false)
|
||||||
|
|
||||||
|
this.transitioning = 1
|
||||||
|
|
||||||
|
var complete = function () {
|
||||||
|
this.transitioning = 0
|
||||||
|
this.$element
|
||||||
|
.removeClass('collapsing')
|
||||||
|
.addClass('collapse')
|
||||||
|
.trigger('hidden.bs.collapse')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$.support.transition) return complete.call(this)
|
||||||
|
|
||||||
|
this.$element
|
||||||
|
[dimension](0)
|
||||||
|
.one('bsTransitionEnd', $.proxy(complete, this))
|
||||||
|
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
|
||||||
|
}
|
||||||
|
|
||||||
|
Collapse.prototype.toggle = function () {
|
||||||
|
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
||||||
|
}
|
||||||
|
|
||||||
|
Collapse.prototype.getParent = function () {
|
||||||
|
return $(this.options.parent)
|
||||||
|
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
|
||||||
|
.each($.proxy(function (i, element) {
|
||||||
|
var $element = $(element)
|
||||||
|
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
|
||||||
|
}, this))
|
||||||
|
.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
|
||||||
|
var isOpen = $element.hasClass('in')
|
||||||
|
|
||||||
|
$element.attr('aria-expanded', isOpen)
|
||||||
|
$trigger
|
||||||
|
.toggleClass('collapsed', !isOpen)
|
||||||
|
.attr('aria-expanded', isOpen)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTargetFromTrigger($trigger) {
|
||||||
|
var href
|
||||||
|
var target = $trigger.attr('data-target')
|
||||||
|
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
||||||
|
|
||||||
|
return $(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// COLLAPSE PLUGIN DEFINITION
|
||||||
|
// ==========================
|
||||||
|
|
||||||
|
function Plugin(option) {
|
||||||
|
return this.each(function () {
|
||||||
|
var $this = $(this)
|
||||||
|
var data = $this.data('bs.collapse')
|
||||||
|
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||||
|
|
||||||
|
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
|
||||||
|
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
|
||||||
|
if (typeof option == 'string') data[option]()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var old = $.fn.collapse
|
||||||
|
|
||||||
|
$.fn.collapse = Plugin
|
||||||
|
$.fn.collapse.Constructor = Collapse
|
||||||
|
|
||||||
|
|
||||||
|
// COLLAPSE NO CONFLICT
|
||||||
|
// ====================
|
||||||
|
|
||||||
|
$.fn.collapse.noConflict = function () {
|
||||||
|
$.fn.collapse = old
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// COLLAPSE DATA-API
|
||||||
|
// =================
|
||||||
|
|
||||||
|
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
||||||
|
var $this = $(this)
|
||||||
|
|
||||||
|
if (!$this.attr('data-target')) e.preventDefault()
|
||||||
|
|
||||||
|
var $target = getTargetFromTrigger($this)
|
||||||
|
var data = $target.data('bs.collapse')
|
||||||
|
var option = data ? 'toggle' : $this.data()
|
||||||
|
|
||||||
|
Plugin.call($target, option)
|
||||||
|
})
|
||||||
|
|
||||||
|
}(jQuery);
|
||||||
|
|
||||||
|
});
|
@ -29,7 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="col-md-9 col-lg-9">
|
<div class="col-md-12 col-lg-12">
|
||||||
<div>
|
<div>
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
@ -60,9 +60,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 col-lg-3">
|
|
||||||
{% include "oj/announcement/_announcement_panel.html" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -39,8 +39,8 @@
|
|||||||
<th class="text-center">AC / 总提交</th>
|
<th class="text-center">AC / 总提交</th>
|
||||||
<th class="text-center">用时 + 罚时</th>
|
<th class="text-center">用时 + 罚时</th>
|
||||||
{% for item in contest_problems %}
|
{% for item in contest_problems %}
|
||||||
<th class="text-center"><a
|
<th class="text-center">
|
||||||
href="/contest/{{ contest.id }}/problem/{{ item.id }}/">{{ item.sort_index }}</a>
|
<a href="/contest/{{ contest.id }}/problem/{{ item.id }}/">{{ item.sort_index }}</a>
|
||||||
</th>
|
</th>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
@ -50,9 +50,9 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th scope="row">{{ forloop.counter }}</th>
|
<th scope="row">{{ forloop.counter }}</th>
|
||||||
<td>
|
<td>
|
||||||
{{ item.user.username }}
|
{{ item.user__username }}
|
||||||
{% if show_real_name %}
|
{% if show_real_name %}
|
||||||
({{ item.real_name }})
|
({{ item.user__real_name }})
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ item.total_ac_number }} / {{ item.total_submission_number }}</td>
|
<td>{{ item.total_ac_number }} / {{ item.total_submission_number }}</td>
|
||||||
|
@ -24,8 +24,10 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-bordered">
|
<table class="table table-bordered">
|
||||||
|
|
||||||
|
{% if submissions %}
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="" success>
|
<tr>
|
||||||
<th>#</th>
|
<th>#</th>
|
||||||
<th>题目名称</th>
|
<th>题目名称</th>
|
||||||
<th>用户</th>
|
<th>用户</th>
|
||||||
@ -65,7 +67,6 @@
|
|||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{% if submissions %}
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for item in submissions %}
|
{% for item in submissions %}
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
import datetime
|
import json
|
||||||
from django.utils.timezone import now
|
|
||||||
|
|
||||||
|
|
||||||
def get_contest_status(contest):
|
def get_contest_status(contest):
|
||||||
@ -34,10 +33,11 @@ def get_the_formatted_time(seconds):
|
|||||||
|
|
||||||
|
|
||||||
def get_submission_class(rank, problem):
|
def get_submission_class(rank, problem):
|
||||||
if str(problem.id) not in rank.submission_info:
|
submission_info = json.loads(rank["submission_info"])
|
||||||
|
if str(problem.id) not in submission_info:
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
submission = rank.submission_info[str(problem.id)]
|
submission = submission_info[str(problem.id)]
|
||||||
if submission["is_ac"]:
|
if submission["is_ac"]:
|
||||||
_class = "alert-success"
|
_class = "alert-success"
|
||||||
if submission["is_first_ac"]:
|
if submission["is_first_ac"]:
|
||||||
@ -48,10 +48,11 @@ def get_submission_class(rank, problem):
|
|||||||
|
|
||||||
|
|
||||||
def get_submission_content(rank, problem):
|
def get_submission_content(rank, problem):
|
||||||
if str(problem.id) not in rank.submission_info:
|
submission_info = json.loads(rank["submission_info"])
|
||||||
|
if str(problem.id) not in submission_info:
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
submission = rank.submission_info[str(problem.id)]
|
submission = submission_info[str(problem.id)]
|
||||||
if submission["is_ac"]:
|
if submission["is_ac"]:
|
||||||
r = get_the_formatted_time(submission["ac_time"])
|
r = get_the_formatted_time(submission["ac_time"])
|
||||||
if submission["error_number"]:
|
if submission["error_number"]:
|
||||||
|
@ -38,7 +38,7 @@ class XssHtml(HTMLParser):
|
|||||||
'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4',
|
'p', 'div', 'em', 'span', 'h1', 'h2', 'h3', 'h4',
|
||||||
'h5', 'h6', 'blockquote', 'ul', 'ol', 'tr', 'th', 'td',
|
'h5', 'h6', 'blockquote', 'ul', 'ol', 'tr', 'th', 'td',
|
||||||
'hr', 'li', 'u', 'embed', 's', 'table', 'thead', 'tbody',
|
'hr', 'li', 'u', 'embed', 's', 'table', 'thead', 'tbody',
|
||||||
'caption', 'small', 'q', 'sup', 'sub']
|
'caption', 'small', 'q', 'sup', 'sub', 'font']
|
||||||
common_attrs = ["style", "class", "name"]
|
common_attrs = ["style", "class", "name"]
|
||||||
nonend_tags = ["img", "hr", "br", "embed"]
|
nonend_tags = ["img", "hr", "br", "embed"]
|
||||||
tags_own_attrs = {
|
tags_own_attrs = {
|
||||||
@ -46,6 +46,7 @@ class XssHtml(HTMLParser):
|
|||||||
"a": ["href", "target", "rel", "title"],
|
"a": ["href", "target", "rel", "title"],
|
||||||
"embed": ["src", "width", "height", "type", "allowfullscreen", "loop", "play", "wmode", "menu"],
|
"embed": ["src", "width", "height", "type", "allowfullscreen", "loop", "play", "wmode", "menu"],
|
||||||
"table": ["border", "cellpadding", "cellspacing"],
|
"table": ["border", "cellpadding", "cellspacing"],
|
||||||
|
"font": ["color"]
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, allows=[]):
|
def __init__(self, allows=[]):
|
||||||
|
Loading…
Reference in New Issue
Block a user