fix many bugs

This commit is contained in:
zema1 2017-10-31 16:33:25 +08:00
parent f0655ee305
commit aa4240790b
12 changed files with 62 additions and 35 deletions

View File

@ -372,10 +372,9 @@ class UserRankAPI(APIView):
if rule_type not in ContestRuleType.choices():
rule_type = ContestRuleType.ACM
profiles = UserProfile.objects.select_related("user")\
.filter(submission_number__gt=0)\
.exclude(user__is_disabled=True)
if rule_type == ContestRuleType.ACM:
profiles = profiles.order_by("-accepted_number", "submission_number")
profiles = profiles.filter(submission_number__gt=0).order_by("-accepted_number", "submission_number")
else:
profiles = profiles.order_by("-total_score")
profiles = profiles.filter(total_score__gt=0).order_by("-total_score")
return self.success(self.paginate_data(request, profiles, RankInfoSerializer))

View File

@ -15,4 +15,4 @@ class Announcement(models.Model):
class Meta:
db_table = "announcement"
ordering = ('-create_time',)
ordering = ("-create_time",)

View File

@ -54,7 +54,7 @@ class Contest(models.Model):
class Meta:
db_table = "contest"
ordering = ("-create_time",)
ordering = ("-start_time",)
class AbstractContestRank(models.Model):

View File

@ -95,7 +95,7 @@ class ContestAPITest(APITestCase):
self.assertSuccess(resp)
class ContestAnnouncementAPITest(APITestCase):
class ContestAnnouncementAdminAPITest(APITestCase):
def setUp(self):
self.create_super_admin()
self.url = self.reverse("contest_announcement_admin_api")
@ -120,7 +120,7 @@ class ContestAnnouncementAPITest(APITestCase):
def test_get_contest_announcements(self):
self.test_create_contest_announcement()
response = self.client.get(self.url)
response = self.client.get(self.url + "?contest_id=" + str(self.data["contest_id"]))
self.assertSuccess(response)
def test_get_one_contest_announcement(self):

View File

@ -6,6 +6,7 @@ from urllib.parse import urljoin
import requests
from django.db import transaction
from django.db.models import F
from django.conf import settings
from account.models import User
from conf.models import JudgeServer
@ -79,7 +80,10 @@ class JudgeDispatcher(object):
try:
for i in range(len(resp_data)):
if resp_data[i]["result"] == JudgeStatus.ACCEPTED:
score += self.problem.test_case_score[i]["score"]
resp_data[i]["score"] = self.problem.test_case_score[i]["score"]
score += resp_data[i]["score"]
else:
resp_data[i]["score"] = 0
except IndexError:
logger.error(f"Index Error raised when summing up the score in problem {self.problem.id}")
self.submission.statistic_info["score"] = 0
@ -115,8 +119,11 @@ class JudgeDispatcher(object):
Submission.objects.filter(id=self.submission.id).update(result=JudgeStatus.JUDGING)
# TODO: try catch
resp = self._request(urljoin(server.service_url, "/judge"), data=data)
service_url = server.service_url
# not set service_url, it should be a linked container
if not service_url:
service_url = settings.DEFAULT_JUDGE_SERVER_SERVICE_URL
resp = self._request(urljoin(service_url, "/judge"), data=data)
self.submission.info = resp
if resp["err"]:
self.submission.result = JudgeStatus.COMPILE_ERROR
@ -201,7 +208,7 @@ class JudgeDispatcher(object):
logger.info("Contest debug mode, id: " + str(self.contest_id) + ", submission id: " + self.submission.id)
return
with transaction.atomic():
user = User.objects.select_for_update().select_related("userprofile").get(id=self.submission.user_id)
user = User.objects.select_for_update().get(id=self.submission.user_id)
user_profile = user.userprofile
problem_id = str(self.problem.id)
if self.contest.rule_type == ContestRuleType.ACM:
@ -298,5 +305,7 @@ class JudgeDispatcher(object):
last_score = rank.submission_info.get(problem_id)
if last_score:
rank.total_score = rank.total_score - last_score + current_score
else:
rank.total_score = rank.total_score + current_score
rank.submission_info[problem_id] = current_score
rank.save()

View File

@ -26,7 +26,7 @@ ALLOWED_HOSTS = ["*"]
TEST_CASE_DIR = "/tmp"
LOG_PATH = "/tmp/"
LOG_PATH = f"{BASE_DIR}/log/"
AVATAR_URI_PREFIX = "/static/avatar"
AVATAR_UPLOAD_DIR = f"{BASE_DIR}{AVATAR_URI_PREFIX}"

View File

@ -30,3 +30,4 @@ AVATAR_UPLOAD_DIR = "/data/avatar"
TEST_CASE_DIR = "/data/test_case"
LOG_PATH = "/data/log"
DEFAULT_JUDGE_SERVER_SERVICE_URL = "http://judge-server:8080/"

