Esempio n. 1
0
    def adjust_submission_form(self, request, form, problem_instance):
        controller = problem_instance.controller
        size_limit = controller.get_submission_size_limit(problem_instance)

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

        def validate_code_length(code):
            if len(code) > size_limit:
                raise ValidationError(_("Code length limit exceeded."))

        def validate_language(file):
            ext = controller._get_language(file, problem_instance)
            if ext not in get_allowed_languages_extensions(problem_instance):
                raise ValidationError(_(
                    "Unknown or not supported file extension."))

        def parse_problem(problem):
            available_problems = form.fields['problem_instance_id'].choices
            problem_id = None
            for (id, name) in available_problems:
                if name.find(problem) != -1:
                    if problem_id is None:
                        problem_id = id
                    else:
                        # matched more than one available problem
                        return None
            return problem_id

        form.fields['file'] = forms.FileField(required=False,
                allow_empty_file=False,
                validators=[validate_file_size, validate_language],
                label=_("File"),
                help_text=mark_safe(_(
                    "Language is determined by the file extension."
                    " It has to be one of: %s."
                    " You can paste the code below instead of"
                    " choosing file."
                    " <strong>Try drag-and-drop too!</strong>"
                ) % (', '.join(get_allowed_languages_extensions(
                        problem_instance))))
        )
        form.fields['code'] = forms.CharField(required=False,
                label=_("Code"),
                validators=[validate_code_length],
                widget=forms.widgets.Textarea(attrs={'rows': 10,
                    'class': 'monospace input-xxxlarge'})
        )

        choices = [('', '')]
        choices += [(lang, lang) for lang
                    in problem_instance.controller.get_allowed_languages()]
        form.fields['prog_lang'] = forms.ChoiceField(required=False,
                label=_("Programming language"),
                choices=choices,
                widget=forms.Select(attrs={'disabled': 'disabled'})
        )
        narrow_input_field(form.fields['prog_lang'])

        if 'dropped_solution' in request.POST:
            form.fields['code'].initial = request.POST['dropped_solution']

        # guessing problem name and extension when file dragged and dropped
        if 'dropped_solution_name' in request.POST:
            # do not validate blank fields this time
            form.is_bound = False

            fname = request.POST['dropped_solution_name']
            if fname.count('.') == 1:
                [problem, ext] = fname.split('.', 1)
                if 'problem_instance_id' not in request.POST:
                    form.fields['problem_instance_id'].initial = \
                            parse_problem(problem)
                if 'prog_lang' not in request.POST:
                    form.fields['prog_lang'].initial = \
                            get_language_by_extension(problem_instance, ext)

        if request.contest and is_contest_admin(request):
            form.fields['user'] = UserSelectionField(
                    label=_("User"),
                    hints_url=reverse('contest_user_hints',
                            kwargs={'contest_id': request.contest.id}),
                    initial=request.user)


            def clean_user():
                try:
                    user = form.cleaned_data['user']
                    if user == request.user:
                        return user
                    if not request.user.is_superuser:
                        controller.registration_controller() \
                            .filter_participants(
                                User.objects.filter(pk=user.pk)).get()
                    return user
                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"))
            narrow_input_fields([form.fields['kind'], form.fields['user']])
