Example #1
0
    def _render_disqualification_reason(self, request, submission):
        prev = super(SimilarityDisqualificationMixin, self) \
            ._render_disqualification_reason(request, submission)

        if is_contest_admin(request):
            q_expression = Q(submissions__submission=submission)
        else:
            # Do not split this filter as it spans many-to-many relationship
            q_expression = Q(submissions__submission=submission,
                             submissions__guilty=True)
        similarities = SubmissionsSimilarityGroup.objects \
            .filter(q_expression) \
            .select_related('submissions')
        if not similarities:
            return prev

        submission_contexts = {}
        for group in similarities:
            for entry in group.submissions.all():
                submission_contexts[entry.submission] = \
                        submission_template_context(request, entry.submission)

        template = ('similarsubmits/programming_similar_submissions_admin.html'
                    if is_contest_admin(request) else
                    'similarsubmits/programming_similar_submissions.html')

        context = RequestContext(request, {
            'similarities': similarities,
            'main_submission_id': submission.id,
            'submission_contexts': submission_contexts,
        })

        return prev + render_to_string(template, context_instance=context)
Example #2
0
def can_see_teams_list(request):
    if not Team.objects.filter(contest=request.contest).exists():
        return False
    try:
        cfg = TeamsConfig.objects.get(contest=request.contest)
    except TeamsConfig.DoesNotExist:
        return is_contest_admin(request)
    return is_contest_admin(request) | \
            (cfg.teams_list_visible == 'PUBLIC') | \
            ((cfg.teams_list_visible == 'YES') & not_anonymous(request))
Example #3
0
def livedata_events_view(request, round_id):
    user_is_participant = Q(
        submission__user__participant__contest_id=request.contest.id, submission__user__participant__status="ACTIVE"
    )
    submission_ignored = Q(submission__kind="IGNORED")

    reports = (
        SubmissionReport.objects.filter(user_is_participant)
        .exclude(submission_ignored)
        .select_related("submission")
        .prefetch_related("scorereport_set")
    )

    if (is_contest_admin(request) or is_contest_observer(request)) and "from" in request.GET:
        # Only admin/observer is allowed to specify 'from' parameter.
        start_time = datetime.datetime.utcfromtimestamp(int(request.GET["from"])).replace(tzinfo=utc)
        reports = reports.filter(creation_date__gte=start_time)

    round = get_object_or_404(request.contest.round_set.all(), pk=round_id)
    contest_start = round.start_date
    reports = reports.filter(submission__problem_instance__round=round)
    if is_contest_admin(request):
        freeze_time = None
    else:
        freeze_time = request.contest.controller.get_round_freeze_time(round)

    return [
        {
            "submissionId": "START",
            "reportId": "START",
            "teamId": "START",
            "taskId": "START",
            "submissionTimestamp": int(dateformat.format(request.timestamp, "U")),
            "judgingTimestamp": int(dateformat.format(contest_start, "U")),
            "result": "CTRL",
        }
    ] + [
        {
            "submissionId": report.submission_id,
            "reportId": report.pk,
            "teamId": report.submission.user_id,
            "taskId": report.submission.problem_instance_id,
            "submissionTimestamp": int(dateformat.format(report.submission.date, "U")),
            "judgingTimestamp": int(dateformat.format(report.creation_date, "U")),
            "result": report.score_report.status
            if freeze_time is None or report.submission.date < freeze_time
            else RESULT_FOR_FROZEN_SUBMISSION,
        }
        for report in reports.order_by("creation_date")
        if report.score_report is not None
    ]
Example #4
0
def livedata_events_view(request, round_id):
    user_is_participant = \
        Q(submission__user__participant__contest_id=request.contest.id,
          submission__user__participant__status='ACTIVE')
    submission_ignored = Q(submission__kind='IGNORED')

    reports = SubmissionReport.objects \
        .filter(user_is_participant) \
        .exclude(submission_ignored) \
        .select_related('submission') \
        .prefetch_related('scorereport_set')

    if (is_contest_admin(request) or is_contest_observer(request)) and \
            'from' in request.GET:
        # Only admin/observer is allowed to specify 'from' parameter.
        start_time = datetime.datetime.utcfromtimestamp(
                int(request.GET['from'])).replace(tzinfo=utc)
        reports = reports.filter(creation_date__gte=start_time)

    round = get_object_or_404(request.contest.round_set.all(), pk=round_id)
    contest_start = round.start_date
    reports = reports.filter(submission__problem_instance__round=round)
    if is_contest_admin(request):
        freeze_time = None
    else:
        freeze_time = request.contest.controller.get_round_freeze_time(round)

    return [{
        'submissionId': 'START',
        'reportId': 'START',
        'teamId': 'START',
        'taskId': 'START',
        'submissionTimestamp': int(dateformat.format(request.timestamp, 'U')),
        'judgingTimestamp': int(dateformat.format(contest_start, 'U')),
        'result': 'CTRL',
    }] + [{
        'submissionId': report.submission_id,
        'reportId': report.pk,
        'teamId': report.submission.user_id,
        'taskId': report.submission.problem_instance_id,
        'submissionTimestamp':
            int(dateformat.format(report.submission.date, 'U')),
        'judgingTimestamp': int(dateformat.format(report.creation_date, 'U')),
        'result':
            report.score_report.status
            if freeze_time is None or report.submission.date < freeze_time
            else RESULT_FOR_FROZEN_SUBMISSION,
    } for report in reports.order_by('creation_date')
        if report.score_report is not None]
