diff --git a/account/decorators.py b/account/decorators.py index 45215301..99d2a8ff 100644 --- a/account/decorators.py +++ b/account/decorators.py @@ -73,7 +73,7 @@ def check_contest_permission(check_type="details"): else: contest_id = request.GET.get("contest_id") if not contest_id: - return self.error("Parameter contest_id not exist.") + return self.error("Parameter contest_id doesn't exist.") try: # use self.contest to avoid query contest again in view. diff --git a/account/serializers.py b/account/serializers.py index f1447679..c07e6ca2 100644 --- a/account/serializers.py +++ b/account/serializers.py @@ -77,13 +77,13 @@ class EditUserSerializer(serializers.Serializer): class EditUserProfileSerializer(serializers.Serializer): - real_name = serializers.CharField(max_length=32, allow_blank=True) - avatar = serializers.CharField(max_length=256, allow_blank=True, required=False) - blog = serializers.URLField(max_length=256, allow_blank=True, required=False) - mood = serializers.CharField(max_length=256, allow_blank=True, required=False) - github = serializers.CharField(max_length=64, allow_blank=True, required=False) - school = serializers.CharField(max_length=64, allow_blank=True, required=False) - major = serializers.CharField(max_length=64, allow_blank=True, required=False) + real_name = serializers.CharField(max_length=32, allow_null=True, required=False) + avatar = serializers.CharField(max_length=256, allow_null=True, allow_blank=True, required=False) + blog = serializers.URLField(max_length=256, allow_null=True, allow_blank=True, required=False) + mood = serializers.CharField(max_length=256, allow_null=True, allow_blank=True, required=False) + github = serializers.CharField(max_length=64, allow_null=True, allow_blank=True, required=False) + school = serializers.CharField(max_length=64, allow_null=True, allow_blank=True, required=False) + major = serializers.CharField(max_length=64, allow_null=True, allow_blank=True, required=False) class ApplyResetPasswordSerializer(serializers.Serializer): diff --git a/contest/migrations/0007_contestannouncement_visible.py b/contest/migrations/0007_contestannouncement_visible.py new file mode 100644 index 00000000..679874f7 --- /dev/null +++ b/contest/migrations/0007_contestannouncement_visible.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2017-11-06 09:02 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('contest', '0006_auto_20171011_1214'), + ] + + operations = [ + migrations.AddField( + model_name='contestannouncement', + name='visible', + field=models.BooleanField(default=True), + ), + ] diff --git a/contest/models.py b/contest/models.py index 1ed8ff9a..aab9e7e1 100644 --- a/contest/models.py +++ b/contest/models.py @@ -93,6 +93,7 @@ class ContestAnnouncement(models.Model): title = models.CharField(max_length=128) content = RichTextField() created_by = models.ForeignKey(User) + visible = models.BooleanField(default=True) create_time = models.DateTimeField(auto_now_add=True) class Meta: diff --git a/contest/serializers.py b/contest/serializers.py index 356a150c..ba8df287 100644 --- a/contest/serializers.py +++ b/contest/serializers.py @@ -54,9 +54,17 @@ class ContestAnnouncementSerializer(serializers.ModelSerializer): class CreateContestAnnouncementSerializer(serializers.Serializer): + contest_id = serializers.IntegerField() title = serializers.CharField(max_length=128) content = serializers.CharField() - contest_id = serializers.IntegerField() + visible = serializers.BooleanField() + + +class EditContestAnnouncementSerializer(serializers.Serializer): + id = serializers.IntegerField() + title = serializers.CharField(max_length=128, required=False) + content = serializers.CharField(required=False, allow_blank=True) + visible = serializers.BooleanField(required=False) class ContestPasswordVerifySerializer(serializers.Serializer): diff --git a/contest/tests.py b/contest/tests.py index 9ce9890b..f8c5b73e 100644 --- a/contest/tests.py +++ b/contest/tests.py @@ -60,7 +60,7 @@ class ContestAPITest(APITestCase): self.create_admin() url = self.reverse("contest_admin_api") self.contest = self.client.post(url, data=DEFAULT_CONTEST_DATA).data["data"] - self.url = self.reverse("contest_api") + "?contest_id=" + str(self.contest["id"]) + self.url = self.reverse("contest_api") + "?id=" + str(self.contest["id"]) def test_get_contest_list(self): url = self.reverse("contest_list_api") @@ -100,7 +100,7 @@ class ContestAnnouncementAdminAPITest(APITestCase): self.create_super_admin() self.url = self.reverse("contest_announcement_admin_api") contest_id = self.create_contest().data["data"]["id"] - self.data = {"title": "test title", "content": "test content", "contest_id": contest_id} + self.data = {"title": "test title", "content": "test content", "contest_id": contest_id, "visible": True} def create_contest(self): url = self.reverse("contest_admin_api") diff --git a/contest/views/admin.py b/contest/views/admin.py index 58e8c7b0..6b53abd4 100644 --- a/contest/views/admin.py +++ b/contest/views/admin.py @@ -6,7 +6,8 @@ from ..models import Contest, ContestAnnouncement from ..serializers import (ContestAnnouncementSerializer, ContestAdminSerializer, CreateConetestSeriaizer, CreateContestAnnouncementSerializer, - EditConetestSeriaizer) + EditConetestSeriaizer, + EditContestAnnouncementSerializer) class ContestAPI(APIView): @@ -83,6 +84,23 @@ class ContestAnnouncementAPI(APIView): announcement = ContestAnnouncement.objects.create(**data) return self.success(ContestAnnouncementSerializer(announcement).data) + @validate_serializer(EditContestAnnouncementSerializer) + def put(self, request): + """ + update contest_announcement + """ + data = request.data + try: + contest_announcement = ContestAnnouncement.objects.get(id=data.pop("id")) + if request.user.is_admin() and contest_announcement.created_by != request.user: + return self.error("Contest announcement does not exist") + except ContestAnnouncement.DoesNotExist: + return self.error("Contest announcement does not exist") + for k, v in data.items(): + setattr(contest_announcement, k, v) + contest_announcement.save() + return self.success() + def delete(self, request): """ Delete one contest_announcement. diff --git a/contest/views/oj.py b/contest/views/oj.py index 342d30c4..d50e0e98 100644 --- a/contest/views/oj.py +++ b/contest/views/oj.py @@ -17,7 +17,7 @@ class ContestAnnouncementListAPI(APIView): contest_id = request.GET.get("contest_id") if not contest_id: return self.error("Invalid parameter") - data = ContestAnnouncement.objects.select_related("created_by").filter(contest_id=contest_id) + data = ContestAnnouncement.objects.select_related("created_by").filter(contest_id=contest_id, visible=True) max_id = request.GET.get("max_id") if max_id: data = data.filter(id__gt=max_id) @@ -25,9 +25,15 @@ class ContestAnnouncementListAPI(APIView): class ContestAPI(APIView): - @check_contest_permission(check_type="details") def get(self, request): - return self.success(ContestSerializer(self.contest).data) + id = request.GET.get("id") + if not id: + return self.error("Invalid parameter") + try: + contest = Contest.objects.get(id=id) + return self.success(ContestSerializer(contest).data) + except Contest.DoesNotExist: + return self.error("Contest does not exist") class ContestListAPI(APIView): diff --git a/judge/languages.py b/judge/languages.py index 2a4281d0..cc5f09b2 100644 --- a/judge/languages.py +++ b/judge/languages.py @@ -59,7 +59,7 @@ _cpp_lang_config = { "exe_name": "main", "max_cpu_time": 3000, "max_real_time": 5000, - "max_memory": 256 * 1024 * 1024, + "max_memory": 512 * 1024 * 1024, "compile_command": "/usr/bin/g++ -DONLINE_JUDGE -O2 -w -fmax-errors=3 -std=c++11 {src_path} -lm -o {exe_path}", }, "run": { diff --git a/problem/views/admin.py b/problem/views/admin.py index c0c3d3da..7d1ac676 100644 --- a/problem/views/admin.py +++ b/problem/views/admin.py @@ -361,4 +361,3 @@ class MakeContestProblemPublicAPIView(APIView): problem.save() problem.tags.set(tags) return self.success() - diff --git a/submission/views/oj.py b/submission/views/oj.py index e66aa5bd..b0751c35 100644 --- a/submission/views/oj.py +++ b/submission/views/oj.py @@ -137,6 +137,7 @@ class SubmissionListAPI(APIView): problem_id = request.GET.get("problem_id") myself = request.GET.get("myself") result = request.GET.get("result") + username = request.GET.get("username") if problem_id: try: problem = Problem.objects.get(_id=problem_id, contest_id__isnull=True, visible=True) @@ -145,6 +146,8 @@ class SubmissionListAPI(APIView): submissions = submissions.filter(problem=problem) if myself and myself == "1": submissions = submissions.filter(user_id=request.user.id) + elif username: + submissions = submissions.filter(username=username) if result: submissions = submissions.filter(result=result) data = self.paginate_data(request, submissions) @@ -163,6 +166,7 @@ class ContestSubmissionListAPI(APIView): problem_id = request.GET.get("problem_id") myself = request.GET.get("myself") result = request.GET.get("result") + username = request.GET.get("username") if problem_id: try: problem = Problem.objects.get(_id=problem_id, contest_id=contest.id, visible=True) @@ -172,6 +176,8 @@ class ContestSubmissionListAPI(APIView): if myself and myself == "1": submissions = submissions.filter(user_id=request.user.id) + elif username: + submissions = submissions.filter(username=username) if result: submissions = submissions.filter(result=result) diff --git a/utils/api/api.py b/utils/api/api.py index 09671d27..e33daafb 100644 --- a/utils/api/api.py +++ b/utils/api/api.py @@ -111,7 +111,7 @@ class APIView(View): limit = int(request.GET.get("limit", "10")) except ValueError: limit = 10 - if limit < 0 or limit > 100: + if limit < 0 or limit > 250: limit = 10 try: offset = int(request.GET.get("offset", "0"))