Skip to content

Commit d8bb845

Browse files
committed
Accept Merge Request QingdaoU#331 dev -> master : (dev -> master)
Merge Request: dev -> master Created By: @virusdefender Accepted By: @virusdefender URL: https://coding.net/u/virusdefender/p/qduoj/git/merge/331
2 parents 8a90b10 + fbbc355 commit d8bb845

87 files changed

Lines changed: 977 additions & 584 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# -*- coding: utf-8 -*-
2+
# Generated by Django 1.9 on 2015-12-08 06:22
3+
from __future__ import unicode_literals
4+
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('account', '0014_auto_20151110_1037'),
12+
]
13+
14+
operations = [
15+
migrations.AddField(
16+
model_name='userprofile',
17+
name='student_id',
18+
field=models.CharField(blank=True, max_length=15, null=True),
19+
),
20+
]

account/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class UserProfile(models.Model):
7070
problems_status = JSONField(default={})
7171
phone_number = models.CharField(max_length=15, blank=True, null=True)
7272
school = models.CharField(max_length=200, blank=True, null=True)
73-
73+
student_id = models.CharField(max_length=15, blank=True, null=True)
7474

7575
class Meta:
7676
db_table = "user_profile"

account/serializers.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class UserRegisterSerializer(serializers.Serializer):
2525
password = serializers.CharField(max_length=30, min_length=6)
2626
email = serializers.EmailField(max_length=254)
2727
captcha = serializers.CharField(max_length=4, min_length=4)
28+
student_id = serializers.CharField(max_length=15, required=False, default=None)
2829

2930

3031
class UserChangePasswordSerializer(serializers.Serializer):
@@ -74,11 +75,12 @@ class EditUserProfileSerializer(serializers.Serializer):
7475
codeforces_username = serializers.CharField(max_length=30, required=False, allow_blank=True, default='')
7576
school = serializers.CharField(max_length=200, required=False, allow_blank=True, default='')
7677
phone_number = serializers.CharField(max_length=15, required=False, allow_blank=True, default='')
78+
student_id = serializers.CharField(max_length=15, required=False, default="")
7779

7880

7981
class UserProfileSerializer(serializers.ModelSerializer):
8082

8183
class Meta:
8284
model = UserProfile
8385
fields = ["avatar", "blog", "mood", "hduoj_username", "bestcoder_username", "codeforces_username",
84-
"rank", "accepted_number", "submissions_number", "problems_status", "phone_number", "school"]
86+
"rank", "accepted_number", "submissions_number", "problems_status", "phone_number", "school", "student_id"]

account/views.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from utils.shortcuts import (serializer_invalid_response, error_response,
1515
success_response, error_page, paginate, rand_str)
1616
from utils.captcha import Captcha
17-
from mail.tasks import send_email
17+
from utils.mail import send_email
1818

1919
from .decorators import login_required
2020
from .models import User, UserProfile
@@ -97,7 +97,7 @@ def post(self, request):
9797
email=data["email"])
9898
user.set_password(data["password"])
9999
user.save()
100-
UserProfile.objects.create(user=user, school=data["school"])
100+
UserProfile.objects.create(user=user, school=data["school"], student_id=data["student_id"])
101101
return success_response(u"注册成功!")
102102
else:
103103
return serializer_invalid_response(serializer)
@@ -262,6 +262,7 @@ def put(self, request):
262262
user_profile.codeforces_username = data["codeforces_username"]
263263
user_profile.blog = data["blog"]
264264
user_profile.school = data["school"]
265+
user_profile.student_id = data["student_id"]
265266
user_profile.phone_number = data["phone_number"]
266267
user_profile.save()
267268
return success_response(u"修改成功")

contest/decorators.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
from utils.shortcuts import error_response, error_page
1010