Example #5
0
def contest_files_view(request):
    contest_files = ContestAttachment.objects.filter(contest=request.contest) \
        .filter(Q(round__isnull=True) | Q(round__in=visible_rounds(request))) \
        .select_related('round')
    if not is_contest_admin(request):
        contest_files = contest_files.filter(Q(pub_date__isnull=True)
                | Q(pub_date__lte=request.timestamp))

    round_file_exists = contest_files.filter(round__isnull=False).exists()
    problem_instances = visible_problem_instances(request)
    problem_ids = [pi.problem_id for pi in problem_instances]
    problem_files = ProblemAttachment.objects \
            .filter(problem_id__in=problem_ids) \
            .select_related('problem')
    add_category_field = round_file_exists or problem_files.exists()
    rows = [{
        'category': cf.round if cf.round else '',
        'name': cf.download_name,
        'description': cf.description,
        'link': reverse('contest_attachment',
            kwargs={'contest_id': request.contest.id, 'attachment_id': cf.id}),
        'pub_date': cf.pub_date
        } for cf in contest_files]
    rows += [{
        'category': pf.problem,
        'name': pf.download_name,
        'description': pf.description,
        'link': reverse('problem_attachment',
            kwargs={'contest_id': request.contest.id, 'attachment_id': pf.id}),
        'pub_date': None
        } for pf in problem_files]
    rows.sort(key=itemgetter('name'))
    return TemplateResponse(request, 'contests/files.html', {'files': rows,
        'files_on_page': getattr(settings, 'FILES_ON_PAGE', 100),
        'add_category_field': add_category_field, 'show_pub_dates': True})
Example #6
0
def thread_view(request, contest_id, category_id, thread_id):
    (forum, category, thread, lock) = get_forum_objects(request,
                                                  category_id, thread_id,
                                                  lock_required=True)
    msgs = get_msgs(forum, request)
    if (request.user.is_authenticated() and
       not request.contest.forum.is_locked(request.timestamp)) or \
       is_contest_admin(request):
        if request.method == "POST":
            form = PostForm(request, request.POST)
            if form.is_valid():
                instance = form.save(commit=False)
                instance.author = request.user
                instance.thread = thread
                instance.add_date = request.timestamp
                instance.save()
                return redirect('forum_thread', contest_id=contest_id,
                                category_id=category.id,
                                thread_id=thread.id)
        else:
            form = PostForm(request)

        return TemplateResponse(request, 'forum/thread.html',
            {'forum': forum, 'category': category, 'thread': thread,
             'form': form, 'msgs': msgs, 'is_locked': lock})
    else:
        return TemplateResponse(request, 'forum/thread.html',
            {'forum': forum, 'category': category, 'thread': thread,
             'msgs': msgs, 'is_locked': lock})
Example #7
0
def delete_post_view(request, category_id, thread_id, post_id):
    (category, thread, post) = get_forum_ctp(category_id, thread_id, post_id)
    is_admin = is_contest_admin(request)
    if not (  # we assert following:
        is_admin
        or (
            post.author == request.user
            # you can remove a post only if there is no post added after yours
            and not thread.post_set.filter(add_date__gt=post.add_date).exists()
            and post.can_be_removed()
        )
    ):
        raise PermissionDenied
    else:
        choice = confirmation_view(request, 'forum/confirm_delete.html',
                {'elem': post})
        if not isinstance(choice, bool):
            return choice
        if choice:
            post.delete()

            if not thread.post_set.exists():
                thread.delete()
                return redirect('forum_category',
                                contest_id=request.contest.id,
                                category_id=category.id)

    return redirect('forum_thread', contest_id=request.contest.id,
                    category_id=category.id, thread_id=thread.id)
Example #8
0
def messages_template_context(request, messages):
    replied_ids = frozenset(m.top_reference_id for m in messages)
    new_ids = new_messages(request, messages).values_list("id", flat=True)

    if is_contest_admin(request):
        unanswered = unanswered_questions(messages)
    else:
        unanswered = []

    to_display = [
        {
            "message": m,
            "link_message": m.top_reference if m.top_reference in messages else m,
            "needs_reply": m in unanswered,
            "read": m.id not in new_ids,
        }
        for m in messages
        if m.id not in replied_ids
    ]

    def key(entry):
        return entry["needs_reply"], entry["message"].date

    to_display.sort(key=key, reverse=True)
    return to_display
Example #9
0
 def render_submission_footer(self, request, submission):
     super_footer = super(ProgrammingContestController, self). \
             render_submission_footer(request, submission)
     queryset = Submission.objects \
             .filter(problem_instance__contest=request.contest) \
             .filter(user=submission.user) \
             .filter(problem_instance=submission.problem_instance) \
             .exclude(pk=submission.pk) \
             .order_by('-date') \
             .select_related()
     if not is_contest_admin(request):
         cc = request.contest.controller
         queryset = cc.filter_my_visible_submissions(request, queryset)
     show_scores = bool(queryset.filter(score__isnull=False))
     if not queryset.exists():
         return super_footer
     return super_footer + render_to_string(
             'programs/other_submissions.html',
             context_instance=RequestContext(request, {
                     'submissions': [submission_template_context(request, s)
                              for s in queryset],
                     'show_scores': show_scores,
                     'main_submission_id': submission.id,
                     'submissions_on_page': getattr(settings,
                         'SUBMISSIONS_ON_PAGE', 15)}))
Example #10
0
 def process_view(self, request, view_func, view_args, view_kwargs):
     if not hasattr(request, 'user'):
         raise ImproperlyConfigured(
             "The OiForceDnsIpAuthMiddleware middleware requires the"
             " 'django.contrib.auth.middleware.AuthenticationMiddleware'"
             " earlier in MIDDLEWARE_CLASSES.")
     if not request.user.is_anonymous() and \
             not hasattr(request.user, 'backend'):
         raise ImproperlyConfigured(
             "The OiForceDnsIpAuthMiddleware middleware requires the"
             " 'oioioi.base.middleware.AnnotateUserBackendMiddleware'"
             " earlier in MIDDLEWARE_CLASSES.")
     if not hasattr(request, 'contest'):
         raise ImproperlyConfigured(
             "The OiForceDnsIpAuthMiddleware middleware requires the"
             " 'oioioi.contests.middleware.CurrentContestMiddleware'"
             " earlier in MIDDLEWARE_CLASSES.")
     if not request.contest:
         return
     if not isinstance(request.contest.controller,
             OIOnsiteContestController):
         return
     if not request.user.is_authenticated():
         return
     if is_contest_admin(request):
         return
     if not Participant.objects.filter(user=request.user,
             contest=request.contest, status='ACTIVE'):
         return
     backend_path = request.user.backend
     if backend_path != 'oioioi.ipdnsauth.backends.IpDnsBackend':
         auth.logout(request)
         return TemplateResponse(request, 'oi/access_blocked.html',
             {'auth_backend': backend_path})
