class ProblemTestdataView(APIView): @method_decorator(parameter_required('pid')) @method_decorator(view_hidden_problem_permission_check()) @method_decorator(permission_required('problem.download_testdata', raise_exception=True)) def get(self, request, pid): # Get problem testdata URL problem = get_object_or_404(Problem, pid=pid) return Response({ 'res': problem.testdata_url }, status=status.HTTP_200_OK) @method_decorator(parameter_required('pid')) @method_decorator(permission_required('problem.edit_problem', raise_exception=True)) @method_decorator(syllable_required('testdata_url', str)) def patch(self, request, pid): # Change problem testdata URL new_value = request.data['testdata_url'] problem = get_object_or_404(Problem, pid=pid) problem.testdata_url = new_value problem.testdata_last_update = timezone.now() problem.save() return Response(status=status.HTTP_204_NO_CONTENT) @method_decorator(parameter_required('pid')) @method_decorator(permission_required('problem.edit_problem', raise_exception=True)) def delete(self, request, pid): problem = get_object_or_404(Problem, pid=pid) problem.testdata_url = None problem.testdata_last_update = timezone.now() problem.save() return Response(status=status.HTTP_204_NO_CONTENT)
class TagView(APIView): @method_decorator(parameter_required('tid')) def get(self, request, tid): # Get a tag tag = get_object_or_404(Tag, id=tid) ts = TagSerializer(tag) return Response({'res': ts.data}, status=status.HTTP_200_OK) @method_decorator(permission_required('problem.add_tag', raise_exception=True)) def post(self, request): # add new tag data = request.data ts = TagSerializer(data=data) ts.is_valid(raise_exception=True) tag = ts.save() return Response({'res': {'id': tag.id}}, status=status.HTTP_201_CREATED) @method_decorator(parameter_required('tid')) @method_decorator(permission_required('problem.delete_tag', raise_exception=True)) def delete(self, request, tid): # delete a tag data = request.data tag = get_object_or_404(Tag, id=tid) tag.delete() return Response(status=status.HTTP_204_NO_CONTENT)
class ProblemDescriptionView(APIView): @method_decorator(parameter_required('pid')) @method_decorator(view_hidden_problem_permission_check()) def get(self, request, pid): problem = get_object_or_404(Problem, pid=pid) pds = ProblemDescriptionSerializer(problem) return Response({'res': pds.data}, status=status.HTTP_200_OK)
class JudgerProblemView(APIView): @method_decorator(parameter_required('pid')) @method_decorator(judger_account_required()) def get(self, request, pid): # Get the content of a problem problem = get_object_or_404(Problem, pid=pid) ps = ProblemSerializer(problem) return Response({'res': ps.data}, status=status.HTTP_200_OK)
class AccountUsernameAccessibilityView(APIView): @method_decorator(parameter_required('username')) def get(self, request, username): account_filter = {'username': username} queryset = Account.objects.filter(**account_filter) if queryset.count() == 0: return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_409_CONFLICT)
class JudgerTaskView(APIView): @method_decorator(judger_account_required()) @method_decorator(parameter_required('tid')) def get(self, request, tid): status_element = get_object_or_404(Status, id=tid) ss = StatusSerializer(status_element) ss_data = ss.data ss_data['problem'] = status_element.problem.pid return Response({'res': ss_data}, status=status.HTTP_200_OK) @method_decorator(judger_account_required()) @method_decorator(parameter_required('tid')) def patch(self, request, tid): data = request.data problem = get_object_or_404(Status, id=tid) ps = StatusEditSerializer(problem, data=data, partial=True) ps.is_valid(raise_exception=True) ps.save() return Response(status=status.HTTP_204_NO_CONTENT)
class ProblemView(APIView): @method_decorator(parameter_required('pid')) @method_decorator(view_hidden_problem_permission_check()) def get(self, request, pid): # Get the content of a problem problem = get_object_or_404(Problem, pid=pid) ps = ProblemSerializer(problem) return Response({'res': ps.data}, status=status.HTTP_200_OK) @method_decorator(permission_required('problem.add_problem', raise_exception=True)) def post(self, request): # Add a new problem data = request.data ps = ProblemSerializer(data=data) ps.is_valid(raise_exception=True) ps.save() return Response(status=status.HTTP_201_CREATED) @method_decorator(parameter_required('pid')) @method_decorator(permission_required('problem.change_problem', raise_exception=True)) def patch(self, request, pid): data = request.data problem = get_object_or_404(Problem, pid=pid) ps = ProblemSerializer(problem, data=data, partial=True) ps.is_valid(raise_exception=True) ps.save() return Response(status=status.HTTP_204_NO_CONTENT) @method_decorator(permission_required('problem.delete_problem')) def delete(self, request, pid): data = request.data problem = get_object_or_404(Problem, pid=pid) problem.delete() return Response(status=status.HTTP_204_NO_CONTENT)
class AccountExtraDataView(APIView): # Get User Extra Data @method_decorator(parameter_required('uid')) def get(self, request, uid): user = get_object_or_404(Account, id=uid) us = AccountExtraDataSerializer(user) return Response({'res': us.data}, status=status.HTTP_200_OK) @method_decorator(parameter_required('uid')) def patch(self, request, uid): if not request.user.has_perm('account.change_user'): if request.user.id != uid: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) data = request.data user = get_object_or_404(Account, id=uid) us = AccountExtraDataSerializer(user, data=data, partial=True) us.is_valid(raise_exception=True) us.save() return Response({'detail': 'Success'}, status=status.HTTP_204_NO_CONTENT)
class StatusView(APIView): @method_decorator(parameter_required('sid')) def get(self, request, sid): status_element = get_object_or_404(Status, id=sid) ss = StatusSerializer(status_element) ss_data = ss.data ss_data['problem'] = status_element.problem.pid return Response({'res': ss_data}, status=status.HTTP_200_OK) @method_decorator(syllable_required('problem', int)) @method_decorator(syllable_required('code', str)) @method_decorator(syllable_required('lang', int)) @method_decorator(login_required()) def post(self, request): # Create Status(Submit Problem) data = request.data if not 1 <= data['lang'] <= 10: return Response({ 'code': 4001, 'detail': 'Unknow language', }) builder = {} builder['owner'] = request.user.id builder['lang'] = data['lang'] builder['code'] = data['code'] if data.get('lang_info') is None: builder['lang_info'] = JLang.DEFAULT_LANG_INFO[data['lang']] else: builder['lang_info'] = data.get('lang_info') builder['problem'] = get_object_or_404(Problem, pid=data['problem']).id ss = StatusSerializer(data=builder) ss.is_valid(raise_exception=True) status_element = ss.save() request.user.submit_time += 1 request.user.save() def cannot_judge(reason, state=JState.JUDGE_STATUS_CFGE): status_element.state = state status_element.additional_info = reason status_element.save() try: res = requests.post('{base_url}/api/task'.format( base_url=settings.JUDGER_PORT['base_url']), json={ 'task_id': status_element.id, 'password': settings.JUDGER_PORT.get('password'), }) res_json = res.json() except: cannot_judge('Cannot connect the Judger Port.') else: code = res_json.get('code') if code is None: cannot_judge('Judger Port response format incorrect.', JState.JUDGE_STATUS_SE) elif code == 3003 or code == 3001: cannot_judge('Judger Port refused our task.') elif code == 2001: cannot_judge('No judger connected to Judger Port.', JState.JUDGE_STATUS_SE) return Response({'id': status_element.id}, status=status.HTTP_201_CREATED)
class AccountView(APIView): # Get User Infomation Except Introduction @method_decorator(parameter_required('uid')) def get(self, request, uid): user = get_object_or_404(Account, id=uid) us = AccountSerializer(user) return Response({'res': us.data}, status=status.HTTP_200_OK) # Create New User(register an account) @method_decorator(syllable_required('username', str)) @method_decorator(syllable_required('password', str)) @method_decorator(syllable_required('email', str)) @method_decorator(captcha_required()) def post(self, request): username = request.data.get('username') password = request.data.get('password') email = request.data.get('email') if len(password) < 6: return Response({'detail': 'Password too short'}, status=status.HTTP_400_BAD_REQUEST) if not tools.isEmail(email): return Response({'detail': 'Email is not correct'}, status=status.HTTP_400_BAD_REQUEST) try: user = Account.objects.create_user(username=username, password=password, email=email) except IntegrityError: # failed, probably because username already exits return Response({'detail': 'Failed to create user.'}, status=status.HTTP_409_CONFLICT) if user: # Success user.save() # Save user return Response( {'detail': 'Success', 'res': {'id': user.id}}, status=status.HTTP_201_CREATED, ) else: # failed, probably because username already exits return Response({'detail': 'Failed to create user.'}, status=status.HTTP_409_CONFLICT) @method_decorator(parameter_required('uid')) def patch(self, request, uid): data = request.data user = get_object_or_404(Account, id=uid) if not request.user.has_perm('account.change_user'): if request.user.id != user.id: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) request_is_active = data.get('is_active') request_is_staff = data.get('is_staff') request_is_superuser = data.get('is_superuser') if request_is_active != None and request_is_active != user.is_active: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) if request_is_staff != None and request_is_staff != user.is_staff: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) if request_is_superuser != None and request_is_superuser != user.is_superuser: return Response( {'detail': 'You have no permission to change this user'}, status=status.HTTP_403_FORBIDDEN ) us = AccountSerializer(user, data=data, partial=True) us.is_valid(raise_exception=True) us.save() return Response(status=status.HTTP_204_NO_CONTENT)