diff --git a/README.md b/README.md index d3e2a57d..043cae07 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,15 @@ 基于 Python 和 Django的在线评测平台。 -文档:https://www.zybuluo.com/virusdefender/note/171932 +文档:http://qingdaou.github.io/OnlineJudge/ demo: https://qduoj.com TODO: - - 完善文档,目前还差很多 - 完善测试 + - 完善小组功能 + - 后台重构 ![oj_previewindex.png][1] diff --git a/account/migrations/0010_remove_user_login_failed_counter.py b/account/migrations/0010_remove_user_login_failed_counter.py new file mode 100644 index 00000000..61e09f17 --- /dev/null +++ b/account/migrations/0010_remove_user_login_failed_counter.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0009_user_reset_password_token_create_time'), + ] + + operations = [ + migrations.RemoveField( + model_name='user', + name='login_failed_counter', + ), + ] diff --git a/account/migrations/0011_user_auth_token.py b/account/migrations/0011_user_auth_token.py new file mode 100644 index 00000000..01a3dc51 --- /dev/null +++ b/account/migrations/0011_user_auth_token.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0010_remove_user_login_failed_counter'), + ] + + operations = [ + migrations.AddField( + model_name='user', + name='auth_token', + field=models.CharField(max_length=40, null=True, blank=True), + ), + ] diff --git a/account/migrations/0012_auto_20151012_1546.py b/account/migrations/0012_auto_20151012_1546.py new file mode 100644 index 00000000..a4f937d0 --- /dev/null +++ b/account/migrations/0012_auto_20151012_1546.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0011_user_auth_token'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='create_time', + field=models.DateTimeField(auto_now_add=True, null=True), + ), + ] diff --git a/account/models.py b/account/models.py index ee0cf188..4c6bfca3 100644 --- a/account/models.py +++ b/account/models.py @@ -29,7 +29,7 @@ class User(AbstractBaseUser): # 用户邮箱 email = models.EmailField(max_length=254, blank=True, null=True) # 用户注册时间 - create_time = models.DateTimeField(auto_now_add=True) + create_time = models.DateTimeField(auto_now_add=True, null=True) # 0代表不是管理员 1是普通管理员 2是超级管理员 admin_type = models.IntegerField(default=0) # JSON字典用来表示该用户的问题的解决状态 1为ac,2为正在进行 @@ -38,6 +38,8 @@ class User(AbstractBaseUser): reset_password_token = models.CharField(max_length=40, blank=True, null=True) # token 生成时间 reset_password_token_create_time = models.DateTimeField(blank=True, null=True) + # 论坛授权token + auth_token = models.CharField(max_length=40, blank=True, null=True) USERNAME_FIELD = 'username' REQUIRED_FIELDS = [] diff --git a/account/serializers.py b/account/serializers.py index 948f7c35..528edc77 100644 --- a/account/serializers.py +++ b/account/serializers.py @@ -36,7 +36,7 @@ class UserSerializer(serializers.ModelSerializer): class Meta: model = User - fields = ["id", "username", "real_name", "email", "admin_type"] + fields = ["id", "username", "real_name", "email", "admin_type", "create_time", "last_login"] class EditUserSerializer(serializers.Serializer): diff --git a/mq/scripts/mq.py b/mq/scripts/mq.py index 48cf0f39..7ba83fba 100644 --- a/mq/scripts/mq.py +++ b/mq/scripts/mq.py @@ -50,6 +50,8 @@ class MessageQueue(object): # 更新普通题目的计数器 problem.add_submission_number() + if "problems" not in problems_status: + problems_status["problems"] = {} if submission.result == result["accepted"]: problem.add_ac_number() problems_status["problems"][str(problem.id)] = 1 @@ -88,6 +90,8 @@ class MessageQueue(object): problems_status = user.problems_status contest_problem.add_submission_number() + if "contest_problems" not in problems_status: + problems_status["contest_problems"] = {} if submission.result == result["accepted"]: contest_problem.add_ac_number() problems_status["contest_problems"][str(contest_problem.id)] = 1 diff --git a/oj/settings.py b/oj/settings.py index 849885ce..dd437a91 100644 --- a/oj/settings.py +++ b/oj/settings.py @@ -181,4 +181,8 @@ DATABASE_ROUTERS = ['oj.db_router.DBRouter'] TEST_CASE_DIR = os.path.join(BASE_DIR, 'test_case/') -IMAGE_UPLOAD_DIR = os.path.join(BASE_DIR, 'upload/') \ No newline at end of file +IMAGE_UPLOAD_DIR = os.path.join(BASE_DIR, 'upload/') + +WEBSITE_INFO = {"website_name": "qduoj", + "website_footer": u"青岛大学信息工程学院 创新实验室", + "url": "https://qduoj.com"} diff --git a/problem/models.py b/problem/models.py index 5441e953..a9e8f74b 100644 --- a/problem/models.py +++ b/problem/models.py @@ -49,12 +49,12 @@ class AbstractProblem(models.Model): abstract = True def add_submission_number(self): - self.total_accepted_number += 1 - self.save() + self.total_submit_number += 1 + self.save(update_fields=["total_submit_number"]) def add_ac_number(self): self.total_accepted_number += 1 - self.save() + self.save(update_fields=["total_accepted_number"]) class Problem(AbstractProblem): diff --git a/static/src/js/build.js b/static/src/js/build.js index d1354819..ba08615e 100644 --- a/static/src/js/build.js +++ b/static/src/js/build.js @@ -73,6 +73,9 @@ appDir: "../", dir: "../../release/", modules: [ + { + name: "bootstrap", + }, { name: "announcement_0_pack" }, diff --git a/submission/views.py b/submission/views.py index 50102a05..caa2e681 100644 --- a/submission/views.py +++ b/submission/views.py @@ -149,7 +149,7 @@ class SubmissionAdminAPIView(APIView): problem_id = request.GET.get("problem_id", None) if not problem_id: return error_response(u"参数错误") - submissions = Submission.objects.filter(problem_id=problem_id).order_by("-create_time") + submissions = Submission.objects.filter(problem_id=problem_id, contest_id__isnull=True).order_by("-create_time") return paginate(request, submissions, SubmissionSerializer) diff --git a/template/src/oj/announcement/announcement.html b/template/src/oj/announcement/announcement.html index 2ce84a19..8cbc2392 100644 --- a/template/src/oj/announcement/announcement.html +++ b/template/src/oj/announcement/announcement.html @@ -10,11 +10,10 @@ 作者:{{ announcement.created_by }}     创建时间:{{ announcement.create_time }} - {% ifequal announcement.create_time announcement.last_update_time %} - {% else %} + {% ifnotequal announcement.create_time announcement.last_update_time %}     最后更新:{{ announcement.last_update_time }} - {% endifequal %} + {% endifnotequal %}

diff --git a/tools/run.py b/tools/run.py index fbd7620d..5c73383b 100644 --- a/tools/run.py +++ b/tools/run.py @@ -56,3 +56,6 @@ f.close() print "Please run source /etc/profile" +os.system("ps -ef|grep celery") +print "nohup celery -A judge.judger_controller worker -l DEBUG &" + diff --git a/utils/shortcuts.py b/utils/shortcuts.py index f650e521..e3af9160 100644 --- a/utils/shortcuts.py +++ b/utils/shortcuts.py @@ -102,5 +102,5 @@ def paginate(request, query_set, object_serializer=None): def rand_str(length=32): - string = hashlib.md5(str(time.time()) + str(random.randrange(1, 987654321234567))).hexdigest() + string = hashlib.md5(str(time.time()) + str(random.randrange(1, 987654321234567)) + str(random.randrange(1, 987654321234567))).hexdigest() return string[0:length] \ No newline at end of file diff --git a/utils/templatetags/website_info.py b/utils/templatetags/website_info.py index 85b6c237..98c19ea1 100644 --- a/utils/templatetags/website_info.py +++ b/utils/templatetags/website_info.py @@ -1,8 +1,9 @@ # coding=utf-8 from django import template +from django.conf import settings register = template.Library() @register.simple_tag def show_website_info(name): - return {"website_name": "qduoj", "website_footer": u"青岛大学信息工程学院 创新实验室"}[name] + return settings.WEBSITE_INFO[name]