Example #11
0
def add_contest_message_view(request):
    is_admin = is_contest_admin(request)
    if request.method == 'POST':
        form = AddContestMessageForm(request, request.POST)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.author = request.user
            if is_admin:
                instance.kind = 'PUBLIC'
            else:
                instance.kind = 'QUESTION'
                instance.pub_date = None
            instance.date = request.timestamp
            instance.save()
            if instance.kind == 'QUESTION':
                new_question_signal.send(sender=Message, request=request,
                                         instance=instance)
            log_addition(request, instance)
            return redirect('contest_messages', contest_id=request.contest.id)

    else:
        initial = {}
        for field in ('category', 'topic', 'content'):
            if field in request.GET:
                initial[field] = request.GET[field]
        form = AddContestMessageForm(request, initial=initial)

    if is_admin:
        title = _("Add news")
    else:
        title = _("Ask question")

    return TemplateResponse(request, 'questions/add.html',
            {'form': form, 'title': title, 'is_news': is_admin})
Example #12
0
def thread_view(request, category_id, thread_id):
    category, thread = get_forum_ct(category_id, thread_id)
    forum, lock = request.contest.forum, forum_is_locked(request)
    msgs = get_msgs(request)
    post_set = thread.post_set.select_related('author').all()
    if (request.user.is_authenticated() and not lock) or \
       is_contest_admin(request):
        if request.method == "POST":
            form = PostForm(request, request.POST)
            if form.is_valid():
                instance = form.save(commit=False)
                instance.author = request.user
                instance.thread = thread
                instance.add_date = request.timestamp
                instance.save()
                return redirect('forum_thread', contest_id=request.contest.id,
                                category_id=category.id,
                                thread_id=thread.id)
        else:
            form = PostForm(request)

        return TemplateResponse(request, 'forum/thread.html',
            {'forum': forum, 'category': category, 'thread': thread,
             'form': form, 'msgs': msgs, 'is_locked': lock,
             'post_set': post_set})
    else:
        return TemplateResponse(request, 'forum/thread.html',
            {'forum': forum, 'category': category, 'thread': thread,
             'msgs': msgs, 'is_locked': lock, 'post_set': post_set})
Example #13
0
def navbar_messages_generator(request):
    if request.contest is None:
        return {}

    is_admin = is_contest_admin(request)
    messages = visible_messages(request)
    visible_ids = messages.values_list('id', flat=True)
    if is_admin:
        messages = unanswered_questions(messages)
    else:
        messages = new_messages(request, messages)
    count = messages.count()
    if count:
        text = ungettext('%(count)d NEW MESSAGE', '%(count)d NEW MESSAGES',
                         count) % {'count': count}

        if count == 1:
            m = messages.get()
            link = reverse('message', kwargs={
                'contest_id': request.contest.id,
                'message_id': m.top_reference_id
                if m.top_reference_id in visible_ids else m.id
            })
        else:
            link = reverse('contest_messages', kwargs={'contest_id':
                                                           request.contest.id})
        return {'link': link, 'text': text, 'id': 'contest_new_messages'}
    else:
        return {'link': None, 'text': None, 'id': 'contest_new_messages'}
Example #14
0
def add_contest_message_view(request, contest_id):
    is_admin = is_contest_admin(request)
    if request.method == "POST":
        form = AddContestMessageForm(request, request.POST)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.author = request.user
            if is_admin:
                instance.kind = "PUBLIC"
            else:
                instance.kind = "QUESTION"
            instance.date = request.timestamp
            instance.save()
            if instance.kind == "QUESTION":
                new_question_signal.send(sender=Message, request=request, instance=instance)
            log_addition(request, instance)
            return redirect("contest_messages", contest_id=contest_id)

    else:
        form = AddContestMessageForm(request)

    if is_admin:
        title = _("Add announcement")
    else:
        title = _("Ask question")

    return TemplateResponse(request, "questions/add.html", {"form": form, "title": title, "is_announcement": is_admin})
Example #15
0
def delete_post_view(request, category_id, thread_id, post_id):
    (category, thread, post) = get_forum_ctp(category_id, thread_id, post_id)
    is_admin = is_contest_admin(request)
    if not is_admin and \
       (post.author != request.user or
       (post.author == request.user and
       (thread.post_set.filter(add_date__gt=post.add_date).exists() or
           not post.can_be_removed()))):
        # author: if there are other posts added later or timedelta is gt 15min
        # if user is not the author of the post or forum admin
        raise PermissionDenied
    else:
        choice = confirmation_view(request, 'forum/confirm_delete.html',
                {'elem': post})
        if not isinstance(choice, bool):
            return choice
        if choice:
            post.delete()

            if not thread.post_set.exists():
                thread.delete()
                return redirect('forum_category',
                                contest_id=request.contest.id,
                                category_id=category.id)
    return redirect('forum_thread', contest_id=request.contest.id,
                    category_id=category.id, thread_id=thread.id)
Example #16
0
 def has_change_permission(self, request, obj=None):
     if obj:
         return False
     # is_contest_observer() is required in here, because otherwise
     # observers get a 403 response. Any actions that modify submissions
     # will be blocked in get_actions()
     return is_contest_admin(request) or is_contest_observer(request)
Example #17
0
def edit_post_view(request, category_id, thread_id, post_id):
    (category, thread, post) = get_forum_ctp(category_id, thread_id, post_id)
    is_admin = is_contest_admin(request)

    if not (post.author == request.user or is_admin):
        raise PermissionDenied

    if request.method == 'POST':
        form = PostForm(request, request.POST, instance=post)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.approved = False
            instance.last_edit_date = request.timestamp
            instance.save()
            return redirect('forum_thread', contest_id=request.contest.id,
                            category_id=category.id,
                            thread_id=thread.id)
    else:
        form = PostForm(request, instance=post)

    return TemplateResponse(request, 'forum/edit_post.html', {
        'forum': request.contest.forum, 'category': category,
        'thread': thread, 'form': form, 'post': post,
        'msgs': get_msgs(request)
    })