11-
from account.models import SUPER_ADMIN
12-
from .models import (Contest, PASSWORD_PROTECTED_CONTEST, PUBLIC_CONTEST, GROUP_CONTEST,
11+
from account.models import SUPER_ADMIN, ADMIN
12+
from .models import (Contest, PASSWORD_PROTECTED_CONTEST, PASSWORD_PROTECTED_GROUP_CONTEST, PUBLIC_CONTEST, GROUP_CONTEST,
1313
CONTEST_ENDED, CONTEST_NOT_START, CONTEST_UNDERWAY)
1414

1515

@@ -57,7 +57,10 @@ def _check_user_contest_permission(*args, **kwargs):
5757

5858
if request.user.admin_type == SUPER_ADMIN or request.user == contest.created_by:
5959
return func(*args, **kwargs)
60-
60+
if request.user.admin_type == ADMIN:
61+
contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all())
62+
if contest in contest_set:
63+
return func(*args, **kwargs)
6164
# 管理员可见隐藏的比赛,已经先判断了身份
6265
if not contest.visible:
6366
if request.is_ajax():
@@ -83,6 +86,15 @@ def _check_user_contest_permission(*args, **kwargs):
8386
else:
8487
return render(request, "oj/contest/no_contest_permission.html",
8588
{"reason": "group_limited", "show_tab": False, "contest": contest})
89+
90+
if contest.contest_type == PASSWORD_PROTECTED_GROUP_CONTEST:
91+
if not contest.groups.filter(id__in=request.user.group_set.all()).exists():
92+
if contest.id not in request.session.get("contests", []):
93+
if request.is_ajax():
94+
return error_response(u"请先输入密码")
95+
else:
96+
return render(request, "oj/contest/no_contest_permission.html",
97+
{"reason": "password_protect", "show_tab": False, "contest": contest})
8698

8799
# 比赛没有开始
88100
if contest.status == CONTEST_NOT_START:

contest/models.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
from group.models import Group
88
from utils.models import RichTextField
99
from jsonfield import JSONField
10-
from judge.judger.result import result
10+
from judge.result import result
1111

1212

1313
GROUP_CONTEST = 0
1414
PUBLIC_CONTEST = 1
1515
PASSWORD_PROTECTED_CONTEST = 2
16+
PASSWORD_PROTECTED_GROUP_CONTEST = 3
1617

1718
CONTEST_NOT_START = 1
1819
CONTEST_ENDED = -1

contest/views.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
success_response, paginate, error_page, paginate_data)
1818
from account.models import SUPER_ADMIN, User
1919
from account.decorators import login_required, super_admin_required
20-
from group.models import Group
20+
from group.models import Group, AdminGroupRelation, UserGroupRelation
2121
from utils.cache import get_cache_redis
2222
from submission.models import Submission
2323
from problem.models import Problem
2424
from .models import (Contest, ContestProblem, CONTEST_ENDED,
2525
CONTEST_NOT_START, CONTEST_UNDERWAY, ContestRank)
26-
from .models import GROUP_CONTEST, PUBLIC_CONTEST, PASSWORD_PROTECTED_CONTEST
26+
from .models import GROUP_CONTEST, PUBLIC_CONTEST, PASSWORD_PROTECTED_CONTEST, PASSWORD_PROTECTED_GROUP_CONTEST
2727
from .decorators import check_user_contest_permission
2828
from .serializers import (CreateContestSerializer, ContestSerializer, EditContestSerializer,
2929
CreateContestProblemSerializer, ContestProblemSerializer,
@@ -50,11 +50,11 @@ def post(self, request):
5050
if request.user.admin_type != SUPER_ADMIN:
5151
return error_response(u"只有超级管理员才可创建公开赛")
5252

53-
if data["contest_type"] == PASSWORD_PROTECTED_CONTEST:
53+
if data["contest_type"] in [PASSWORD_PROTECTED_CONTEST, PASSWORD_PROTECTED_GROUP_CONTEST]:
5454
if not data["password"]:
55-
return error_response(u"此比赛为有密码的公开赛,密码不可为空")
55+
return error_response(u"此比赛为有密码的比赛,密码不可为空")
5656
# 没有密码的公开赛 没有密码的小组赛
57-
elif data["contest_type"] == GROUP_CONTEST:
57+
if data["contest_type"] == GROUP_CONTEST or data["contest_type"] == PASSWORD_PROTECTED_GROUP_CONTEST:
5858
if request.user.admin_type == SUPER_ADMIN:
5959
groups = Group.objects.filter(id__in=data["groups"])
6060
else:
@@ -91,8 +91,10 @@ def put(self, request):
9191
try:
9292
# 超级管理员可以编辑所有的
9393
contest = Contest.objects.get(id=data["id"])
94-
if request.user.admin_type != SUPER_ADMIN and contest.created_by != request.user:
95-
return error_response(u"无权访问!")
94+
if request.user.admin_type != SUPER_ADMIN:
95+
contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all())
96+
if contest not in contest_set:
97+
return error_response(u"无权访问!")
9698
except Contest.DoesNotExist:
9799
return error_response(u"该比赛不存在!")
98100
try:
@@ -107,7 +109,7 @@ def put(self, request):
107109
if data["contest_type"] == PASSWORD_PROTECTED_CONTEST:
108110
if not data["password"]:
109111
return error_response(u"此比赛为有密码的公开赛,密码不可为空")
110-
elif data["contest_type"] == GROUP_CONTEST:
112+
elif data["contest_type"] in [GROUP_CONTEST, PASSWORD_PROTECTED_GROUP_CONTEST]:
111113
if request.user.admin_type == SUPER_ADMIN:
112114
groups = Group.objects.filter(id__in=data["groups"])
113115
else:
@@ -151,16 +153,18 @@ def get(self, request):
151153
# 普通管理员只能获取自己创建的题目
152154
# 超级管理员可以获取全部的题目
153155
contest = Contest.objects.get(id=contest_id)
154-
if request.user.admin_type != SUPER_ADMIN and contest.created_by != request.user:
155-
return error_response(u"题目不存在")
156+
if request.user.admin_type != SUPER_ADMIN:
157+
contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all())
158+
if contest not in contest_set:
159+
return error_response(u"比赛不存在")
156160
return success_response(ContestSerializer(contest).data)
157161
except Contest.DoesNotExist:
158-
return error_response(u"题目不存在")
162+
return error_response(u"比赛不存在")
159163

