From 675557668ca377929c8c0790357e7400d5a16fe0 Mon Sep 17 00:00:00 2001 From: virusdefender Date: Sun, 13 May 2018 16:40:47 +0800 Subject: [PATCH] update --- Dockerfile | 3 +- account/views/oj.py | 4 ++ deploy/nginx/api_proxy.conf | 2 +- group/migrations/0002_auto_20180510_0041.py | 27 +++++++++++++ group/models.py | 4 +- group/serializers.py | 30 ++++++++++++++ group/urls/oj.py | 7 ++++ group/views/admin.py | 43 +++++++++++++++++++-- group/views/oj.py | 22 +++++++++++ oj/settings.py | 2 +- oj/urls.py | 3 +- 11 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 group/migrations/0002_auto_20180510_0041.py create mode 100644 group/urls/oj.py create mode 100644 group/views/oj.py diff --git a/Dockerfile b/Dockerfile index 41cabf83..88d4c6e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,8 @@ WORKDIR /app HEALTHCHECK --interval=5s --retries=3 CMD python2 /app/deploy/health_check.py -RUN apk add --update --no-cache build-base nginx openssl curl unzip supervisor jpeg-dev zlib-dev postgresql-dev freetype-dev && \ +RUN apk add --update --no-cache build-base nginx openssl curl unzip supervisor jpeg-dev zlib-dev postgresql-dev freetype-dev git && \ + git clone pip install --no-cache-dir -r /app/deploy/requirements.txt && \ apk del build-base --purge diff --git a/account/views/oj.py b/account/views/oj.py index d7e2a646..b168d728 100644 --- a/account/views/oj.py +++ b/account/views/oj.py @@ -11,6 +11,7 @@ from django.utils.timezone import now from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt from otpauth import OtpAuth +from group.models import Group from problem.models import Problem from utils.constants import ContestRuleType from options.options import SysOptions @@ -375,6 +376,7 @@ class SessionManagementAPI(APIView): class UserRankAPI(APIView): def get(self, request): + group_id = request.GET.get("group_id") rule_type = request.GET.get("rule") if rule_type not in ContestRuleType.choices(): rule_type = ContestRuleType.ACM @@ -384,6 +386,8 @@ class UserRankAPI(APIView): profiles = profiles.filter(submission_number__gt=0).order_by("-accepted_number", "submission_number") else: profiles = profiles.filter(total_score__gt=0).order_by("-total_score") + if group_id: + profiles = profiles.filter(user__in=Group.objects.get(id=group_id).members.all()) return self.success(self.paginate_data(request, profiles, RankInfoSerializer)) diff --git a/deploy/nginx/api_proxy.conf b/deploy/nginx/api_proxy.conf index cc508c8e..9997ce78 100644 --- a/deploy/nginx/api_proxy.conf +++ b/deploy/nginx/api_proxy.conf @@ -1,5 +1,5 @@ proxy_pass http://backend; -proxy_set_header X-Real-IP __IP_HEADER__; +proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; client_max_body_size 200M; proxy_http_version 1.1; diff --git a/group/migrations/0002_auto_20180510_0041.py b/group/migrations/0002_auto_20180510_0041.py new file mode 100644 index 00000000..e3215ddf --- /dev/null +++ b/group/migrations/0002_auto_20180510_0041.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.3 on 2018-05-10 00:41 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('group', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='group', + name='allow_join', + field=models.BooleanField(default=True), + preserve_default=False, + ), + migrations.AddField( + model_name='group', + name='password', + field=models.TextField(default=''), + preserve_default=False, + ), + ] diff --git a/group/models.py b/group/models.py index 69050ba4..1a25c5b6 100644 --- a/group/models.py +++ b/group/models.py @@ -3,9 +3,11 @@ from account.models import User class Group(models.Model): - name = models.TextField() + name = models.TextField(unique=True) description = models.TextField() create_time = models.DateTimeField(auto_now_add=True) + password = models.TextField() + allow_join = models.BooleanField() created_by = models.ForeignKey(User, related_name="my_groups") members = models.ManyToManyField(User) diff --git a/group/serializers.py b/group/serializers.py index ac60fd23..16909593 100644 --- a/group/serializers.py +++ b/group/serializers.py @@ -6,7 +6,37 @@ from .models import Group class GroupSerializer(serializers.ModelSerializer): created_by = UsernameSerializer() + members = UsernameSerializer(many=True) class Meta: model = Group fields = "__all__" + + +class CreateGroupSerializer(serializers.Serializer): + name = serializers.CharField() + description = serializers.CharField() + password = serializers.CharField(allow_blank=True) + allow_join = serializers.BooleanField() + + +class EditGroupSerializer(CreateGroupSerializer): + id = serializers.IntegerField() + + +class DeleteGroupSerializer(serializers.Serializer): + group_id = serializers.IntegerField() + user_id = serializers.IntegerField(required=False) + + +class SimpleGroupSerializer(serializers.ModelSerializer): + created_by = UsernameSerializer() + + class Meta: + model = Group + fields = ["id", "created_by", "name"] + + +class JoinGroupSerializer(serializers.Serializer): + group_name = serializers.CharField() + password = serializers.CharField() \ No newline at end of file diff --git a/group/urls/oj.py b/group/urls/oj.py new file mode 100644 index 00000000..4488135f --- /dev/null +++ b/group/urls/oj.py @@ -0,0 +1,7 @@ +from django.conf.urls import url +from ..views.oj import GroupAPI + + +urlpatterns = [ + url(r"^group/?$", GroupAPI.as_view(), name="group_api"), +] diff --git a/group/views/admin.py b/group/views/admin.py index 9d949080..75f24074 100644 --- a/group/views/admin.py +++ b/group/views/admin.py @@ -1,8 +1,11 @@ +from django.db import IntegrityError + from account.decorators import admin_role_required, ensure_created_by +from account.models import User from utils.api import APIView, validate_serializer from ..models import Group -from ..serializers import GroupSerializer +from ..serializers import GroupSerializer, CreateGroupSerializer, EditGroupSerializer, DeleteGroupSerializer class GroupAPI(APIView): @@ -25,11 +28,43 @@ class GroupAPI(APIView): groups = groups.filter(name__contains=keyword) return self.success(self.paginate_data(request, groups, GroupSerializer)) + @validate_serializer(CreateGroupSerializer) def post(self, request): - pass + data = request.data + data["created_by"] = request.user + try: + group = Group.objects.create(**data) + except IntegrityError: + return self.error("小组名不能重复") + return self.success(GroupSerializer(group).data) + @validate_serializer(EditGroupSerializer) def put(self, request): - pass + data = request.data + _id = data.pop("id") + try: + group = Group.objects.get(id=_id) + except Group.DoesNotExist: + return self.error("Group does not exist") + ensure_created_by(group, request.user) + try: + Group.objects.filter(id=_id).update(**data) + except IntegrityError: + return self.error("小组名不能重复") + return self.success() + @validate_serializer(DeleteGroupSerializer) def delete(self, request): - pass + data = request.data + try: + group = Group.objects.get(id=data["group_id"]) + except Group.DoesNotExist: + return self.error("Group does not exist") + ensure_created_by(group, request.user) + if not data.get("user_id"): + group.members.clear() + group.delete() + return self.success() + else: + group.members.remove(User.objects.get(id=data["user_id"])) + return self.success(GroupSerializer(group).data) diff --git a/group/views/oj.py b/group/views/oj.py new file mode 100644 index 00000000..d1485c66 --- /dev/null +++ b/group/views/oj.py @@ -0,0 +1,22 @@ +from group.models import Group +from utils.api import APIView, validate_serializer +from ..serializers import SimpleGroupSerializer, JoinGroupSerializer + + +class GroupAPI(APIView): + def get(self, request): + return self.success(SimpleGroupSerializer(Group.objects.filter(allow_join=True).order_by("-id"), many=True).data) + + @validate_serializer(JoinGroupSerializer) + def post(self, request): + data = request.data + try: + group = Group.objects.get(allow_join=True, name=data["group_name"]) + except Group.DoesNotExist: + return self.error("小组不存在") + if group.members.filter(username=request.user.username).exists(): + return self.error("你已经在小组中了") + if group.password and group.password != data["password"]: + return self.error("密码错误") + group.members.add(request.user) + return self.success() diff --git a/oj/settings.py b/oj/settings.py index 2cb467a3..79cd2646 100644 --- a/oj/settings.py +++ b/oj/settings.py @@ -180,7 +180,7 @@ REST_FRAMEWORK = { ) } -REDIS_URL = "redis://%s:%s" % (REDIS_CONF["host"], REDIS_CONF["port"]) +REDIS_URL = "redis://:foobar@%s:%s" % (REDIS_CONF["host"], REDIS_CONF["port"]) def redis_config(db): diff --git a/oj/urls.py b/oj/urls.py index e12e2dcc..ac4e2233 100644 --- a/oj/urls.py +++ b/oj/urls.py @@ -14,5 +14,6 @@ urlpatterns = [ url(r"^api/", include("submission.urls.oj")), url(r"^api/admin/", include("submission.urls.admin")), url(r"^api/admin/", include("utils.urls")), - url(r"^api/admin/", include("group.urls.admin")) + url(r"^api/admin/", include("group.urls.admin")), + url(r"^api/", include("group.urls.oj")) ]