Example #18
0
def download_user_all_output_view(request, submission_report_id):
    submission_report = get_object_or_404(SubmissionReport,
                                          id=submission_report_id)
    _check_generate_out_permission(request, submission_report)

    testreports = TestReport.objects.filter(
                                        submission_report=submission_report)
    if not all(bool(report.output_file) for report in testreports):
        raise Http404

    if not is_contest_admin(request):
        for report in testreports:
            _check_generated_out_visibility_for_user(report)

    zipfd, tmp_zip_filename = tempfile.mkstemp()
    with zipfile.ZipFile(os.fdopen(zipfd, 'wb'), 'w') as zip:
        for report in testreports:
            arcname = _userout_filename(report)
            testfd, tmp_test_filename = tempfile.mkstemp()
            fileobj = os.fdopen(testfd, 'wb')
            try:
                shutil.copyfileobj(report.output_file, fileobj)
                fileobj.close()
                zip.write(tmp_test_filename, arcname)
            finally:
                os.unlink(tmp_test_filename)

        name = submission_report.submission.problem_instance.problem.short_name
        return stream_file(File(open(tmp_zip_filename, 'rb'),
            name=name + '_' + str(submission_report.submission.user) +
            '_' + str(submission_report.id) + '_user_outs.zip'))
Example #19
0
def test_view(request, package_id):
    tp = get_object_or_404(TestsPackage, id=package_id)
    if not is_contest_admin(request) and not tp.is_visible(request.timestamp):
        raise PermissionDenied
    file_name = '%s.zip' % tp.name
    file_name = file_name.encode('utf-8')
    return stream_file(tp.package, name=file_name)
Example #20
0
def dangling_problems_processor(request):
    if not getattr(request, 'contest', None):
        return {}
    if not is_contest_admin(request):
        return {}

    def generator():
        dangling_pis = ProblemInstance.objects.filter(contest=request.contest,
                round__isnull=True)
        count = dangling_pis.count()
        if not count:
            return ''
        elif count == 1:
            pi = dangling_pis.get()
            link = reverse('oioioiadmin:contests_probleminstance_change',
                        args=(pi.id,))
            if request.path == link:
                return ''
        else:
            link = reverse('oioioiadmin:contests_probleminstance_changelist')
        text = ungettext('%(count)d PROBLEM WITHOUT ROUND',
                '%(count)d PROBLEMS WITHOUT ROUNDS',
                count) % {'count': count}
        return make_navbar_badge(link, text)
    return {'extra_navbar_right_dangling_problems': lazy(generator, unicode)()}
Example #21
0
def add_or_update_problem(request, contest, template):
    if 'problem' in request.GET:
        existing_problem = \
                get_object_or_404(Problem, id=request.GET['problem'])
        if contest and not existing_problem.probleminstance_set.filter(
                contest=contest).exists():
            raise Http404
        if not can_admin_problem(request, existing_problem):
            raise PermissionDenied
    else:
        existing_problem = None
        if not request.user.has_perm('problems.problems_db_admin'):
            if contest and (not is_contest_admin(request)):
                raise PermissionDenied

    navbar_links = navbar_links_registry.template_context(request)

    context = {'existing_problem': existing_problem, 'navbar_links': navbar_links}
    tab_kwargs = {
        'contest': contest,
        'existing_problem': existing_problem
    }

    tab_link_params = request.GET.dict()

    def build_link(tab):
        tab_link_params['key'] = tab.key
        return request.path + '?' + six.moves.urllib.parse.urlencode(
                tab_link_params)

    return tabbed_view(request, template, context,
            problem_sources(request), tab_kwargs, build_link)
Example #22
0
 def filter_visible_reports(self, request, submission, queryset):
     if is_contest_admin(request):
         return queryset
     else:
         return queryset.filter(status='ACTIVE',
                 kind__in=self.get_visible_reports_kinds(request,
                                                         submission))
Example #23
0
def logo_processor(request):
    if not getattr(request, 'contest', None):
        return {}

    if is_contest_admin(request):
        return {}

    @memoized
    def generator():
        try:
            instance = ContestLogo.objects.get(contest=request.contest)
            url = reverse('logo_image_view',
                    kwargs={'contest_id': request.contest.id})
            link = instance.link
        except ContestLogo.DoesNotExist:
            url = request.contest.controller.default_contestlogo_url()
            link = request.contest.controller.default_contestlogo_link()

        if not url:
            return ''

        if not link:
            link = reverse('default_contest_view',
                           kwargs={'contest_id': request.contest.id})
        context = Context({'url': url, 'link': link})
        template = loader.get_template('contestlogo/logo.html')
        return template.render(context)
    return {'extra_menu_top_contestlogo': lazy(generator, unicode)()}
Example #24
0
def visible_messages(request, author=None, category=None, kind=None):
    rounds_ids = [round.id for round in visible_rounds(request)]
    q_expression = Q(round_id__in=rounds_ids)
    if author:
        q_expression = q_expression & Q(author=author)
    if category:
        # pylint: disable=unpacking-non-sequence
        category_type, category_id = category
        if category_type == 'p':
            q_expression = q_expression & Q(problem_instance__id=category_id)
        elif category_type == 'r':
            q_expression = q_expression & Q(round__id=category_id,
                                            problem_instance=None)
    if kind:
        q_expression = q_expression & Q(kind=kind)
    messages = Message.objects.filter(q_expression).order_by('-date')
    if not is_contest_admin(request):
        q_expression = Q(kind='PUBLIC')
        if request.user.is_authenticated:
            q_expression = q_expression \
                    | (Q(author=request.user) & Q(kind='QUESTION')) \
                    | Q(top_reference__author=request.user)
        q_time = Q(date__lte=request.timestamp) \
                 & ((Q(pub_date__isnull=True)
                    | Q(pub_date__lte=request.timestamp))) \
                 & ((Q(top_reference__isnull=True))
                    | Q(top_reference__pub_date__isnull=True)
                    | Q(top_reference__pub_date__lte=request.timestamp))
        messages = messages.filter(q_expression, q_time)

    return messages.select_related('top_reference', 'author',
            'problem_instance', 'problem_instance__problem')