Esempio n. 2
0
    def __init__(self, request, *args, **kwargs):
        problem_instance = kwargs.pop('problem_instance', None)
        if problem_instance is None:
            # if problem_instance does not exist any from the current
            # contest is chosen. To change in future.
            # ALSO in mailsubmit.forms
            contest = request.contest
            assert contest is not None
            problem_instances = ProblemInstance.objects \
                    .filter(contest=contest)
            problem_instance = problem_instances[0]
        else:
            problem_instances = [problem_instance]
            contest = None
        self.all_problem_instances = problem_instances

        # Default kind is selected based on
        # the first problem_instance assigned to this form.
        # This is an arbitrary choice.
        self.kind = kwargs.pop(
            'kind',
            problem_instance.controller.get_default_submission_kind(
                request, problem_instance=problem_instance))
        problem_filter = kwargs.pop('problem_filter', None)
        self.request = request

        # taking the available problems
        pis = self.get_problem_instances()
        if problem_filter:
            pis = problem_filter(pis)
        pi_choices = [(pi.id, six.text_type(pi)) for pi in pis]

        # pylint: disable=non-parent-init-called
        # init form with previously sent data
        forms.Form.__init__(self, *args, **kwargs)

        # prepare problem instance selector
        pi_field = self.fields['problem_instance_id']
        pi_field.widget.attrs['class'] = 'input-xlarge'
        self._set_field_show_always('problem_instance_id')

        if len(pi_choices) > 1:
            pi_field.choices = [('', '')] + pi_choices
        else:
            pi_field.choices = pi_choices

        narrow_input_field(pi_field)

        # if contest admin, add kind and 'as other user' field
        if contest and is_contest_basicadmin(request):
            self.fields['user'] = UserSelectionField(
                label=_("User"),
                hints_url=reverse('contest_user_hints',
                                  kwargs={'contest_id': request.contest.id}),
                initial=request.user)
            self._set_field_show_always('user')

            def clean_user():
                try:
                    user = self.cleaned_data['user']
                    if user == request.user:
                        return user
                    if not request.user.is_superuser:
                        contest.controller.registration_controller() \
                            .filter_participants(
                                User.objects.filter(pk=user.pk)).get()
                    return user
                except User.DoesNotExist:
                    raise forms.ValidationError(
                        _("User does not exist or "
                          "you do not have enough privileges"))

            self.clean_user = clean_user
            self.fields['kind'] = forms.ChoiceField(choices=[
                ('NORMAL', _("Normal")), ('IGNORED', _("Ignored"))
            ],
                                                    initial=self.kind,
                                                    label=_("Kind"))
            self._set_field_show_always('kind')
            narrow_input_fields([self.fields['kind'], self.fields['user']])

        # adding additional fields, etc
        for pi in pis:
            pi.controller.adjust_submission_form(request, self, pi)

        self._set_default_fields_attributes()

        # fix field order (put kind and user at the end)
        self._move_field_to_end('user')
        self._move_field_to_end('kind')
Esempio n. 3
0
    def __init__(self, request, *args, **kwargs):
        problem_instance = kwargs.pop('problem_instance', None)
        if problem_instance is None:
            # if problem_instance does not exist any from the current
            # contest is chosen. To change in future.
            # ALSO in mailsubmit.forms
            contest = request.contest
            assert contest is not None
            problem_instances = ProblemInstance.objects \
                    .filter(contest=contest)
            problem_instance = problem_instances[0]
        else:
            problem_instances = [problem_instance]
            contest = None

        # Default kind is selected based on
        # the first problem_instance assigned to this form.
        # This is an arbitrary choice.
        self.kind = kwargs.pop('kind',
                               problem_instance.controller.get_default_submission_kind(request,
                                       problem_instance=problem_instance))
        problem_filter = kwargs.pop('problem_filter', None)
        self.request = request

        # taking the available problems
        pis = self.get_problem_instances()
        if problem_filter:
            pis = problem_filter(pis)
        pi_choices = [(pi.id, six.text_type(pi)) for pi in pis]

        # pylint: disable=non-parent-init-called
        # init form with previously sent data
        forms.Form.__init__(self, *args, **kwargs)

        # prepare problem instance selector
        pi_field = self.fields['problem_instance_id']
        pi_field.widget.attrs['class'] = 'input-xlarge'
        self._set_field_show_always('problem_instance_id')

        if len(pi_choices) > 1:
            pi_field.choices = [('', '')] + pi_choices
        else:
            pi_field.choices = pi_choices

        narrow_input_field(pi_field)

        # if contest admin, add kind and 'as other user' field
        if contest and is_contest_admin(request):
            self.fields['user'] = UserSelectionField(
                    label=_("User"),
                    hints_url=reverse('contest_user_hints',
                            kwargs={'contest_id': request.contest.id}),
                    initial=request.user)
            self._set_field_show_always('user')

            def clean_user():
                try:
                    user = self.cleaned_data['user']
                    if user == request.user:
                        return user
                    if not request.user.is_superuser:
                        contest.controller.registration_controller() \
                            .filter_participants(
                                User.objects.filter(pk=user.pk)).get()
                    return user
                except User.DoesNotExist:
                    raise forms.ValidationError(_(
                            "User does not exist or "
                            "you do not have enough privileges"))
            self.clean_user = clean_user
            self.fields['kind'] = forms.ChoiceField(choices=[
                ('NORMAL', _("Normal")), ('IGNORED', _("Ignored"))],
                initial=self.kind, label=_("Kind"))
            self._set_field_show_always('kind')
            narrow_input_fields([self.fields['kind'], self.fields['user']])

        # adding additional fields, etc
        for pi in problem_instances:
            pi.controller.adjust_submission_form(request, self, pi)

        self._set_default_fields_attributes()

        # fix field order (put kind and user at the end)
        self._move_field_to_end('user')
        self._move_field_to_end('kind')