def rejudge(self, request, pk=None, *args, **kwargs): queryset = self.get_queryset() submission = get_object_or_404(queryset, pk=pk) # 如果已经保存了 last rejudge time 的话,与 last rejudge time 比较 # 如果没有保存 last rejudge time 的话, 和 create time 比较 if (submission.last_rejudge_time is not None and timezone.now() < submission.last_rejudge_time + timedelta(minutes=1)) or ( submission.last_rejudge_time is None and timezone.now() < submission.create_time + timedelta(minutes=1)): return Response(msg(err=_('Can\'t Rejudge Within 1 minutes.'))) submission.last_rejudge_time = timezone.now() submission.verdict = Verdict.PENDING submission.additional_info = None submission.save() run_submission_task.apply_async(args=[ submission.id, submission.problem.id, submission.problem.manifest, submission.code, submission.lang, submission.problem.time_limit, submission.problem.memory_limit ], queue='judge') Activity(user=request.user, category=Activity.SUBMISSION, info=f'用户请求Rejudge,提交编号是{submission.id}').save() return Response(msg(SubmissionShortSerializer(submission).data))
def register(self, request): if request.user.is_authenticated: return Response( msg(err=_('Please sign out first before try to register.'))) serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.save() return Response(msg(UserInfoSerializer(user).data))
def get(self, request, *args, **kwargs): form = RequestFileForm(data=request.GET) if not form.is_valid(): return Response(msg(_('Params validate error'))) path = os.path.join(PROBLEM_PDF_DIR, str(form.cleaned_data['title'])) if os.path.exists(path): with open(path, 'rb') as f: return HttpResponse(f.read(), content_type='application/pdf') else: return Response(msg(err=_('PDF not exist.')))
def delete(self, request, *args, **kwargs): form = ImageNameForms(request.GET) if form.is_valid(): title = form.cleaned_data['title'] path = os.path.join(PROBLEM_IMAGE_DIR, str(title)) if os.path.exists(path): os.remove(path) return Response(msg('Ok')) return Response(msg(err=_('file not exist.'))) return Response(msg(err=form.errors))
def queue(self, request, *args, **kwargs): try: inspect_task = inspect(app=celery_app) replies = inspect_task.run('active_queues') res = [{ 'name': key, 'queue': [item['name'] for item in replies[key]] } for key in replies.keys()] return Response(msg(data=res)) except Exception as e: return Response(msg(err=str(e)))
def language(self, request, *args, **kwargs): if request.method == 'POST': serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) res = Response(msg(_('Success.'))) res.set_cookie(key=LANGUAGE_COOKIE_NAME, value=serializer.validated_data['language'], samesite='lax') return res else: return Response(msg(LANGUAGES))
def student(self, request, *args, **kwargs): if request.method == 'POST': serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save(request.user) return Response(msg(serializer.data)) else: try: serializer = self.get_serializer(request.user.student) except StudentInfo.DoesNotExist: return Response(msg({})) return Response(msg(serializer.data))
def login(self, request): if request.user.is_authenticated: return Response( msg(err=_('Please sign out first before try to login.'))) serializer = self.get_serializer(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) try: return Response( msg(UserInfoSerializer(serializer.login(request)).data)) except Exception as e: return Response(msg(err=str(e)))
def upload_test_cases(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) tmp_file = f'{uuid4()}.zip' os.makedirs(TMP_DIR, exist_ok=True) with open(os.path.join(TMP_DIR, tmp_file), 'wb') as destination: for chunk in serializer.validated_data['file'].chunks(1024): destination.write(chunk) try: manifest = TestCasesProcessor.handle_upload_test_cases(tmp_file, TMP_DIR) os.remove(os.path.join(TMP_DIR, tmp_file)) return Response(msg(manifest)) except TestCasesError as e: return Response(msg(err=str(e)))
def personal(self, request, pk=None): queryset = self.get_queryset() submission = get_object_or_404(queryset, pk=pk) if submission.user == request.user or request.user.is_staff or submission.is_public: serializer = self.get_serializer(submission) return Response(msg(serializer.data)) raise PermissionDenied
def put(self, request, *args, **kwargs): serializer = ProblemImageSerializer(data=request.data) serializer.is_valid(raise_exception=True) # 将文件保存到PROBLEM_IMAGE_DIR目录下 suffix = str(serializer.validated_data['file']).split('.')[-1] filename = str(uuid4()) + '.' + suffix tmp_path = os.path.join(TMP_DIR, filename) if not os.path.exists(TMP_DIR) or not os.path.isdir(TMP_DIR): os.makedirs(TMP_DIR) final_path = os.path.join(PROBLEM_IMAGE_DIR, filename) if not os.path.exists(PROBLEM_IMAGE_DIR) or not os.path.isdir(PROBLEM_IMAGE_DIR): os.makedirs(PROBLEM_IMAGE_DIR) with open(tmp_path, 'wb') as destination: for chunk in serializer.validated_data['file'].chunks(1024): destination.write(chunk) # 如果上传的图片大小太大的话,就将图片等比例缩放到最大边为self.MAX_SIZE大小 img: Image.Image = Image.open(tmp_path) (w, h) = img.size if w > self.MAX_SIZE or h > self.MAX_SIZE: nw = nh = self.MAX_SIZE if w > h: nh = nw * h // w else: nw = nh * w // h img2 = img.resize((nw, nh)) img.close() img2.save(final_path) img2.close() else: img.save(final_path) img.close() return Response(msg(f'/api/problem/image?title={filename}'))
def get_paginated_response(self, data): return Response( msg( OrderedDict([('count', self.page.paginator.count), ('next', self.get_next_link()), ('previous', self.get_previous_link()), ('results', data)])))
def activities(self, request: Request, pk=None, *args, **kwargs): if request.user.id == pk or request.user.is_staff: user = get_object_or_404(User.objects.all(), pk=pk) serializer = self.get_serializer(user.activities.all()[:10], many=True) return Response(msg(serializer.data)) raise PermissionDenied
def reset_password(self, request, pk=None, *args, **kwargs): queryset = User.objects.all() user = get_object_or_404(queryset, pk=pk) new_password = random_str(8) user.set_password(new_password) user.save() return Response(msg({'new_password': new_password}))
def followed(self, request, pk=None, *args, **kwargs): return Response( msg({ 'followed': int(pk) in list(map(lambda user: user.id, request.user.following.all())) }))
def info(self, request, *args, **kwargs): user_cnt = User.objects.all().count() problem_cnt = Problem.objects.all().count() submission_cnt = Submission.objects.all().count() return Response( msg({ 'user_cnt': user_cnt, 'problem_cnt': problem_cnt, 'submission_cnt': submission_cnt }))
def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(msg(serializer.data))
def password(self, request: Request): serializer = ChangePasswordSerializer(data=request.data, context={ 'user': request.user, 'request': request }) serializer.is_valid(raise_exception=True) serializer.save() auth.logout(request) return Response(msg(_('Success')))
def create(self, request: Request): last_submit_time = request.user.last_submit_time if last_submit_time is not None and timezone.now( ) < last_submit_time + timedelta(seconds=10): return Response( msg(err=_('Can\'t submit twice within 10 seconds.'))) serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) submission = serializer.save(user=request.user) run_submission_task.apply_async(args=[ submission.id, submission.problem.id, submission.problem.manifest, submission.code, submission.lang, submission.problem.time_limit, submission.problem.memory_limit ], queue='judge') Activity(user=request.user, category=Activity.SUBMISSION, info=f'用户提交了题目{submission.problem.id},提交编号是{submission.id}' ).save() return Response(msg(SubmissionShortSerializer(submission).data))
def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) queryset = sorted(queryset, key=lambda x: (-x.total_passed, x.total_submitted, x.id)) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(msg(serializer.data))
def post(self, request, *args, **kwargs): serializer = ProblemPDFSerializer(data=request.data) serializer.is_valid(True) filename = str(uuid4()) + '.pdf' final_path = os.path.join(PROBLEM_PDF_DIR, filename) if not os.path.exists(PROBLEM_PDF_DIR) or not os.path.isdir(PROBLEM_PDF_DIR): os.makedirs(PROBLEM_PDF_DIR) with open(final_path, 'wb') as destination: for chunk in serializer.validated_data['file'].chunks(1024): destination.write(chunk) return Response(msg({'title': filename}))
def check_email(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) verify_code = serializer.save() if OJ_DEBUG: print("verify code:", verify_code) send_activated_email.apply_async( args=[serializer.validated_data['email'], verify_code], queue='result') return Response( msg(_('please check your new email box to get verify code.')))
def following(self, request, *args, **kwargs): if request.method == 'GET': queryset = self.filter_queryset(request.user.following.all()) queryset = sorted(queryset, key=lambda x: (-x.total_passed, x.total_submitted, x.id)) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return Response(msg(serializer.data)) else: serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) if serializer.validated_data['follow']: request.user.following.add( serializer.validated_data['user_id']) else: request.user.following.remove( serializer.validated_data['user_id']) return Response(msg('Success.'))
def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) if getattr(instance, '_prefetched_objects_cache', None): instance._prefetched_objects_cache = {} return Response(msg(serializer.data))
def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() # 权限检查,管理员或者作者用户 if not request.user.is_staff and request.user.id != instance.user.id: raise PermissionDenied serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) if getattr(instance, '_prefetched_objects_cache', None): # If 'prefetch_related' has been applied to a queryset, we need to # forcibly invalidate the prefetch cache on the instance. instance._prefetched_objects_cache = {} return Response(msg(_('Success')))
def retrieve(self, request, pk=None): queryset = User.objects.all() user = get_object_or_404(queryset, pk=pk) return Response(msg(self.get_serializer(user).data))
def info(self, request): if request.user.is_authenticated: return Response(msg(self.get_serializer(request.user).data)) else: return Response(msg(err=_('Not login.')))
def email(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data, context={'user': request.user}) serializer.is_valid(raise_exception=True) serializer.save() return Response(msg(_('Change email address success.')))
def logout(self, request): auth.logout(request) return Response(msg(_('Successful logout.')))
def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return Response(msg(serializer.data))