Example #25
0
 def can_see_round(self, request, round):
     if is_contest_admin(request):
         return True
     rtimes = self.get_round_times(request, round)
     if has_any_active_round(request):
         return rtimes.is_active(request.timestamp)
     return super(OIOnsiteContestController, self) \
             .can_see_round(request, round)
Example #26
0
def forum_exists_and_visible(request):
    # checks whether the forum exists and
    # - is locked & visible
    # - is not locked
    # - user is contest admin
    return forum_exists(request) and (not
            (request.contest.forum.is_locked(request.timestamp) and
             not request.contest.forum.visible)) or (is_contest_admin(request))
Example #27
0
 def can_edit_registration(self, request, participant):
     if self.form_class is None:
         return False
     if is_contest_admin(request):
         return True
     if participant.status == 'BANNED':
         return False
     return bool(request.user == participant.user)
Example #28
0
 def queryset(self, request):
     queryset = super(ProblemAdmin, self).queryset(request)
     combined = queryset.none()
     if request.user.has_perm('problems.problems_db_admin'):
         combined |= queryset.filter(contest__isnull=True)
     if is_contest_admin(request):
         combined |= queryset.filter(contest=request.contest)
     return combined
Example #29
0
 def test_utils(self):
     ofactory = partial(self.factory, self.observer)
     cfactory = partial(self.factory, self.cadmin)
     ufactory = partial(self.factory, User.objects.get(username='******'))
     self.assertFalse(can_enter_contest(ufactory(self.during)))
     self.assertTrue(is_contest_admin(cfactory(self.during)))
     self.assertTrue(can_enter_contest(cfactory(self.during)))
     self.assertTrue(is_contest_observer(ofactory(self.during)))
     self.assertTrue(can_enter_contest(ofactory(self.during)))
Example #30
0
def get_testrun_report_or_404(request, submission, testrun_report_id=None):
    qs = TestRunReport.objects.filter(submission_report__submission=submission)

    if is_contest_admin(request) and testrun_report_id is not None:
        qs = qs.filter(id=testrun_report_id)
    else:
        qs = qs.filter(submission_report__status='ACTIVE')

    return get_object_or_404(qs)
Example #31
0
 def get_list_display(self, request):
     items = super(ProblemPackageAdmin, self).get_list_display(request) + [
         self.actions_field(request.contest)
     ]
     if not is_contest_admin(request):
         disallowed_items = [
             'created_by',
             'actions_field',
         ]
         items = [item for item in items if item not in disallowed_items]
     return items
    def can_see_round(self, request, round):
        """Determines if the current user is allowed to see the given round.

           If not, everything connected with this round will be hidden.

           The default implementation checks round dates.
        """
        if is_contest_admin(request):
            return True
        rtimes = self.get_round_times(request, round)
        return not rtimes.is_future(request.timestamp)
def can_make_complaint(request):
    if not request.user.is_authenticated():
        return False
    if is_contest_admin(request):
        return False
    try:
        cconfig = request.contest.complaints_config
        return cconfig.enabled and request.timestamp >= cconfig.start_date \
                and request.timestamp <= cconfig.end_date
    except ComplaintsConfig.DoesNotExist:
        return False
Example #34
0
def contest_attachment_view(request, attachment_id):
    attachment = get_object_or_404(ContestAttachment,
            contest_id=request.contest.id, id=attachment_id)

    if (attachment.round and
            attachment.round not in visible_rounds(request)) or \
       (not is_contest_admin(request) and
           attachment.pub_date and attachment.pub_date > request.timestamp):
        raise PermissionDenied

    return stream_file(attachment.content, attachment.download_name)
Example #35
0
def registration_notice_fragment(request):
    rc = request.contest.controller.registration_controller()
    if isinstance(rc, PARegistrationController) \
            and request.user.is_authenticated() \
            and not is_contest_admin(request) \
            and not is_participant(request) \
            and rc.can_register(request):
        return render_to_string('pa/registration-notice.html',
            context_instance=RequestContext(request))
    else:
        return None
Example #36
0
def forum_exists_and_visible(request):
    # checks whether the forum exists and
    # - is locked & visible
    # - is not locked
    # - user is contest admin
    # TODO maybe logic error (exists and visible or admin),
    #  should be exists and (visible or admin)?
    return (forum_exists(request) and
            (not (request.contest.forum.is_locked(request.timestamp)
                  and not request.contest.forum.visible))
            or (is_contest_admin(request)))
Example #37
0
    def get_readonly_fields(self, request, obj=None):
        result = super(TermsAcceptedPhraseInline,
                       self).get_readonly_fields(request, obj)

        if not is_contest_admin(
                request
        ) or not request.contest.controller.registration_controller(
        ).can_change_terms_accepted_phrase(request):
            result = result + ('text', )

        return result
Example #38
0
    def test_utils_off(self):
        user = User.objects.get(pk=1001)
        contest = Contest.objects.get(pk="uc")

        request = RequestFactory().request()
        request.contest = contest
        request.user = user

        self.assertFalse(is_contest_admin(request))
        self.assertFalse(is_contest_basicadmin(request))
        self.assertFalse(is_contest_observer(request))
Example #39
0
def get_testrun_report_or_404(
    request, submission, testrun_report_id=None, model=TestRunReport
):
    qs = model.objects.filter(submission_report__submission=submission)

    if is_contest_admin(request) and testrun_report_id is not None:
        qs = qs.filter(id=testrun_report_id)
    else:
        qs = qs.filter(submission_report__status='ACTIVE')

    return get_object_or_404(qs)
Example #40
0
 def get_queryset(self, request):
     queryset = super(ProblemAdmin, self).get_queryset(request)
     if request.user.is_anonymous():
         combined = queryset.none()
     else:
         combined = request.user.problem_set.all()
     if request.user.has_perm('problems.problems_db_admin'):
         combined |= queryset.filter(contest__isnull=True)
     if is_contest_admin(request):
         combined |= queryset.filter(contest=request.contest)
     return combined
