def post(self, request): problem_id = request.data.get("problem_id", -1) try: problem = ContestProblem.objects.get(id=problem_id, is_public=False) problem.is_public = True problem.save() except ContestProblem.DoesNotExist: return error_response(u"比赛不存在") if problem.contest.status != CONTEST_ENDED: return error_response(u"比赛还没有结束,不能公开题目") Problem.objects.create( title=problem.title, description=problem.description, input_description=problem.input_description, output_description=problem.output_description, samples=problem.samples, test_case_id=problem.test_case_id, hint=problem.hint, created_by=problem.created_by, time_limit=problem.time_limit, memory_limit=problem.memory_limit, visible=False, difficulty=-1, source=problem.contest.title, ) problem.is_public = True problem.save() return success_response(u"创建成功")
def put(self, request): """ 用户编辑json api接口 --- request_serializer: EditUserSerializer response_serializer: UserSerializer """ serializer = EditUserSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: user = User.objects.get(id=data["id"]) except User.DoesNotExist: return error_response(u"该用户不存在!") try: user = User.objects.get(username=data["username"]) if user.id != data["id"]: return error_response(u"昵称已经存在") except User.DoesNotExist: pass user.username = data["username"] user.real_name = data["real_name"] user.email = data["email"] user.admin_type = data["admin_type"] if data["password"]: user.set_password(data["password"]) user.save() return success_response(UserSerializer(user).data) else: return serializer_invalid_response(serializer)
def put(self, request): """ 比赛题目编辑json api接口 --- request_serializer: EditContestProblemSerializer response_serializer: ContestProblemSerializer """ serializer = EditContestProblemSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: contest_problem = ContestProblem.objects.get(id=data["id"]) except ContestProblem.DoesNotExist: return error_response(u"该比赛题目不存在!") contest = Contest.objects.get(id=contest_problem.contest_id) if request.user.admin_type != SUPER_ADMIN and contest.created_by != request.user: return error_response(u"比赛不存在") contest_problem.title = data["title"] contest_problem.description = data["description"] contest_problem.input_description = data["input_description"] contest_problem.output_description = data["output_description"] contest_problem.test_case_id = data["test_case_id"] contest_problem.time_limit = data["time_limit"] contest_problem.memory_limit = data["memory_limit"] contest_problem.samples = json.dumps(data["samples"]) contest_problem.hint = data["hint"] contest_problem.visible = data["visible"] contest_problem.sort_index = data["sort_index"] contest_problem.last_update_time = now() contest_problem.save() return success_response(ContestProblemSerializer(contest_problem).data) else: return serializer_invalid_response(serializer)
def post(self, request): """ 提交请求重置密码 --- request_serializer: ApplyResetPasswordSerializer """ serializer = ApplyResetPasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: user = User.objects.get(email=data["email"]) except User.DoesNotExist: return error_response(u"用户不存在") if user.reset_password_token_create_time and (now() - user.reset_password_token_create_time).total_seconds() < 20 * 60: return error_response(u"20分钟内只能找回一次密码") user.reset_password_token = rand_str() user.reset_password_token_create_time = now() user.save() email_template = codecs.open(settings.TEMPLATES[0]["DIRS"][0] + "utils/reset_password_email.html", "r", "utf-8").read() email_template = email_template.replace("{{ username }}", user.username).\ replace("{{ website_name }}", settings.WEBSITE_INFO["website_name"]).\ replace("{{ link }}", request.scheme + "://" + request.META['HTTP_HOST'] + "/reset_password/t/" + user.reset_password_token) send_email(settings.WEBSITE_INFO["website_name"], user.email, user.username, settings.WEBSITE_INFO["website_name"] + u" 登录信息找回邮件", email_template) return success_response(u"邮件发送成功,请前往您的邮箱查收") else: return serializer_invalid_response(serializer)
def post(self, request): """ 用户登录json api接口 --- request_serializer: UserLoginSerializer """ serializer = UserLoginSerializer(data=request.data) if serializer.is_valid(): data = serializer.data user = auth.authenticate(username=data["username"], password=data["password"]) # 用户名或密码错误的话 返回None if user: if not user.two_factor_auth: auth.login(request, user) return success_response(u"登录成功") # 没有输入两步验证的验证码 if user.two_factor_auth and "tfa_code" not in data: return success_response("tfa_required") if OtpAuth(user.tfa_token).valid_totp(data["tfa_code"]): auth.login(request, user) return success_response(u"登录成功") else: return error_response(u"验证码错误") else: return error_response(u"用户名或密码错误") else: return serializer_invalid_response(serializer)
def post(self, request): """ 用户注册json api接口 --- request_serializer: UserRegisterSerializer """ serializer = UserRegisterSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: User.objects.get(username=data["username"]) return error_response(u"用户名已存在") except User.DoesNotExist: pass try: User.objects.get(email=data["email"]) return error_response(u"该邮箱已被注册,请换其他邮箱进行注册") except User.DoesNotExist: user = User.objects.create(username=data["username"], real_name=data["real_name"], email=data["email"]) user.set_password(data["password"]) user.save() return success_response(u"注册成功!") else: return serializer_invalid_response(serializer)
def put(self, request): """ 同意或者拒绝加入小组请求 --- request_serializer: PutJoinGroupRequestSerializer """ serializer = PutJoinGroupRequestSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: join_request = JoinGroupRequest.objects.get(id=data["request_id"], group__admin=request.user, status=False) except JoinGroupRequest.DoesNotExist: return error_response(u"请求不存在") join_request.status = True join_request.save() if data["status"]: if join_group(join_request.user, join_request.group): join_request.accepted = True join_request.save() return success_response(u"加入成功") else: return error_response(u"加入失败,已经在本小组内") else: return success_response(u"已拒绝") else: return serializer_invalid_response(serializer)
def put(self, request): """ 修改小组信息的api --- request_serializer: EditGroupSerializer response_serializer: GroupSerializer """ serializer = EditGroupSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: group = self.get_group(request, data["group_id"]) except Group.DoesNotExist: return error_response(u"小组不存在") try: group.name = data["name"] group.description = data["description"] group.join_group_setting = data["join_group_setting"] group.visible = data["visible"] group.save() except IntegrityError: return error_response(u"小组名已经存在") return success_response(GroupSerializer(group).data) else: return serializer_invalid_response(serializer)
def post(self, request): """ 创建比赛的提交 --- request_serializer: CreateContestSubmissionSerializer """ serializer = CreateContestSubmissionSerializer(data=request.data) if serializer.is_valid(): data = serializer.data contest = Contest.objects.get(id=data["contest_id"]) try: problem = ContestProblem.objects.get(contest=contest, id=data["problem_id"]) # 更新题目提交计数器 problem.total_submit_number += 1 problem.save() except ContestProblem.DoesNotExist: return error_response(u"题目不存在") submission = Submission.objects.create(user_id=request.user.id, language=int(data["language"]), contest_id=contest.id, code=data["code"], problem_id=problem.id) try: judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception: return error_response(u"提交判题任务失败") # 增加redis 中判题队列长度的计数器 r = redis.Redis(host=redis_config["host"], port=redis_config["port"], db=redis_config["db"]) r.incr("judge_queue_length") return success_response({"submission_id": submission.id}) else: return serializer_invalid_response(serializer)
def post(self, request): """ 比赛题目发布json api接口 --- request_serializer: CreateContestProblemSerializer response_serializer: ContestProblemSerializer """ serializer = CreateContestProblemSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: contest = Contest.objects.get(id=data["contest_id"]) if request.user.admin_type != SUPER_ADMIN: contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all()) if contest not in contest_set: return error_response(u"比赛不存在") except Contest.DoesNotExist: return error_response(u"比赛不存在") contest_problem = ContestProblem.objects.create(title=data["title"], description=data["description"], input_description=data["input_description"], output_description=data["output_description"], test_case_id=data["test_case_id"], samples=json.dumps(data["samples"]), time_limit=data["time_limit"], memory_limit=data["memory_limit"], created_by=request.user, hint=data["hint"], contest=contest, sort_index=data["sort_index"]) return success_response(ContestProblemSerializer(contest_problem).data) else: return serializer_invalid_response(serializer)
def get(self, request): """ 比赛分页json api接口 --- response_serializer: ContestSerializer """ contest_id = request.GET.get("contest_id", None) if contest_id: try: # 普通管理员只能获取自己创建的题目 # 超级管理员可以获取全部的题目 contest = Contest.objects.get(id=contest_id) if request.user.admin_type != SUPER_ADMIN: contest_set = Contest.objects.filter(groups__in=request.user.managed_groups.all()) if contest not in contest_set: return error_response(u"比赛不存在") return success_response(ContestSerializer(contest).data) except Contest.DoesNotExist: return error_response(u"比赛不存在") if request.user.admin_type == SUPER_ADMIN: contest = Contest.objects.all().order_by("-create_time") else: contest = Contest.objects.filter(groups__in=request.user.managed_groups.all()).distinct().order_by("-create_time") visible = request.GET.get("visible", None) if visible: contest = contest.filter(visible=(visible == "true")) keyword = request.GET.get("keyword", None) if keyword: contest = contest.filter(Q(title__contains=keyword) | Q(description__contains=keyword)) return paginate(request, contest, ContestSerializer)
def post(self, request): serializer = SubmissionRejudgeSerializer(data=request.data) if serializer.is_valid(): submission_id = serializer.data["submission_id"] try: submission = Submission.objects.get(id=submission_id) except Submission.DoesNotExist: return error_response(u"提交不存在") # 目前只考虑前台公开题目的重新判题 try: problem = Problem.objects.get(id=submission.problem_id) except Problem.DoesNotExist: return error_response(u"题目不存在") try: judge.delay(submission_id, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败") # 增加redis 中判题队列长度的计数器 r = redis.Redis(host=redis_config["host"], port=redis_config["port"], db=redis_config["db"]) r.incr("judge_queue_length") return success_response(u"任务提交成功") else: return serializer_invalid_response(serializer)
def get(self, request): test_case_id = request.GET.get("test_case_id", None) if not test_case_id: return error_response(u"参数错误") # 防止URL./../../.上层目录遍历 if not re.compile(r"^[0-9a-zA-Z]+$").match(test_case_id): return error_response(u"参数错误") try: # 超级管理员可以下载全部的题目的测试数据 # 普通管理员只能下载自己创建的题目的测试数据 if request.user.admin_type != SUPER_ADMIN: ContestProblem.objects.get(test_case_id=test_case_id, created_by=request.user) test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id) if not os.path.exists(test_case_dir): return error_response(u"测试用例不存在") # 压缩测试用例,命名规则为 "test_case" + test_case_id + ".zip" test_case_zip = os.path.join("/tmp", "test_case-" + test_case_id + ".zip") zf = zipfile.ZipFile(test_case_zip, "w", zipfile.ZIP_DEFLATED) for filename in os.listdir(test_case_dir): if self._is_legal_test_case_file_name(filename): zf.write(os.path.join(test_case_dir, filename), filename) zf.close() # 大文件传输 response = StreamingHttpResponse(self.file_iterator(test_case_zip)) response['Content-Type'] = 'application/octet-stream' response['Content-Disposition'] = 'attachment;filename=test_case-%s.zip' % test_case_id return response except ContestProblem.DoesNotExist: return error_response(u"题目不存在")
def _submit_code(user, problem_id, language, code): controller = BucketController(user_id=user.id, redis_conn=redis.Redis(host=settings.REDIS_CACHE["host"], port=settings.REDIS_CACHE["port"], db=settings.REDIS_CACHE["db"]), default_capacity=settings.TOKEN_BUCKET_DEFAULT_CAPACITY) bucket = TokenBucket(fill_rate=settings.TOKEN_BUCKET_FILL_RATE, capacity=settings.TOKEN_BUCKET_DEFAULT_CAPACITY, last_capacity=controller.last_capacity, last_timestamp=controller.last_timestamp) if bucket.consume(): controller.last_capacity -= 1 else: return error_response(u"您提交的频率过快, 请等待%d秒" % int(bucket.expected_time() + 1)) try: problem = Problem.objects.get(id=problem_id) except Problem.DoesNotExist: return error_response(u"题目不存在") submission = Submission.objects.create(user_id=user.id, language=language, code=code, problem_id=problem.id) try: _judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id, problem.spj, problem.spj_language, problem.spj_code, problem.spj_version) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败") return success_response({"submission_id": submission.id})
def get(self, request): """ 题目分页json api接口 --- response_serializer: ProblemSerializer """ problem_id = request.GET.get("problem_id", None) if problem_id: try: # 普通管理员只能获取自己创建的题目 # 超级管理员可以获取全部的题目 problem = Problem.objects.get(id=problem_id) if request.user.admin_type != SUPER_ADMIN and problem.created_by != request.user: return error_response(u"题目不存在") return success_response(ProblemSerializer(problem).data) except Problem.DoesNotExist: return error_response(u"题目不存在") # 获取问题列表 problems = Problem.objects.all().order_by("-create_time") if request.user.admin_type != SUPER_ADMIN: problems = problems.filter(created_by=request.user) visible = request.GET.get("visible", None) if visible: problems = problems.filter(visible=(visible == "true")) keyword = request.GET.get("keyword", None) if keyword: problems = problems.filter(Q(title__contains=keyword) | Q(description__contains=keyword)) return paginate(request, problems, ProblemSerializer)
def post(self, request): """ 公告发布json api接口 --- request_serializer: CreateAnnouncementSerializer """ serializer = CreateAnnouncementSerializer(data=request.data) if serializer.is_valid(): data = serializer.data groups = [] # 如果不是全局公告,就去查询一下小组的id 列表中的内容,注意用户身份 if not data["is_global"]: if request.user.admin_type == SUPER_ADMIN: groups = Group.objects.filter(id__in=data["groups"]) else: groups = Group.objects.filter(id__in=data["groups"], admin=request.user) if not groups.count(): return error_response(u"至少选择一个小组") else: if request.user.admin_type != SUPER_ADMIN: return error_response(u"只有超级管理员可以创建全局公告") announcement = Announcement.objects.create(title=data["title"], content=data["content"], created_by=request.user, is_global=data["is_global"]) announcement.groups.add(*groups) return success_response(u"公告发布成功!") else: return serializer_invalid_response(serializer)
def get(self, request): """ 比赛题目分页json api接口 --- response_serializer: ContestProblemSerializer """ contest_problem_id = request.GET.get("contest_problem_id", None) if contest_problem_id: try: contest_problem = ContestProblem.objects.get(id=contest_problem_id) if request.user.admin_type != SUPER_ADMIN and contest_problem.created_by != request.user: return error_response(u"比赛题目不存在") return success_response(ContestProblemSerializer(contest_problem).data) except ContestProblem.DoesNotExist: return error_response(u"比赛题目不存在") contest_problems = ContestProblem.objects.all().order_by("sort_index") if request.user.admin_type != SUPER_ADMIN: contest_problems = contest_problems.filter(created_by=request.user).order_by("sort_index") visible = request.GET.get("visible", None) if visible: contest_problems = contest_problems.filter(visible=(visible == "true")) keyword = request.GET.get("keyword", None) if keyword: contest_problems = contest_problems.filter(Q(title__contains=keyword) | Q(description__contains=keyword)) contest_id = request.GET.get("contest_id", None) if contest_id: contest_problems = contest_problems.filter(contest__id=contest_id).order_by("sort_index") return paginate(request, contest_problems, ContestProblemSerializer)
def get(self, request): """ 查询比赛提交,单个比赛题目提交的adminAPI --- response_serializer: SubmissionSerializer """ problem_id = request.GET.get("problem_id", None) contest_id = request.GET.get("contest_id", None) if contest_id: try: contest = Contest.objects.get(pk=contest_id) except Contest.DoesNotExist: return error_response(u"比赛不存在!") if request.user.admin_type != SUPER_ADMIN and contest.created_by != request.user: return error_response(u"您无权查看该信息!") submissions = Submission.objects.filter(contest_id=contest_id).order_by("-create_time") else: if problem_id: try: contest_problem = ContestProblem.objects.get(pk=problem_id) except ContestProblem.DoesNotExist: return error_response(u"问题不存在!") if request.user.admin_type != SUPER_ADMIN and contest_problem.contest.created_by != request.user: return error_response(u"您无权查看该信息!") submissions = Submission.objects.filter(contest_id=contest_problem.contest_id).order_by("-create_time") else: return error_response(u"参数错误!") if problem_id: submissions = submissions.filter(problem_id=problem_id) return paginate(request, submissions, SubmissionSerializer)
def post(self, request): """ 加入某个小组的api --- request_serializer: CreateJoinGroupRequestSerializer """ serializer = CreateJoinGroupRequestSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: group = Group.objects.get(id=data["group_id"]) except Group.DoesNotExist: return error_response(u"小组不存在") if group.join_group_setting == 0: if join_group(request.user, group): return success_response(u"你已经成功的加入该小组") else: return error_response(u"你已经是小组成员了") elif group.join_group_setting == 1: if not data["message"]: return error_response(u"message : 该字段是必填项。") try: JoinGroupRequest.objects.get(user=request.user, group=group, status=False) return error_response(u"你已经提交过申请了,请等待审核") except JoinGroupRequest.DoesNotExist: JoinGroupRequest.objects.create(user=request.user, group=group, message=data["message"]) return success_response(u"申请提交成功,请等待审核") elif group.join_group_setting == 2: return error_response(u"该小组不允许任何人加入") else: return serializer_invalid_response(serializer)
def post(self, request): """ 用户登录json api接口 --- request_serializer: UserLoginSerializer """ serializer = UserLoginSerializer(data=request.data) if serializer.is_valid(): data = serializer.data if "captcha" not in data: return error_response(u"请填写验证码!") captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") user = auth.authenticate(username=data["username"], password=data["password"]) # 用户名或密码错误的话 返回None if user: auth.login(request, user) return success_response(u"登录成功") else: return error_response(u"用户名或密码错误") else: return serializer_invalid_response(serializer)
def post(self, request): """ 提交请求重置密码 --- request_serializer: ApplyResetPasswordSerializer """ serializer = ApplyResetPasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: user = User.objects.get(username=data["username"], email=data["email"]) except User.DoesNotExist: return error_response(u"用户不存在") user.reset_password_token = rand_str() user.save() email_template = codecs.open(settings.TEMPLATES[0]["DIRS"][0] + "utils/reset_password_email.html", "r", "utf-8").read() email_template = email_template.replace("{{ username }}", user.username).replace("{{ link }}", request.scheme + "://" + request.META['HTTP_HOST'] + "/reset_password/?token=" + user.reset_password_token) send_email(user.email, user.username, u"qduoj 密码找回邮件", email_template) return success_response(u"邮件发生成功") else: return serializer_invalid_response(serializer)
def post(self, request): """ 创建比赛的提交 --- request_serializer: CreateContestSubmissionSerializer """ serializer = CreateContestSubmissionSerializer(data=request.data) if serializer.is_valid(): data = serializer.data contest = Contest.objects.get(id=data["contest_id"]) try: problem = ContestProblem.objects.get(contest=contest, id=data["problem_id"]) except ContestProblem.DoesNotExist: return error_response(u"题目不存在") submission = Submission.objects.create(user_id=request.user.id, language=int(data["language"]), contest_id=contest.id, code=data["code"], problem_id=problem.id) try: _judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id, problem.spj, problem.spj_language, problem.spj_code, problem.spj_version) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败") return success_response({"submission_id": submission.id}) else: return serializer_invalid_response(serializer)
def post(self, request): """ 提交代码 --- request_serializer: CreateSubmissionSerializer """ serializer = CreateSubmissionSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: problem = Problem.objects.get(id=data["problem_id"]) except Problem.DoesNotExist: return error_response(u"题目不存在") submission = Submission.objects.create(user_id=request.user.id, language=int(data["language"]), code=data["code"], problem_id=problem.id) try: judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败") r = redis.Redis(host=redis_config["host"], port=redis_config["port"], db=redis_config["db"]) r.incr("judge_queue_length") return success_response({"submission_id": submission.id}) else: return serializer_invalid_response(serializer)
def get(self, request): submission_id = request.GET.get("submission_id", None) if not submission_id: return error_response(u"参数错误") try: submission = Submission.objects.get(id=submission_id, user_id=request.user.id) except Submission.DoesNotExist: return error_response(u"提交不存在") response_data = {"result": submission.result} if submission.result == 0: response_data["accepted_answer_time"] = submission.accepted_answer_time return success_response(response_data)
def get(self, request): test_case_id = request.GET.get("test_case_id", None) if not test_case_id: return error_response(u"参数错误") test_case_config = os.path.join(settings.TEST_CASE_DIR, test_case_id, "info") try: f = open(test_case_config) config = json.loads(f.read()) f.close() except Exception as e: return error_response(u"读取测试用例出错") return success_response({"file_list": config["test_cases"], "spj": config.get("spj", False)})
def get(self, request): test_case_id = request.GET.get("test_case_id", None) if not test_case_id: return error_response(u"参数错误") test_case_config = settings.TEST_CASE_DIR + test_case_id + "/info" try: f = open(test_case_config) config = json.loads(f.read()) f.close() except Exception as e: return error_response(u"读取测试用例出错") return success_response({"file_list": config["test_cases"]})
def post(self, request): if "file" not in request.FILES: return error_response(u"文件上传失败") f = request.FILES["file"] if f.size > 1024 * 1024: return error_response(u"图片过大") if os.path.splitext(f.name)[-1].lower() not in [".gif", ".jpg", ".jpeg", ".bmp", ".png"]: return error_response(u"需要上传图片格式") name = "avatar_" + rand_str(5) + os.path.splitext(f.name)[-1] with open(os.path.join(settings.IMAGE_UPLOAD_DIR, name), "wb") as img: for chunk in request.FILES["file"]: img.write(chunk) return success_response({"path": "/static/upload/" + name})
def put(self, request): """ 用户编辑json api接口 --- request_serializer: EditUserSerializer response_serializer: UserSerializer """ serializer = EditUserSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: user = User.objects.get(id=data["id"]) except User.DoesNotExist: return error_response(u"该用户不存在!") try: user = User.objects.get(username=data["username"]) if user.id != data["id"]: return error_response(u"昵称已经存在") except User.DoesNotExist: pass user.username = data["username"] user.real_name = data["real_name"] user.email = data["email"] user.admin_type = data["admin_type"] if data["password"]: user.set_password(data["password"]) # 后台控制用户是否可以使用openapi if data["openapi"] is False: user.openapi_appkey = None elif data["openapi"] and user.openapi_appkey is None: user.openapi_appkey = rand_str() # 后台控制用户是否使用两步验证 # 注意:用户没开启,后台开启的话,用户没有绑定过两步验证token,会造成无法登陆的! if data["tfa_auth"] is False: user.two_factor_auth = False elif data["tfa_auth"] and user.two_factor_auth is False: user.two_factor_auth = True user.tfa_token = rand_str() # 后台控制用户是否被禁用 user.is_forbidden = data["is_forbidden"] user.save() return success_response(UserSerializer(user).data) else: return serializer_invalid_response(serializer)
def post(self, request): """ 比赛发布json api接口 --- request_serializer: CreateContestSerializer response_serializer: ContestSerializer """ serializer = CreateContestSerializer(data=request.data) if serializer.is_valid(): data = serializer.data groups = [] # 首先判断比赛的类型: 0 即为是小组赛(GROUP_CONTEST),1 即为是无密码的公开赛(PUBLIC_CONTEST), # 2 即为是有密码的公开赛(PASSWORD_PUBLIC_CONTEST) # 此时为有密码的公开赛,并且此时只能超级管理员才有权限此创建比赛 if data["contest_type"] in [PUBLIC_CONTEST, PASSWORD_PROTECTED_CONTEST]: if request.user.admin_type != SUPER_ADMIN: return error_response(u"只有超级管理员才可创建公开赛") if data["contest_type"] == PASSWORD_PROTECTED_CONTEST: if not data["password"]: return error_response(u"此比赛为有密码的公开赛,密码不可为空") # 没有密码的公开赛 没有密码的小组赛 elif data["contest_type"] == GROUP_CONTEST: if request.user.admin_type == SUPER_ADMIN: groups = Group.objects.filter(id__in=data["groups"]) else: groups = Group.objects.filter(id__in=data["groups"], admin=request.user) if not groups.count(): return error_response(u"请至少选择一个小组") if data["start_time"] >= data["end_time"]: return error_response(u"比赛的开始时间必须早于比赛结束的时间") try: contest = Contest.objects.create( title=data["title"], description=data["description"], contest_type=data["contest_type"], real_time_rank=data["real_time_rank"], password=data["password"], start_time=dateparse.parse_datetime(data["start_time"]), end_time=dateparse.parse_datetime(data["end_time"]), created_by=request.user, visible=data["visible"], ) except IntegrityError: return error_response(u"比赛名已经存在") contest.groups.add(*groups) return success_response(ContestSerializer(contest).data) else: return serializer_invalid_response(serializer)
def get(self, request): """ 查询小组成员的api,需要传递group_id参数 --- response_serializer: GroupMemberSerializer """ group_id = request.GET.get("group_id", None) if not group_id: return error_response(u"参数错误") try: group = self.get_group(request, group_id) except Group.DoesNotExist: return error_response(u"小组不存在") return paginate(request, UserGroupRelation.objects.filter(group=group), GroupMemberSerializer)
def get(self, request): """ openapi 获取提交详情 """ submission_id = request.GET.get("submission_id", None) appkey = request.GET.get("appkey", None) if not (submission_id and appkey): return error_response(u"参数错误") try: user = User.objects.get(openapi_appkey=appkey) except User.DoesNotExist: return error_response(u"appkey无效") try: submission = Submission.objects.get(id=submission_id, user_id=user.id) return success_response( OpenAPISubmissionSerializer(submission).data) except Submission.DoesNotExist: return error_response(u"提交不存在")
def get(self, request): session_token = request.session.get('token') token = request.GET.get("token") if session_token == token: message = "验证通过" return shortcuts.success_response(message) else: message = "短信验证码无效,请稍后点击重新发送短信" return shortcuts.error_response(message)
def post(self, request): serializer = SSOSerializer(data=request.data) if serializer.is_valid(): try: user = User.objects.get(auth_token=serializer.data["token"]) return success_response({"username": user.username}) except User.DoesNotExist: return error_response(u"用户不存在") else: return serializer_invalid_response(serializer)
def __call__(self, *args, **kwargs): if len(args) == 2: self.request = args[1] else: self.request = args[0] if self.check_permission(): if self.request.user.is_forbidden is True: if self.request.is_ajax(): return error_response(u"您已被禁用,请联系管理员") else: return error_page(self.request, u"您已被禁用,请联系管理员") return self.func(*args, **kwargs) else: if self.request.is_ajax(): return error_response(u"请先登录") else: return HttpResponseRedirect("/login/?__from=" + urllib.quote(self.request.path))
def post(self, request): serializer = ResetPasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: user = User.objects.get(reset_password_token=data["token"]) except User.DoesNotExist: return error_response(u"token 不存在") if (now() - user.reset_password_token_create_time).total_seconds() > 30 * 60: return error_response(u"token 已经过期,请在30分钟内重置密码") user.reset_password_token = None user.set_password(data["password"]) user.save() return success_response(u"密码重置成功") else: return serializer_invalid_response(serializer)
def post(self, request): serializer = SSOSerializer(data=request.data) if serializer.is_valid(): try: User.objects.get(openapi_appkey=serializer.data["appkey"]) except User.DoesNotExist: return error_response(u"appkey无效") try: user = User.objects.get(auth_token=serializer.data["token"]) user.auth_token = None user.save() return success_response({"username": user.username, "id": user.id, "admin_type": user.admin_type, "avatar": user.userprofile.avatar}) except User.DoesNotExist: return error_response(u"用户不存在") else: return serializer_invalid_response(serializer)
def get(self, request): """ 查询小组成员的api,需要传递group_id参数 --- response_serializer: GroupMemberSerializer """ group_id = request.GET.get("group_id", None) if not group_id: return error_response(u"参数错误") try: group = self.get_group(request, group_id) except Group.DoesNotExist: return error_response(u"小组不存在") admin_only = request.GET.get("admin_only", None) if admin_only: members = AdminGroupRelation.objects.filter(group=group) else: members = UserGroupRelation.objects.filter(group=group) return paginate(request, members, GroupMemberSerializer)
def check(*args, **kwargs): # 在class based views 里面,args 有两个元素,一个是self, 第二个才是request, # 在function based views 里面,args 只有request 一个参数 if len(args) == 2: request = args[-1] else: request = args[0] # 这是在后台使用的url middleware 已经确保用户是登录状态的了 try: problem = Problem.objects.get(id=request.data.get("id", -1)) except Problem.DoesNotExist: return error_response(u"问题不存在") if request.user.admin_type == SUPER_ADMIN: return func(*args, **kwargs) else: if problem.created_by != request.user: return error_response(u"问题不存在") return func(*args, **kwargs)
def get(self,request): posts=Post.objects.all() topic_id=request.GET.get("topic_id",None) keyword = request.GET.get("keyword", None) if keyword and topic_id: posts = Post.objects.filter(Q(content_raw__contains=keyword),topic_id=topic_id) elif topic_id: posts = Post.objects.filter(topic_id=topic_id) else : return error_response("no this topic_id!") return paginate(request,posts,PostSerializer)
def post(self, request): """ 提交请求重置密码 --- request_serializer: ApplyResetPasswordSerializer """ serializer = ApplyResetPasswordSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") try: user = User.objects.get(email=data["email"]) except User.DoesNotExist: return error_response(u"用户不存在") if user.reset_password_token_create_time and ( now() - user.reset_password_token_create_time ).total_seconds() < 20 * 60: return error_response(u"20分钟内只能找回一次密码") user.reset_password_token = rand_str() user.reset_password_token_create_time = now() user.save() email_template = codecs.open( settings.TEMPLATES[0]["DIRS"][0] + "utils/reset_password_email.html", "r", "utf-8").read() email_template = email_template.replace("{{ username }}", user.username). \ replace("{{ website_name }}", settings.WEBSITE_INFO["website_name"]). \ replace("{{ link }}", request.scheme + "://" + request.META['HTTP_HOST'] + "/reset_password/t/" + user.reset_password_token) _send_email.delay( settings.WEBSITE_INFO["website_name"], user.email, user.username, settings.WEBSITE_INFO["website_name"] + u" 登录信息找回邮件", email_template) return success_response(u"邮件发送成功,请前往您的邮箱查收") else: return serializer_invalid_response(serializer)
def post(self, request): serializer = ContestPasswordVerifySerializer(data=request.data) if serializer.is_valid(): data = request.data try: contest = Contest.objects.get(id=data["contest_id"], contest_type=PASSWORD_PROTECTED_CONTEST) except Contest.DoesNotExist: return error_response(u"比赛不存在") if data["password"] != contest.password: return error_response(u"密码错误") else: if "contests" not in request.session: request.session["contests"] = [] request.session["contests"].append(int(data["contest_id"])) # https://docs.djangoproject.com/en/dev/topics/http/sessions/#when-sessions-are-saved request.session.modified = True return success_response(True) else: return serializer_invalid_response(serializer)
def put(self, request): serializer = TwoFactorAuthCodeSerializer(data=request.data) if serializer.is_valid(): user = request.user code = serializer.data["code"] if OtpAuth(user.tfa_token).valid_totp(code): user.two_factor_auth = False user.save() else: return error_response(u"验证码错误") else: return serializer_invalid_response(serializer)
def post(self, request): serializer = UserLoginSerializer(data=request.data) if serializer.is_valid(): data = serializer.data print data user = auth.authenticate(userName=data["userName"], password=data["password"]) if user: auth.login(request, user) message = "登录成功" print message return shortcuts.success_response(message) else: message = "您输入的帐号密码不正确,请重新输入" print message return shortcuts.error_response(message) else: message = "请输入正确格式" print message return shortcuts.error_response(message)
def post(self, request): """ 用户登录json api接口 --- request_serializer: UserLoginSerializer """ serializer = UserLoginSerializer(data=request.data) if serializer.is_valid(): data = serializer.data captcha = Captcha(request) if not captcha.check(data["captcha"]): return error_response(u"验证码错误") user = auth.authenticate(username=data["username"], password=data["password"]) # 用户名或密码错误的话 返回None if user: auth.login(request, user) return success_response(u"登录成功") else: return error_response(u"用户名或密码错误") else: return serializer_invalid_response(serializer)
def post(self, request): problem_id = request.data.get("problem_id", -1) try: problem = ContestProblem.objects.get(id=problem_id, is_public=False) problem.is_public = True problem.save() except ContestProblem.DoesNotExist: return error_response(u"比赛不存在") if problem.contest.status != CONTEST_ENDED: return error_response(u"比赛还没有结束,不能公开题目") Problem.objects.create(title=problem.title, description=problem.description, input_description=problem.input_description, output_description=problem.output_description, samples=problem.samples, test_case_id=problem.test_case_id, hint=problem.hint, created_by=problem.created_by, time_limit=problem.time_limit, memory_limit=problem.memory_limit, visible=False, difficulty=-1, source=problem.contest.title) problem.is_public = True problem.save() return success_response(u"创建成功")
def post(self, request): """ 提交代码 --- request_serializer: CreateSubmissionSerializer """ controller = BucketController(user_id=request.user.id, redis_conn=redis.Redis(host=settings.REDIS_CACHE["host"], port=settings.REDIS_CACHE["port"], db=settings.REDIS_CACHE["db"]), default_capacity=settings.TOKEN_BUCKET_DEFAULT_CAPACITY) bucket = TokenBucket(fill_rate=settings.TOKEN_BUCKET_FILL_RATE, capacity=settings.TOKEN_BUCKET_DEFAULT_CAPACITY, last_capacity=controller.last_capacity, last_timestamp=controller.last_timestamp) if bucket.consume(): controller.last_capacity -= 1 else: return error_response(u"您提交的频率过快, 请等待%d秒" % int(bucket.expected_time() + 1)) serializer = CreateSubmissionSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: problem = Problem.objects.get(id=data["problem_id"]) except Problem.DoesNotExist: return error_response(u"题目不存在") submission = Submission.objects.create(user_id=request.user.id, language=int(data["language"]), code=data["code"], problem_id=problem.id) try: _judge.delay(submission, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败") return success_response({"submission_id": submission.id}) else: return serializer_invalid_response(serializer)
def put(self, request): """ 比赛题目编辑json api接口 --- request_serializer: EditContestProblemSerializer response_serializer: ContestProblemSerializer """ serializer = EditContestProblemSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: contest_problem = ContestProblem.objects.get(id=data["id"]) except ContestProblem.DoesNotExist: return error_response(u"该比赛题目不存在!") contest = Contest.objects.get(id=contest_problem.contest_id) if request.user.admin_type != SUPER_ADMIN and contest.created_by != request.user: return error_response(u"比赛不存在") contest_problem.title = data["title"] contest_problem.description = data["description"] contest_problem.input_description = data["input_description"] contest_problem.output_description = data["output_description"] contest_problem.test_case_id = data["test_case_id"] contest_problem.time_limit = data["time_limit"] contest_problem.memory_limit = data["memory_limit"] contest_problem.spj = data["spj"] contest_problem.spj_language = data["spj_language"] contest_problem.spj_code = data["spj_code"] contest_problem.spj_version = self._spj_version(data["spj_code"]) contest_problem.samples = json.dumps(data["samples"]) contest_problem.hint = data["hint"] contest_problem.visible = data["visible"] contest_problem.sort_index = data["sort_index"] contest_problem.last_update_time = now() contest_problem.save() return success_response( ContestProblemSerializer(contest_problem).data) else: return serializer_invalid_response(serializer)
def get(self, request): test_case_id = request.GET.get("test_case_id", None) if not test_case_id: return error_response(u"参数错误") # 防止URL./../../.上层目录遍历 if not re.compile(r"^[0-9a-zA-Z]+$").match(test_case_id): return error_response(u"参数错误") try: # 超级管理员可以下载全部的题目的测试数据 # 普通管理员只能下载自己创建的题目的测试数据 if request.user.admin_type != SUPER_ADMIN: ContestProblem.objects.get(test_case_id=test_case_id, created_by=request.user) test_case_dir = os.path.join(settings.TEST_CASE_DIR, test_case_id) if not os.path.exists(test_case_dir): return error_response(u"测试用例不存在") # 压缩测试用例,命名规则为 "test_case" + test_case_id + ".zip" test_case_zip = os.path.join("/tmp", "test_case-" + test_case_id + ".zip") zf = zipfile.ZipFile(test_case_zip, "w", zipfile.ZIP_DEFLATED) for filename in os.listdir(test_case_dir): # 避免存在文件链接,导致真实文件被打包 if self._is_legal_test_case_file_name( filename) and not os.path.islink( os.path.join(test_case_dir, filename)): zf.write(os.path.join(test_case_dir, filename), filename) zf.close() # 大文件传输 response = StreamingHttpResponse(self.file_iterator(test_case_zip)) response['Content-Type'] = 'application/octet-stream' response[ 'Content-Disposition'] = 'attachment;filename=test_case-%s.zip' % test_case_id return response except ContestProblem.DoesNotExist: return error_response(u"题目不存在")
def post(self, request): """ 比赛题目发布json api接口 --- request_serializer: CreateContestProblemSerializer response_serializer: ContestProblemSerializer """ serializer = CreateContestProblemSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: contest = Contest.objects.get(id=data["contest_id"]) if request.user.admin_type != SUPER_ADMIN: contest_set = Contest.objects.filter( groups__in=request.user.managed_groups.all()) if contest not in contest_set: return error_response(u"比赛不存在") except Contest.DoesNotExist: return error_response(u"比赛不存在") contest_problem = ContestProblem.objects.create( title=data["title"], description=data["description"], input_description=data["input_description"], output_description=data["output_description"], test_case_id=data["test_case_id"], samples=json.dumps(data["samples"]), time_limit=data["time_limit"], memory_limit=data["memory_limit"], spj=data["spj"], spj_language=data["spj_language"], spj_code=data["spj_code"], spj_version=self._spj_version(data["spj_code"]), created_by=request.user, hint=data["hint"], contest=contest, sort_index=data["sort_index"]) return success_response( ContestProblemSerializer(contest_problem).data) else: return serializer_invalid_response(serializer)
def post(self, request): """ 用户修改密码json api接口 --- request_serializer: UserChangePasswordSerializer """ 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: user.set_password(data["new_password"]) user.save() return success_response(u"用户密码修改成功!") else: return error_response(u"密码不正确,请重新修改!") else: return serializer_invalid_response(serializer)
def __call__(self, *args, **kwargs): if len(args) == 2: self.request = args[1] else: self.request = args[0] if self.check_permission(): return self.func(*args, **kwargs) else: if self.request.is_ajax(): return error_response(u"请先登录") else: return HttpResponseRedirect("/login/?__from=" + urllib.quote(self.request.build_absolute_uri()))
def put(self, request): serializer = AppendixSerializer(data=request.data) if serializer.is_valid(): data = serializer.data if str(request.data["dell"]) == '1': try: appendix=Appendix.objects.get(id=int(request.data['id'])) appendix.delete() except Appendix.DoesNotExist: return error_response(u"厉害了,没有这个id,sorry!") return success_response(u"删除成功") else :#修改 try: appendix = Appendix.objects.get(id=int(request.data['id'])) except Appendix.DoesNotExist: return error_response(u"厉害了,没有这个id,sorry!") pass appendix.content_raw = data["content_raw"] appendix.save() return success_response(PostSerializer(appendix).data) else : return serializer_invalid_response(serializer)
def post(self, request): # serializer = SubmissionRejudgeSerializer(data=request.data) # if serializer.is_valid(): # submission_id = serializer.data["submission_id"] # # 目前只考虑前台公开题目的重新判题 # try: # submission = Submission.objects.get(id=submission_id, contest_id__isnull=True) # except Submission.DoesNotExist: # return error_response(u"提交不存在") # # try: # problem = Problem.objects.get(id=submission.problem_id) # except Problem.DoesNotExist: # return error_response(u"题目不存在") # try: # _judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id, # problem.spj, problem.spj_language, problem.spj_code, problem.spj_version) # except Exception as e: # logger.error(e) # return error_response(u"提交判题任务失败") # return success_response(u"任务提交成功,请稍后进行查看") # else: # return serializer_invalid_response(serializer) submissions = Submission.objects.filter(result=8) for submission in submissions: try: problem = Problem.objects.get(id=submission.problem_id) except Problem.DoesNotExist: return error_response(u"题目不存在:{}".format( submission.problem_id)) try: _judge.delay(submission.id, problem.time_limit, problem.memory_limit, problem.test_case_id, problem.spj, problem.spj_language, problem.spj_code, problem.spj_version) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败:{}".format(problem.title)) return success_response(u"重判已经开始,请稍后进行查看")
def post(self, request): serializer = SubmissionRejudgeSerializer(data=request.data) if serializer.is_valid(): submission_id = serializer.data["submission_id"] # 目前只考虑前台公开题目的重新判题 try: submission = Submission.objects.get(id=submission_id, contest_id__isnull=True) except Submission.DoesNotExist: return error_response(u"提交不存在") try: problem = Problem.objects.get(id=submission.problem_id) except Problem.DoesNotExist: return error_response(u"题目不存在") try: _judge.delay(submission, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败") return success_response(u"任务提交成功") else: return serializer_invalid_response(serializer)
def post(self, request): """ 批量导入用户 """ if "file" not in request.FILES: return error_response(u"未上传文件") f = request.FILES["file"] tmp = "/tmp/" + rand_str() + ".xls" import xlrd try: with open(tmp, "wb") as user_info: for line in f: user_info.write(line) except Exception as e: logger.error(e) return error_response(u"写入文件失败") excel_list = {} try: user_info = xlrd.open_workbook(tmp) sheet = user_info.sheet_by_index(0) rows, cols = sheet.nrows, sheet.ncols try: with transaction.atomic(): for row in range(1, rows): username = sheet.cell(row, 0).value real_name = sheet.cell(row, 1).value email = sheet.cell(row, 2).value password = sheet.cell(row, 3).value student_id = sheet.cell(row, 4).value excel_list[str(row)] = { "username": username, "real_name": real_name, "email": email, "password": password, "student_id": student_id } try: User.objects.get(username=username) return error_response(u"{}.该用户名已经存在,请修改".format(username)) except: pass try: User.objects.get(email=email) return error_response(u"{}.该邮箱已经存在,请修改".format(email)) except: pass user = User.objects.create(username=username, real_name=real_name, email=email) user.set_password(password) user.save() UserProfile.objects.create(user=user, student_id=str(int(student_id))) except: return error_response(u"导入用户出错") return success_response({"excel_list": excel_list}) except: return error_response(u"读取文件失败")
def post(self, request): """ post讨论内容 """ msg = request.POST.get("message") problem_id = request.POST.get("problem_id") try: problem = Problem.objects.get(id=problem_id, visible=True) except Problem.DoesNotExist: return error_response(u"题目不存在") ProblemDiscussion.objects.create(message=msg, user=request.user, problem=problem) return success_response(u"留言成功!")
def post(self, request): """ openapi 创建提交 """ serializer = OpenAPICreateSubmissionSerializer(data=request.data) if serializer.is_valid(): data = serializer.data try: user = User.objects.get(openapi_appkey=data["appkey"]) except User.DoesNotExist: return error_response(u"appkey无效") return _submit_code(user, data["problem_id"], data["language"], data["code"]) else: return serializer_invalid_response(serializer)
def get(self, request): """ 搜索小组的api,需要传递keyword参数 --- response_serializer: GroupSerializer """ keyword = request.GET.get("keyword", None) if not keyword: return error_response(u"参数错误") # 搜索包含这个关键词的 没有解散的 而且允许加入的小组 groups = Group.objects.filter(name__contains=keyword, visible=True, join_group_setting__lte=2) return paginate(request, groups, GroupSerializer)
def get(self, request): """ 获取全部判题服务器 """ judge_server_id = request.GET.get("judge_server_id", None) if judge_server_id: try: judge_server = JudgeServer.objects.get(id=judge_server_id) except JudgeServer.DoesNotExist: return error_response(u"判题服务器不存在") return success_response(JudgesSerializer(judge_server).data) judge_server = JudgeServer.objects.all() return paginate(request, judge_server, JudgesSerializer)
def get(self, request): contest_id = request.GET.get("contest_id", -1) try: contest = Contest.objects.get(id=contest_id) except Contest.DoesNotExist: return error_response(u"比赛不存在") return success_response({ "start": int((contest.start_time - now()).total_seconds() * 1000), "end": int((contest.end_time - now()).total_seconds() * 1000), "status": contest.status })