160164
if request.user.admin_type == SUPER_ADMIN:
161165
contest = Contest.objects.all().order_by("-create_time")
162166
else:
163-
contest = Contest.objects.filter(created_by=request.user).order_by("-create_time")
167+
contest = Contest.objects.filter(groups__in=request.user.managed_groups.all()).distinct().order_by("-create_time")
164168
visible = request.GET.get("visible", None)
165169
if visible:
166170
contest = contest.filter(visible=(visible == "true"))
@@ -184,8 +188,10 @@ def post(self, request):
184188
data = serializer.data
185189
try:
186190
contest = Contest.objects.get(id=data["contest_id"])
187-
if request.user.admin_type != SUPER_ADMIN and contest.created_by != request.user:
188-
return error_response(u"比赛不存在")
191+
if request.user.admin_type != SUPER_ADMIN:
192+
contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all())
193+
if contest not in contest_set:
194+
return error_response(u"比赛不存在")
189195
except Contest.DoesNotExist:
190196
return error_response(u"比赛不存在")
191197
contest_problem = ContestProblem.objects.create(title=data["title"],
@@ -362,7 +368,10 @@ def contest_problem_page(request, contest_id, contest_problem_id):
362368
request.user.admin_type == SUPER_ADMIN or \
363369
request.user == contest.created_by:
364370
show_submit_code_area = True
365-
371+
else:
372+
contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all())
373+
if contest in contest_set:
374+
show_submit_code_area = True
366375
return render(request, "oj/problem/contest_problem.html", {"problem": problem,
367376
"contest": contest,
368377
"samples": json.loads(problem.samples),
File renamed without changes.

dockerfiles/judger/Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ RUN cd lrun && make install
1919
RUN mkdir -p /var/judger/run/ && mkdir /var/judger/test_case/ && mkdir /var/judger/code/
2020
RUN chmod -R 777 /var/judger/run/
2121
COPY policy /var/judger/run/
22-
WORKDIR /var/judger/code/
22+
WORKDIR /var/judger/code/judge/
23+
CMD python server.py

dockerfiles/oj_web_server/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ redis
44
django-redis-sessions
55
djangorestframework
66
django-rest-swagger
7-
celery
87
gunicorn
98
coverage
109
django-extensions
1110
supervisor
1211
pillow
1312
jsonfield
14-
Envelopes
13+
Envelopes
14+
huey

0 commit comments

Comments
 (0)