Example #41
0
    def can_see_source(self, request, submission):
        """Check if submission's source should be visible.
           :type submission: oioioi.contest.Submission

           Consider using filter_visible_sources instead, especially for batch
           queries.
        """
        qs = Submission.objects.filter(id=submission.id)
        if not (is_contest_admin(request) or is_contest_observer(request)) \
                and is_model_submission(submission):
            return False
        return self.filter_visible_sources(request, qs).exists()
Example #42
0
def _testreports_to_generate_outs(request, testreports):
    """Gets tests' ids from ``testreports`` without generated or processing
       right now outs. Returns list of tests' ids.
    """
    test_ids = []

    for testreport in testreports:
        download_control, created = UserOutGenStatus.objects. \
                select_for_update().get_or_create(testreport=testreport)

        if not created:
            if not is_contest_admin(request):
                # out generated by admin is now visible for user
                download_control.visible_for_user = True
                download_control.save()

            # making sure, that output really exists or is processing right now
            if bool(testreport.output_file) or download_control.status == '?':
                # out already generated or is processing, omit
                continue
            else:
                download_control.status = '?'
                download_control.save()
        elif bool(testreport.output_file):
            # out already generated but without UserOutGenStatus object
            # so probably automatically by system
            download_control.visible_for_user = True
            download_control.status = 'OK'
            download_control.save()
            continue
        else:
            download_control.status = '?'
            # invisible to the the user when first generated by the admin
            download_control.visible_for_user = \
                    not is_contest_admin(request)
            download_control.save()

        test_ids.append(testreport.test.id)

    return test_ids
Example #43
0
    def render_disqualifications(self, request, user, submissions):
        """Renders all disqualifications of the given user to HTML, which
           may be put anywhere on the site.

           This method should process only submission from ``submissions``.
        """
        if not (self.is_user_disqualified(request, user) or
                (is_contest_admin(request)
                 and self.user_has_disqualification_history(request, user))):
            return None

        disqualified_submissions = []
        for submission in submissions:
            if self.is_submission_disqualified(submission) or \
                    (is_contest_admin(request) and
                        self.has_disqualification_history(submission)):
                disqualified_submissions.append({
                    'submission':
                    submission,
                    'reason':
                    self._render_disqualification_reason(request, submission)
                })

        contestwide = self._render_contestwide_disqualification_reason(
            request, user)
        if not disqualified_submissions and not contestwide:
            return None

        if is_contest_admin(request):
            template = 'disqualification/submissions-admin.html'
        else:
            template = 'disqualification/submissions.html'

        return render_to_string(
            template,
            context_instance=RequestContext(
                request, {
                    'submissions': disqualified_submissions,
                    'contestwide': contestwide,
                }))
Example #44
0
    def get_contest_participant_info_list(self, request, user):
        """Returns a list of tuples (priority, info).
           Each entry represents a fragment of HTML with information about the
           user's participation in the contest. This information will be
           visible for contest admins. It can be any information an application
           wants to add.

           The fragments are sorted by priority (descending) and rendered in
           that order.

           The default implementation returns basic info about the contestant:
           his/her full name, e-mail, the user id, his/her submissions and
           round time extensions.

           To add additional info from another application, override this
           method. For integrity, include the result of the parent
           implementation in your output.
        """
        res = [(100, render_to_string('contests/basic_user_info.html', {
                        'request': request,
                        'target_user_name': self.get_user_public_name(request,
                                                                      user),
                        'target_user': user,
                        'user': request.user}))]

        exts = RoundTimeExtension.objects.filter(user=user,
                round__contest=request.contest)
        if exts.exists():
            res.append((99,
                    render_to_string('contests/roundtimeextension_info.html', {
                            'request': request,
                            'extensions': exts,
                            'user': request.user})))

        if is_contest_admin(request) or is_contest_observer(request):
            submissions = Submission.objects.filter(
                    problem_instance__contest=request.contest, user=user) \
                    .order_by('-date').select_related()

            if submissions.exists():
                submission_records = [submission_template_context(request, s)
                        for s in submissions]
                context = {
                    'submissions': submission_records,
                    'show_scores': True
                }
                rendered_submissions = render_to_string(
                        'contests/user_submissions_table.html',
                        context_instance=RequestContext(request, context))
                res.append((50, rendered_submissions))

        return res
Example #45
0
def download_user_one_output_view(request, testreport_id):
    testreport = get_object_or_404(TestReport, id=testreport_id)

    if not is_contest_admin(request):
        _check_generated_out_visibility_for_user(testreport)

    submission_report = testreport.submission_report
    _check_generate_out_permission(request, submission_report)

    if not bool(testreport.output_file):
        raise Http404

    return stream_file(testreport.output_file, _userout_filename(testreport))
Example #46
0
    def can_see_problem_statistics(self, request, pi):
        controller = pi.controller
        rtimes = rounds_times(request, self.contest)

        can_see_problem = controller.can_see_problem(request, pi)
        if pi.round:
            can_see_round_results = rtimes[pi.round].public_results_visible(
                request.timestamp)
        else:
            can_see_round_results = False
        can_observe = is_contest_admin(request) or is_contest_observer(request)

        return can_see_problem and (can_see_round_results or can_observe)
Example #47
0
    def filter_visible_sources(self, request, queryset):
        """Determines which sources the user could see.

           This usually involves cross-user privileges, like publicizing
           sources. Default implementations delegates to
           :meth:`~ContestController.filter_my_visible_submissions`, except for
           admins and observers, which get full access.

           Queryset's model should be oioioi.contest.Submission
        """
        if is_contest_admin(request) or is_contest_observer(request):
            return queryset
        return self.filter_my_visible_submissions(request, queryset)
    def can_see_problem(self, request, problem_instance):
        """Determines if the current user is allowed to see the given problem.

           If not, the problem will be hidden from all lists, so that its name
           should not be visible either.

           The default implementation checks if the user can see the given
           round (calls :meth:`can_see_round`).
        """
        if not problem_instance.round:
            return False
        if is_contest_admin(request):
            return True
        return self.can_see_round(request, problem_instance.round)