View File

@ -10,6 +10,7 @@ For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.8/ref/settings/
"""
import os
from copy import deepcopy
from .custom_settings import *
@ -20,17 +21,17 @@ else:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Applications
INSTALLED_APPS = (
VENDOR_APPS = (
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'account',
)
LOCAL_APPS = (
'account',
'announcement',
'conf',
'problem',
@ -38,8 +39,11 @@ INSTALLED_APPS = (
'utils',
'submission',
'options',
'judge',
)
INSTALLED_APPS = VENDOR_APPS + LOCAL_APPS
MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
@ -115,17 +119,16 @@ LOGGING = {
'formatters': {
'standard': {
'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'}
# 日志格式
},
'handlers': {
'django_error': {
'level': 'DEBUG',
'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(LOG_PATH, 'django.log'),
'formatter': 'standard'
},
'app_info': {
'level': 'DEBUG',
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(LOG_PATH, 'app_info.log'),
'formatter': 'standard'
@ -137,23 +140,30 @@ LOGGING = {
}
},
'loggers': {
'app_info': {
'handlers': ['app_info', "console"],
'level': 'DEBUG',
'propagate': True
},
'django.request': {
'handlers': ['django_error', 'console'],
'level': 'DEBUG',
'level': 'WARNING',
'propagate': True,
},
'django.server': {
'handlers': ['django_error', 'console'],
'level': 'ERROR',
'propagate': True,
},
'django.db.backends': {
'handlers': ['console'],
'level': 'ERROR',
'handlers': ['django_error', 'console'],
'level': 'WARNING',
'propagate': True,
}
},
},
}
app_logger = {
'handlers': ['app_info', 'console'],
'level': 'DEBUG',
'propagate': False
}
LOGGING["loggers"].update({app: deepcopy(app_logger) for app in LOCAL_APPS})
REST_FRAMEWORK = {
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
'DEFAULT_RENDERER_CLASSES': (
@ -163,6 +173,7 @@ REST_FRAMEWORK = {
REDIS_URL = "redis://%s:%s" % (REDIS_CONF["host"], REDIS_CONF["port"])
def redis_config(db):
def make_key(key, key_prefix, version):
return key
@ -175,16 +186,14 @@ def redis_config(db):
"KEY_FUNCTION": make_key
}
CACHES = {
"default": redis_config(db=1)
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
CELERY_RESULT_BACKEND = f"{REDIS_URL}/2"
BROKER_URL = f"{REDIS_URL}/3"
CELERY_TASK_SOFT_TIME_LIMIT = CELERY_TASK_TIME_LIMIT = 180

View File

@ -1,3 +1,4 @@
import os
from django.core.cache import cache
from django.db import transaction, IntegrityError
@ -6,6 +7,11 @@ from utils.shortcuts import rand_str
from .models import SysOptions as SysOptionsModel
def default_token():
token = os.environ.get("JUDGE_SERVER_TOKEN")
return token if token else rand_str()
class OptionKeys:
website_base_url = "website_base_url"
website_name = "website_name"
@ -25,7 +31,7 @@ class OptionDefaultValue:
allow_register = True
submission_list_show_all = True
smtp_config = {}
judge_server_token = rand_str
judge_server_token = default_token
class _SysOptionsMeta(type):

View File

@ -113,5 +113,5 @@ class ContestProblemSerializer(BaseProblemSerializer):
class ContestProblemSafeSerializer(BaseProblemSerializer):
class Meta:
model = Problem
exclude = ("test_case_score", "test_case_id", "visible", "is_public", "difficulty"
exclude = ("test_case_score", "test_case_id", "visible", "is_public", "difficulty",
"submission_number", "accepted_number", "statistic_info")

View File

@ -76,7 +76,7 @@ class TestCaseUploadAPI(CSRFExemptAPIView):
content = zip_file.read(item).replace(b"\r\n", b"\n")
size_cache[item] = len(content)
if item.endswith(".out"):
md5_cache[item] = hashlib.md5(content).hexdigest()
md5_cache[item] = hashlib.md5(content.rstrip()).hexdigest()
f.write(content)
test_case_info = {"spj": spj, "test_cases": {}}

View File

@ -55,7 +55,7 @@ class SubmissionAPI(APIView):
return self.error("The contest have ended")
if contest.status == ContestStatus.CONTEST_NOT_START and not contest.is_contest_admin(request.user):
return self.error("Contest have not started")
if not contest.problem_details_permission():
if not contest.problem_details_permission(request.user):
hide_id = True
if data.get("captcha"):
@ -110,6 +110,9 @@ class SubmissionAPI(APIView):
@validate_serializer(ShareSubmissionSerializer)
@login_required
def put(self, request):
"""
share submission
"""
try:
submission = Submission.objects.select_related("problem").get(id=request.data["id"])
except Submission.DoesNotExist: