From 7b8079f4beb7fdd5d39ff3bd1379832889536440 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 10 Sep 2015 09:16:51 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E6=97=B6=E7=94=A8=E6=88=B7=E5=90=8D=E6=98=BE=E7=A4=BA=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- template/src/oj/problem/my_submission.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/src/oj/problem/my_submission.html b/template/src/oj/problem/my_submission.html index cb7df85..634c789 100644 --- a/template/src/oj/problem/my_submission.html +++ b/template/src/oj/problem/my_submission.html @@ -71,7 +71,7 @@ {% endif %} {% endifequal %} From fbeb745530afaa2054ae15510e4d3fa95c48c839 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 10 Sep 2015 15:35:27 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E6=AF=94=E8=B5=9B=E6=8E=92=E5=90=8D?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=8F=90=E7=A4=BA=E9=94=99=E8=AF=AF=E7=9A=84?= =?UTF-8?q?=E6=AC=A1=E6=95=B0=E5=92=8C=20AC=20=E7=9A=84=E6=97=B6=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0007_contestsubmission_ac_time.py | 19 +++++++++++++++++++ contest/models.py | 2 ++ contest/views.py | 4 ++-- mq/scripts/info.py | 11 ++++++----- utils/templatetags/submission.py | 10 ++++++++-- 5 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 contest/migrations/0007_contestsubmission_ac_time.py diff --git a/contest/migrations/0007_contestsubmission_ac_time.py b/contest/migrations/0007_contestsubmission_ac_time.py new file mode 100644 index 0000000..d7bc904 --- /dev/null +++ b/contest/migrations/0007_contestsubmission_ac_time.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('contest', '0006_merge'), + ] + + operations = [ + migrations.AddField( + model_name='contestsubmission', + name='ac_time', + field=models.IntegerField(default=0), + ), + ] diff --git a/contest/models.py b/contest/models.py index 338e3b1..be80f9e 100644 --- a/contest/models.py +++ b/contest/models.py @@ -84,6 +84,8 @@ class ContestSubmission(models.Model): total_submission_number = models.IntegerField(default=1) # 这道题是 AC 还是没过 ac = models.BooleanField() + # ac 用时 + ac_time = models.IntegerField(default=0) # 总的时间,用于acm 类型的,也需要保存罚时 total_time = models.IntegerField(default=0) diff --git a/contest/views.py b/contest/views.py index e68b81f..d897b4d 100644 --- a/contest/views.py +++ b/contest/views.py @@ -402,8 +402,8 @@ def _cmp(x, y): def contest_rank_page(request, contest_id): contest = Contest.objects.get(id=contest_id) contest_problems = ContestProblem.objects.filter(contest=contest).order_by("sort_index") - result = ContestSubmission.objects.filter(contest=contest).values("user_id").annotate( - total_submit=Sum("total_submission_number")) + result = ContestSubmission.objects.filter(contest=contest).values("user_id").\ + annotate(total_submit=Sum("total_submission_number")) for i in range(0, len(result)): # 这个人所有的提交 submissions = ContestSubmission.objects.filter(user_id=result[i]["user_id"], contest_id=contest_id) diff --git a/mq/scripts/info.py b/mq/scripts/info.py index 119845c..a3e13b9 100644 --- a/mq/scripts/info.py +++ b/mq/scripts/info.py @@ -60,11 +60,12 @@ class MessageQueue(object): # 避免这道题已经 ac 了,但是又重新提交了一遍 if not contest_submission.ac: # 这种情况是这个题目前处于错误状态,就使用已经存储了的罚时加上这道题的实际用时 - logger.debug(contest.start_time) - logger.debug(submission.create_time) - logger.debug((submission.create_time - contest.start_time).total_seconds()) - logger.debug(int((submission.create_time - contest.start_time).total_seconds() / 60)) - contest_submission.total_time += int((submission.create_time - contest.start_time).total_seconds() / 60) + # logger.debug(contest.start_time) + # logger.debug(submission.create_time) + # logger.debug((submission.create_time - contest.start_time).total_seconds()) + # logger.debug(int((submission.create_time - contest.start_time).total_seconds() / 60)) + contest_submission.ac_time = int((submission.create_time - contest.start_time).total_seconds() / 60) + contest_submission.total_time += contest_submission.ac_time # 标记为已经通过 contest_submission.ac = True # contest problem ac 计数器加1 diff --git a/utils/templatetags/submission.py b/utils/templatetags/submission.py index b1f43d2..2e73417 100644 --- a/utils/templatetags/submission.py +++ b/utils/templatetags/submission.py @@ -33,8 +33,14 @@ def get_contest_submission_problem_detail(contest_problem, my_submission): if contest_problem.id in my_submission: submission = my_submission[contest_problem.id] if submission.ac: - return u"\n 时间: " + str(submission.total_time) + u" min" - return "" + # 只提交了一次就AC + if submission.total_submission_number == 1: + return str(submission.ac_time) + " min" + else: + return "20 min × " + str(submission.total_submission_number - 1) + " WA + " + str(submission.ac_time) + " min" + return str(submission.total_submission_number) + " WA" + else: + return "" def get_submission_problem_result_class(contest_problem, my_submission): From 12b6eae6e85460625a26c75acbc010906cf4578f Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Thu, 10 Sep 2015 15:59:48 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E7=9A=84=E9=AA=8C=E8=AF=81=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/serializers.py | 1 + account/views.py | 4 ++++ oj/urls.py | 1 + static/src/js/app/oj/account/change_password.js | 12 +++++++++++- template/src/oj/account/change_password.html | 8 +++++++- utils/captcha/views.py | 8 ++++++++ 6 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 utils/captcha/views.py diff --git a/account/serializers.py b/account/serializers.py index 179d28d..4cda3ae 100644 --- a/account/serializers.py +++ b/account/serializers.py @@ -27,6 +27,7 @@ class UserRegisterSerializer(serializers.Serializer): class UserChangePasswordSerializer(serializers.Serializer): old_password = serializers.CharField() new_password = serializers.CharField(max_length=30, min_length=6) + captcha = serializers.CharField(max_length=4, min_length=4) class UserSerializer(serializers.ModelSerializer): diff --git a/account/views.py b/account/views.py index 1da8967..1304ded 100644 --- a/account/views.py +++ b/account/views.py @@ -7,6 +7,7 @@ from django.db.models import Q from rest_framework.views import APIView from utils.shortcuts import serializer_invalid_response, error_response, success_response, paginate +from utils.captcha import Captcha from .decorators import login_required from .models import User @@ -79,6 +80,9 @@ class UserChangePasswordAPIView(APIView): serializer = UserChangePasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data + captcha = Captcha(request) + if not captcha.check(data["captcha"]): + return error_response(u"验证码错误") username = request.user.username user = auth.authenticate(username=username, password=data["old_password"]) if user: diff --git a/oj/urls.py b/oj/urls.py index a5582d2..8d6e819 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -112,4 +112,5 @@ urlpatterns = [ url(r'^help/$', TemplateView.as_view(template_name="utils/help.html"), name="help_page"), url(r'^api/submission/share/$', SubmissionShareAPIView.as_view(), name="submission_share_api"), + url(r'^captcha/$', "utils.captcha.views.show_captcha", name="show_captcha"), ] diff --git a/static/src/js/app/oj/account/change_password.js b/static/src/js/app/oj/account/change_password.js index 608114f..a66505d 100644 --- a/static/src/js/app/oj/account/change_password.js +++ b/static/src/js/app/oj/account/change_password.js @@ -1,13 +1,22 @@ require(["jquery", "bsAlert", "csrfToken", "validator"], function ($, bsAlert, csrfTokenHeader) { + function refresh_captcha(){ + this.src = "/captcha/?" + Math.random(); + $("#captcha")[0].value = ""; + } + $("#captcha-img").click(function(){ + refresh_captcha(); + }); + $('form').validator().on('submit', function (e) { e.preventDefault(); var newPassword = $("#new_password ").val(); var password = $("#password").val(); + var captcha = $("#captcha").val(); $.ajax({ beforeSend: csrfTokenHeader, url: "/api/change_password/", - data: {new_password: newPassword, old_password: password}, + data: {new_password: newPassword, old_password: password, captcha: captcha}, dataType: "json", method: "post", success: function (data) { @@ -15,6 +24,7 @@ require(["jquery", "bsAlert", "csrfToken", "validator"], function ($, bsAlert, c window.location.href = "/login/"; } else { + refresh_captcha(); bsAlert(data.data); } } diff --git a/template/src/oj/account/change_password.html b/template/src/oj/account/change_password.html index dad9d14..d8099f5 100644 --- a/template/src/oj/account/change_password.html +++ b/template/src/oj/account/change_password.html @@ -17,7 +17,13 @@
- + +
+
+
+ + +
diff --git a/utils/captcha/views.py b/utils/captcha/views.py new file mode 100644 index 0000000..8562912 --- /dev/null +++ b/utils/captcha/views.py @@ -0,0 +1,8 @@ +# coding=utf-8 +from django.http import HttpResponse + +from utils.captcha import Captcha + + +def show_captcha(request): + return HttpResponse(Captcha(request).display(), content_type="image/gif")