Example #49
0
    def _out_generate_status(self, request, testreport):
        try:
            if is_contest_admin(request) or \
                    testreport.userout_status.visible_for_user:
                # making sure, that output really exists or is processing
                if bool(testreport.output_file) or \
                        testreport.userout_status.status == '?':
                    return testreport.userout_status.status

        except UserOutGenStatus.DoesNotExist:
            if testreport.output_file:
                return 'OK'

        return None
    def can_see_source(self, request, submission):
        """Determines if the current user is allowed to see source
           of ``submission``.

           This usually involves cross-user privileges, like publicizing
           sources.
           Default implementations delegates to
           :meth:`~ContestController.filter_my_visible_submissions`, except for
           admins and observers, which get full access.
        """
        if is_contest_admin(request) or is_contest_observer(request):
            return True
        queryset = Submission.objects.filter(id=submission.id)
        return self.filter_my_visible_submissions(request, queryset).exists()
 def _rounds_for_ranking(self, request, key=CONTEST_RANKING_KEY):
     can_see_all = is_contest_admin(request) or is_contest_observer(request)
     ccontroller = self.contest.controller
     queryset = self.contest.round_set.all()
     if key != CONTEST_RANKING_KEY:
         queryset = queryset.filter(id=key)
     if can_see_all:
         for round in queryset:
             yield round
     else:
         for round in queryset:
             rtimes = ccontroller.get_round_times(request, round)
             if not rtimes.is_future(request.timestamp):
                 yield round
Example #52
0
def can_admin_instance_of_problem(request, problem):
    """Checks if the user has admin permission in a ProblemInstace
       of the given Problem.
       If request.contest is not None then ProblemInstaces from this contest
       are taken into account, problem.main_problem_instance otherwise.

       If there is no ProblemInstace of problem in request.contest then
       the function returns False.

       If the user has permission to admin problem then the function
       will always return True.
    """
    if can_admin_problem(request, problem):
        return True
    return is_contest_admin(request) and ProblemInstance.objects \
        .filter(problem=problem, contest=request.contest).exists()
Example #53
0
    def view(self, request, contest, existing_problem=None):
        form = self.make_form(request, contest, existing_problem)
        if contest:
            contest.controller.adjust_upload_form(request, existing_problem,
                    form)
        if request.method == 'POST':
            if form.is_valid():
                try:
                    # We need to make sure that the package is saved in the
                    # database before the Celery task starts.
                    with transaction.atomic():
                        original_filename, file_manager = \
                                self.get_package_file(request, contest, form,
                                        existing_problem)
                        with file_manager as path:
                            package = self.create_package_instance(request,
                                    contest, path, existing_problem,
                                    original_filename)
                            env = self.create_env(request, contest, form, path,
                                    package, existing_problem,
                                    original_filename)
                            if contest:
                                contest.controller.fill_upload_environ(request,
                                        form, env)
                            package.save()
                        async_task = unpackmgr_job.s(env)
                        async_result = async_task.freeze()
                        ProblemPackage.objects.filter(id=package.id).update(
                                celery_task_id=async_result.task_id)
                    async_task.delay()
                    if request.user.is_superuser or (request.contest and
                                 is_contest_admin(request)):
                        messages.success(request,
                                _("Package queued for processing."))
                        return self._redirect_response(request)

                    messages.success(request,
                        _("Package queued for processing. It will appear in "
                            "problem list when ready. Please be patient."))
                    return TemplateResponse(request, self.template_name,
                                            {'form': form})

                # pylint: disable=broad-except
                except Exception, e:
                    logger.error("Error processing package", exc_info=True,
                        extra={'omit_sentry': True})
                    form._errors['__all__'] = form.error_class([smart_str(e)])
Example #54
0
def all_messages_view(request):
    def make_entry(m):
        return {
            'message': m,
            'replies': [],
            'timestamp': m.get_user_date(),  # only for messages ordering
            'is_new': m in new_msgs,
            'has_new_message': m in new_msgs,  # only for messages ordering
            'needs_reply': m in unanswered,
        }

    form, vmsg_kwargs = process_filter_form(request)
    vmessages = visible_messages(request, **vmsg_kwargs)
    new_msgs = frozenset(new_messages(request, vmessages))
    unanswered = unanswered_questions(vmessages)
    tree = {m.id: make_entry(m) for m in vmessages if m.top_reference is None}

    for m in vmessages:
        if m.id in tree:
            continue
        entry = make_entry(m)
        if m.top_reference_id in tree:
            parent = tree[m.top_reference_id]
            parent['replies'].append(entry)
            parent['timestamp'] = max(parent['timestamp'], entry['timestamp'])
            parent['has_new_message'] = max(parent['has_new_message'],
                                            entry['has_new_message'])
        else:
            tree[m.id] = entry

    if is_contest_admin(request):
        sort_key = lambda x: (x['needs_reply'], x['has_new_message'], x[
            'timestamp'])
    else:
        sort_key = lambda x: (x['has_new_message'], x['needs_reply'], x[
            'timestamp'])
    tree_list = sorted(list(tree.values()), key=sort_key, reverse=True)
    for entry in tree_list:
        entry['replies'].sort(key=sort_key, reverse=True)

    if request.user.is_authenticated:
        mark_messages_read(request.user, vmessages)

    return TemplateResponse(request, 'questions/tree.html', {
        'tree_list': tree_list,
        'form': form,
    })
