def post(self, request, *args, **kwargs): try: n = request.POST['answer'] contest = Contest.objects.get(pk=n) # 检查权限,如果不是比赛管理员,或者该比赛不是作业集(这是一个常规比赛),不允许复制 if not is_contest_manager(request.user, contest): raise PermissionError if contest.contest_type != 1: raise PermissionError # 复制的内容包括作业集的比赛的基本元信息、题目列表、命题人列表、管理员列表(不包括志愿者列表) # 需要教师手动导入新学期的学生名单,并修改作业集的起始时间 # 除非复制者已具备作业集题目的管理权限,否则复制成功后不会将题目的管理权限赋予复制者,复制者只能管理比赛内容,并管理具备权限的题目 problem_list = contest.contestproblem_set.all() contest_author = contest.authors.all() contest_manager = contest.managers.all() new_hw = Contest.objects.create(title='Contest') new_hw.title = 'Contest #%d' % contest.id new_hw.managers.add(request.user) saved_id = new_hw.id contest.id = saved_id contest.title = contest.title + ' - 复制' contest.save() for p in problem_list: contest.contestproblem_set.create(identifier=p.identifier, problem_id=p.problem_id, weight=p.weight) for c in contest_author: contest.authors.add(c.id) # 复制出题人 contest.managers.add(c.id) # 将出题人添加到该学期作业集的管理名单中 for m in contest_manager: if m.polygon_enabled: contest.managers.add(m.id) # 只把具有 Polygon 权限的教师添加到新学期作业集,排除上学期助教 contest.save() except: return redirect(reverse('polygon:contest_list')) return redirect(reverse('polygon:contest_list') + "?exact=%d" % saved_id)
def post(self, request, *args, **kwargs): try: n = request.POST['answer'] if '-' in n: contest_id, identifier = n.split('-') contest = Contest.objects.get(pk=contest_id) if not is_contest_manager(request.user, contest): raise PermissionError problem = contest.contestproblem_set.get( identifier=identifier).problem else: problem = Problem.objects.get(pk=n) if not is_problem_manager(request.user, problem): raise PermissionError if 'force' in request.GET: new_prob = None else: new_prob = ProblemCreate.get_unused_problem() if not new_prob: new_prob = Problem.objects.create() new_prob.managers.add(request.user) saved_id = new_prob.id problem.clone_parent = problem.id problem.id = saved_id problem.alias = 'p%d' % problem.id problem.visible = False problem.save() except: messages.error(request, "Problem does not exist or not available.") return redirect(reverse('polygon:problem_list_2')) return redirect( reverse('polygon:problem_list_2') + "?exact=%d" % saved_id)
def post(self, request, cid): text = request.POST.get("text", "") if not text or not request.user.is_authenticated: raise PermissionDenied if is_contest_manager(request.user, self.contest): ContestClarification.objects.create(contest=self.contest, important=True, author=request.user, answer=text) set_many_contest_notification([ (self.contest.pk, user_id) for user_id in self.contest.contestparticipant_set.values_list( "user_id", flat=True) ]) else: ContestClarification.objects.create(contest=self.contest, author=request.user, text=text) set_many_contest_notification([ (self.contest.pk, user_id) for user_id in self.contest.managers.values_list("id", flat=True) ]) return redirect( reverse("contest:question", kwargs={"cid": self.contest.pk}))
def get_context_data(self, **kwargs): data = super(ContestSubmissionView, self).get_context_data(**kwargs) data['submission'] = submission = get_contest_submission(self.kwargs.get('sid'), self.kwargs.get('cid')) submission.contest_problem = self.contest.get_contest_problem(submission.problem_id) if submission.author == self.request.user and self.contest.case_public and submission.is_judged and \ is_case_download_available(self.request.user, submission.problem_id, submission.contest_id): submission.allow_case_download = True authorized = False if self.request.user.is_authenticated: # Check author or managers (no share) if is_contest_manager(self.request.user, self.contest) or self.request.user == submission.author: authorized = True if not authorized and self.contest.allow_code_share > 0: # start to share if self.participate_contest_status > 0 and self.contest.allow_code_share >= 2: authorized = True if self.request.user.submission_set.filter(problem_id=submission.problem_id, status=SubmissionStatus.ACCEPTED).exists() and ( self.participate_contest_status > 0 or self.contest.allow_code_share >= 3): authorized = True if self.participate_contest_status > 0 and self.request.user.is_authenticated and self.request.user.has_coach_access(): authorized = True if authorized: permission = get_permission_for_submission(self.request.user, submission, special_permission=True) # it is already authorized thus requires special permission to open it data['submission_block'] = render_submission(submission, permission=permission, show_percent=data['show_percent']) if permission == 2 or (self.request.user == submission.author and submission.report_paid) or \ (self.participate_contest_status > 0 and self.request.user.has_coach_access()) or self.contest.case_public >= 2: data['report_block'] = render_submission_report(submission.pk) else: data['report_block'] = '' else: raise PermissionDenied return data
def dispatch(self, request, *args, **kwargs): self.contest = get_object_or_404(Contest, pk=kwargs.get('cid')) self.site_closed = is_site_closed(request) if self.site_closed: if self.contest.always_running: raise CloseSiteException if not self.contest.start_time - timedelta(minutes=30) <= timezone.now() \ <= self.contest.end_time + timedelta(minutes=10): raise CloseSiteException if self.contest.access_level >= 30: raise CloseSiteException self.user = request.user self.privileged = is_contest_manager(self.user, self.contest) self.volunteer = is_contest_volunteer(self.user, self.contest) self.registered = False if self.user.is_authenticated: try: participant = self.contest.contestparticipant_set.get(user=self.user) if self.contest.ip_sensitive: current_ip = get_ip(request) if participant.ip_address is None: participant.ip_address = current_ip participant.save(update_fields=['ip_address']) self.registered = current_ip == participant.ip_address else: self.registered = True except ContestParticipant.DoesNotExist: pass if not self.registered and (self.contest.access_level >= 30 or (self.contest.access_level >= 20 and self.contest.status > 0)): self.registered = True return super(BaseContestMixin, self).dispatch(request, *args, **kwargs)
def get_selected_from(self): if not self.user.is_authenticated: raise PermissionDenied if self.contest.contest_type != 1 and self.participate_contest_status == 0 and \ not is_contest_manager(self.user, self.contest): return self.contest.submission_set.filter(author=self.user).all() else: return self.user.submission_set.filter( problem_id__in=self.contest.contestproblem_set.values_list( "problem_id", flat=True)).all()
def dispatch(self, request, *args, **kwargs): self.contest = get_object_or_404(Contest, pk=kwargs.get('cid')) self.user = request.user self.privileged = is_contest_manager(self.user, self.contest) self.volunteer = is_volunteer(self.user) if self.user.is_authenticated and self.contest.contestparticipant_set.filter(user=self.user).exists(): self.registered = True elif self.contest.public: self.registered = True else: self.registered = False return super(BaseContestMixin, self).dispatch(request, *args, **kwargs)
def post(self, request, cid, pk): if is_contest_manager(request.user, self.contest): clarification = get_object_or_404(ContestClarification, contest_id=cid, pk=pk) clarification.answer = request.POST["text"] clarification.save(update_fields=["answer"]) notify.send(sender=request.user, recipient=[clarification.author], verb="answered your question in", level="warning", target=self.contest, description=clarification.answer) return redirect(reverse("contest:dashboard", kwargs={"cid": self.contest.pk})) raise PermissionDenied
def get_queryset(self): contest_id = self.request.data.get("contest") if contest_id: contest = Contest.objects.get(contest_id) if is_contest_manager(self.request.user, contest): submission_set = contest.submission_set.all() else: raise PermissionDenied else: submission_set = Submission.objects.select_related( "problem").filter(problem__visible=True).all() return submission_set.only("author_id", "contest_id", "problem_id", "create_time", "status")
def dispatch(self, request, *args, **kwargs): self.contest = get_object_or_404(Contest, pk=kwargs.get('cid')) self.site_closed = is_site_closed(request) if self.site_closed: if self.contest.contest_type == 1: raise CloseSiteException if not self.contest.start_time - timedelta(minutes=30) <= timezone.now() \ <= self.contest.end_time + timedelta(minutes=10): raise CloseSiteException if self.contest.access_level >= 30: raise CloseSiteException self.user = request.user self.privileged = is_contest_manager(self.user, self.contest) self.volunteer = is_contest_volunteer(self.user, self.contest) self.registered, self.vp_available = False, False self.virtual_progress, self.participant = None, None # virtual participation undergoing self.participate_start_time = self.contest.start_time # the start time for the participant self.participate_end_time = self.contest.end_time # the end time for the participant self.participate_contest_status = self.contest.status # the contest status for the participant if self.user.is_authenticated: try: self.participant = self.contest.contestparticipant_set.get( user=self.user) self.participate_start_time = self.participant.start_time( self.contest) self.participate_end_time = self.participant.end_time( self.contest) self.participate_contest_status = self.participant.status( self.contest) if self.participant.join_time is not None and self.participate_contest_status == 0: self.virtual_progress = datetime.now( ) - self.participate_start_time if self.contest.ip_sensitive: current_ip = get_ip(request) if self.participant.ip_address is None: self.participant.ip_address = current_ip self.participant.save(update_fields=['ip_address']) self.registered = current_ip == self.participant.ip_address else: self.registered = True except ContestParticipant.DoesNotExist: pass if not self.registered and (self.contest.access_level >= 30 or (self.contest.access_level >= 20 and self.contest.status > 0)): self.registered = True if self.participant is None and self.user.is_authenticated and self.contest.access_level >= 15 and \ self.contest.contest_type == 0 and self.contest.status > 0: self.vp_available = True return super(BaseContestMixin, self).dispatch(request, *args, **kwargs)
def post(self, request, cid, pk): if is_contest_manager(request.user, self.contest): clarification = get_object_or_404(ContestClarification, contest_id=cid, pk=pk) builtin = request.POST.get("builtin", "custom") clarification.answer = request.POST.get("text", "") dfind = dict(BUILTIN_CHOICES) if builtin in dfind and builtin != "custom": clarification.answer = dfind[builtin] clarification.save(update_fields=["answer"]) set_contest_notification(self.contest.pk, clarification.author_id) return redirect( reverse("contest:question", kwargs={"cid": self.contest.pk})) raise PermissionDenied
def send_notification(request, **kwargs): def get_parent_user(comment): return XtdComment.objects.get(pk=comment['parent_id']).user comment = kwargs['comment'] if comment['content_type'].name in ('blog', 'problem', 'contest'): recipient = None target = None verb = 'replied on' if comment['content_type'].name == 'blog': target = comment['content_object'] recipient = target.author if comment['parent_id']: recipient = get_parent_user(comment) elif comment['content_type'].name == 'contest': target = contest = comment['content_object'] if comment['parent_id']: recipient = get_parent_user(comment) verb = 'replied in' elif is_contest_manager(comment.user, contest): recipient = list( map(lambda x: x.user, contest.contestparticipant_set.all())) verb = 'posted a notification in' else: recipient = contest.managers.all() verb = 'asked a question in' elif comment['content_type'].name == 'problem': if comment['parent_id']: target = comment['content_object'] recipient = get_parent_user(comment) else: return level = 'info' if comment['content_type'].name == 'contest': level = 'warning' if recipient and recipient != comment['user']: notify.send(sender=comment['user'], recipient=recipient, verb=verb, level=level, target=target)
def post(self, request, cid): if self.contest.status != 0: raise PermissionDenied text = request.POST.get("text", "") if not text or not request.user.is_authenticated: raise PermissionDenied if is_contest_manager(request.user, self.contest): ContestClarification.objects.create(contest=self.contest, important=True, author=request.user, answer=text) notify.send( sender=request.user, recipient=list( map( lambda x: x.user, self.contest.contestparticipant_set.select_related( "user").all())), verb="posted a notification in", level="warning", target=self.contest, description=text) else: ContestClarification.objects.create(contest=self.contest, author=request.user, text=text) notify.send(sender=request.user, recipient=self.contest.managers.all(), verb="asked a question in", level="warning", target=self.contest, description=text) emails = self.contest.managers.all().values_list("email", flat=True) msg_pre = [ "Contest: " + self.contest.title, "Who: " + request.user.username, "Question: " + text ] Thread(target=self.send_notification_email, args=('\n'.join(msg_pre), list(emails))).start() return redirect( reverse("contest:dashboard", kwargs={"cid": self.contest.pk}))
def create_submission(problem, author: User, code, lang, contest=None, status=SubmissionStatus.WAITING, ip='', visible=True): if not 6 <= len(code) <= 65536: raise ValueError("代码不得小于 6 字节,不得超过 65536 字节。") if lang == "java": matching_regex = r"public\s+(final\s+)?class\s+Main" if re.search(matching_regex, code) is None: raise ValueError("Java 语言应匹配正则:" + matching_regex) if author.submission_set.exists() and ( datetime.now() - author.submission_set.first().create_time ).total_seconds() < settings.SUBMISSION_INTERVAL_LIMIT: raise ValueError("5 秒内只能提交一次。") if contest: if contest.submission_set.filter(author=author, problem_id=problem, code__exact=code, lang=lang).exists(): raise ValueError("你之前交过完全一样的代码。") if isinstance(problem, (int, str)): problem = Problem.objects.get(pk=problem) if contest is not None: if is_contest_manager(author, contest): visible = False elif is_problem_manager(author, problem): visible = False return Submission.objects.create(lang=lang, code=code, author=author, problem=problem, contest=contest, status=status, ip=ip, visible=visible)
def post(self, request, cid): if self.contest.status != 0: raise PermissionDenied text = request.POST["text"] if not text or not request.user.is_authenticated: raise PermissionDenied if is_contest_manager(request.user, self.contest): ContestClarification.objects.create(contest=self.contest, important=True, author=request.user, answer=text) notify.send(sender=request.user, recipient=list(map(lambda x: x.user, self.contest.contestparticipant_set.select_related("user").all())), verb="posted a notification in", level="warning", target=self.contest, description=text) else: ContestClarification.objects.create(contest=self.contest, author=request.user, text=text) notify.send(sender=request.user, recipient=self.contest.managers.all(), verb="asked a question in", level="warning", target=self.contest, description=text) return redirect(reverse("contest:dashboard", kwargs={"cid": self.contest.pk}))
def dispatch(self, request, *args, **kwargs): blogs = Blog.objects.with_likes().with_dislikes().with_likes_flag(request.user) self.blog = get_object_or_404(blogs, pk=kwargs.get('pk')) self.user = request.user if self.blog.is_reward and self.blog.contest: self.site_closed = is_site_closed(request) self.contest = self.blog.contest if self.site_closed: if self.contest.contest_type == 1: raise CloseSiteException if not self.contest.start_time - timedelta(minutes=30) <= timezone.now() \ <= self.contest.end_time + timedelta(minutes=10): raise CloseSiteException if self.contest.access_level >= 30: raise CloseSiteException self.privileged = is_contest_manager(self.user, self.contest) self.volunteer = is_contest_volunteer(self.user, self.contest) self.registered = False self.virtual_progress, self.participant = None, None self.participate_start_time = self.contest.start_time self.participate_end_time = self.contest.end_time self.participate_contest_status = self.contest.status if self.user.is_authenticated: try: self.participant = self.contest.contestparticipant_set.get(user=self.user) self.participate_start_time = self.participant.start_time(self.contest) self.participate_end_time = self.participant.end_time(self.contest) self.participate_contest_status = self.participant.status(self.contest) if self.participant is not None: self.registered = True except ContestParticipant.DoesNotExist: pass if not self.registered and (self.contest.access_level >= 30 or (self.contest.access_level >= 20 and self.contest.status > 0)): self.registered = True return super(BlogMixin, self).dispatch(request, *args, **kwargs)
def test_func(self): if is_problem_manager(self.request.user, self.submission.problem) or \ (self.submission.contest and is_contest_manager(self.request.user, self.submission.contest)): return super(RejudgeSubmission, self).test_func() return False
def test_func(self): if not is_contest_manager(self.request.user, self.contest): return False return super(PolygonContestMixin, self).test_func()