Example #55
0
    def adjust_submission_form(self, request, form, problem_instance):
        super(TeamsMixinForContestController, self).adjust_submission_form(
            request, form, problem_instance
        )
        try:
            tm = TeamMembership.objects.get(
                user=request.user, team__contest=request.contest
            )
            if not is_contest_admin(request):
                form.fields['user'] = UserSelectionField(
                    initial=tm.team.user,
                    label=_("Team name"),
                    widget=forms.TextInput(attrs={'readonly': 'readonly'}),
                    help_text=_(
                        "You are in the team, so submission will"
                        " be sent as the team."
                    ),
                )

                def clean_user():
                    user = form.cleaned_data['user']
                    try:
                        tm = TeamMembership.objects.get(
                            user=request.user, team__contest=request.contest
                        )
                        if user != tm.team.user:
                            raise forms.ValidationError(
                                _("You can't submit a" " solution for another team!")
                            )
                        return user
                    except TeamMembership.DoesNotExist:
                        raise forms.ValidationError(_("Team does not exist"))

                form.clean_user = clean_user
            else:
                form.fields['team'] = forms.CharField(
                    initial=tm.team.name,
                    label=_("Team name"),
                    widget=forms.TextInput(attrs={'readonly': 'readonly'}),
                    help_text=_(
                        "You are in the team, but you are also the "
                        "admin, so you can send solution as the "
                        "team user or as yourself."
                    ),
                )
        except TeamMembership.DoesNotExist:
            pass
    def serialize_ranking(self, request, key):
        controller = request.contest.controller
        rounds = list(self._rounds_for_ranking(request, key))
        # If at least one visible round is not trial we don't want to show
        # trial rounds in default ranking.
        if key == CONTEST_RANKING_KEY:
            not_trial = [r for r in rounds if not r.is_trial]
            if not_trial:
                rounds = not_trial

        freeze_times = [
            controller.get_round_freeze_time(round) for round in rounds
        ]

        pis = list(
            ProblemInstance.objects.filter(round__in=rounds).select_related(
                'problem').prefetch_related('round'))
        rtopis = defaultdict(lambda: [])

        for pi in pis:
            rtopis[pi.round].append(pi)

        users = self.filter_users_for_ranking(request, key, User.objects.all())

        results = []
        ccontroller = self.contest.controller

        frozen = False
        for round, freeze_time in zip(rounds, freeze_times):
            rpis = rtopis[round]
            rtimes = ccontroller.get_round_times(request, round)
            if freeze_time is None or \
                    is_contest_admin(request) or \
                    rtimes.results_visible(request.timestamp) or \
                    request.timestamp <= freeze_time:
                results += UserResultForProblem.objects \
                    .filter(problem_instance__in=rpis, user__in=users) \
                    .prefetch_related('problem_instance__round')
            else:
                results += self._get_old_results(request, freeze_time, rpis,
                                                 users)
                frozen = True

        data = self._get_users_results(pis, results, rounds, users)
        self._assign_places(data, itemgetter('sum'))
        return {'rows': data, 'problem_instances': pis, 'frozen': frozen}
Example #57
0
def message_view(request, message_id):
    message = get_object_or_404(Message,
                                id=message_id,
                                contest_id=request.contest.id)
    vmessages = visible_messages(request)
    if not vmessages.filter(id=message_id):
        raise PermissionDenied
    if message.top_reference_id is None:
        replies = list(vmessages.filter(top_reference=message))
        replies.sort(key=Message.get_user_date)
    else:
        replies = []
    if is_contest_admin(request) and message.kind == 'QUESTION' and \
            message.can_have_replies:
        if request.method == 'POST':
            form = AddReplyForm(request, request.POST)

            if request.POST.get('just_reload') != 'yes' and form.is_valid():
                instance = form.save(commit=False)
                instance.top_reference = message
                instance.author = request.user
                instance.date = request.timestamp
                instance.save()

                log_addition(request, instance)
                return redirect('contest_messages',
                                contest_id=request.contest.id)
            elif request.POST.get('just_reload') == 'yes':
                form.is_bound = False
        else:
            form = AddReplyForm(request,
                                initial={
                                    'topic': _("Re: ") + message.topic,
                                })
    else:
        form = None
    if request.user.is_authenticated:
        mark_messages_read(request.user, [message] + replies)
    return TemplateResponse(
        request, 'questions/message.html', {
            'message': message,
            'replies': replies,
            'form': form,
            'reply_to_id': message.top_reference_id or message.id,
            'timestamp': request_time_seconds(request)
        })
Example #58
0
    def adjust_submission_form(self, request, form):
        size_limit = self.get_submission_size_limit()

        def validate_file_size(file):
            if file.size > size_limit:
                raise ValidationError(_("File size limit exceeded."))

        def validate_language(file):
            ext = self._get_language(file)
            if ext not in self.get_allowed_extensions():
                raise ValidationError(_(
                    "Unknown or not supported file extension."))

        form.fields['file'] = forms.FileField(allow_empty_file=False,
                validators=[validate_file_size, validate_language],
                label=_("File"),
                help_text=_("Language is determined by the file extension."
                            " It has to be one of: %s.") %
                            (', '.join(self.get_allowed_extensions()),)
                )

        if is_contest_admin(request):
            form.fields['user'] = forms.CharField(label=_("User"),
                    initial=request.user.username)

            def clean_user():
                username = form.cleaned_data['user']
                if username == request.user.username:
                    return request.user

                qs = User.objects.filter(username=username)
                try:
                    if request.user.is_superuser:
                        return qs.get()
                    else:
                        return self.registration_controller() \
                                .filter_participants(qs) \
                                .get()
                except User.DoesNotExist:
                    raise forms.ValidationError(_(
                            "User does not exist or "
                            "you do not have enough privileges"))
            form.clean_user = clean_user
            form.fields['kind'] = forms.ChoiceField(choices=[
                ('NORMAL', _("Normal")), ('IGNORED', _("Ignored"))],
                initial=form.kind, label=_("Kind"))
Example #59
0
    def _render_contestwide_disqualification_reason(self, request, user):
        """Renders part with reason of the given user disqualification not
           directly associated with any particular submission.

           This method is only used internally.
        """
        reasons = Disqualification.objects.filter(user=user,
                                                  contest=request.contest,
                                                  submission__isnull=True)
        if not is_contest_admin(request):
            reasons = reasons.filter(guilty=True)

        if not reasons:
            return None
        return render_to_string('disqualification/reason.html',
                                request=request,
                                context={'reasons': reasons})
    def filter_my_visible_submissions(self, request, queryset):
        """Returns the submissions which the user should see in the
           "My submissions" view.

           The default implementation returns all submissions belonging to
           the user for the problems that are visible.

           Should return the updated queryset.
        """
        if not request.user.is_authenticated():
            return queryset.none()
        qs = queryset.filter(user=request.user) \
            .filter(problem_instance__in=visible_problem_instances(request))
        if is_contest_admin(request):
            return qs
        else:
            return qs.filter(date__lte=request.timestamp)