Beispiel #1
0
def get_language_hints_view(request):
    pi_ids = request.GET.getlist(u'pi_ids[]')
    filename = request.GET.get(u'filename', u'')
    pis = ProblemInstance.objects.filter(id__in=pi_ids)

    extension = get_extension(filename)
    lang_dict = {pi: get_language_by_extension(pi, extension) for pi in pis}

    if contest_exists(request):
        submittable_pis = submittable_problem_instances(request)
        lang_dict = {
            pi: lang
            for (pi, lang) in lang_dict.items() if pi in submittable_pis
        }
    else:
        problemsite_key = request.GET.get(u'problemsite_key', u'')
        lang_dict = {
            pi: lang
            for (pi, lang) in lang_dict.items()
            if pi.problem.problemsite.url_key == problemsite_key
        }

    langs = getattr(settings, 'SUBMITTABLE_LANGUAGES', {})
    lang_display_dict = {
        pi.id: langs.get(lang, {'display_name': ''})['display_name']
        for (pi, lang) in lang_dict.items()
    }

    return lang_display_dict
Beispiel #2
0
    def get_compiler_for_submission(self, submission):
        problem_instance = submission.problem_instance
        extension = get_extension(submission.source_file.name)
        language = get_language_by_extension(problem_instance, extension)
        assert language

        compiler = problem_instance.controller.get_compiler_for_language(
            problem_instance, language)
        if compiler is not None:
            return compiler
        else:
            logger.warning("No default compiler for language %s", language)
            return 'default-' + extension
Beispiel #3
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_extension(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'
            }))

        self._add_langs_to_form(request, form, problem_instance)

        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

            langs_field_name = form_field_id_for_langs(problem_instance)
            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 langs_field_name not in request.POST:
                    form.fields[langs_field_name].initial = \
                            get_language_by_extension(problem_instance, ext)

        form.media.add_js([
            'common/submit_view.js',
        ])
Beispiel #4
0
    def validate_submission_form(self, request, problem_instance, form,
                                 cleaned_data):
        if any(field in form.errors.as_data() for field in ('file', 'code')):
            return  # already have a ValidationError

        is_file_chosen = 'file' in cleaned_data and \
                cleaned_data['file'] is not None
        is_code_pasted = 'code' in cleaned_data and cleaned_data['code']

        if (not is_file_chosen and not is_code_pasted) or \
                (is_file_chosen and is_code_pasted):
            raise ValidationError(
                _("You have to either choose file or paste "
                  "code."))

        langs_field_name = form_field_id_for_langs(problem_instance)
        if langs_field_name not in cleaned_data:
            cleaned_data[langs_field_name] = None

        if not cleaned_data[langs_field_name] and is_file_chosen:
            ext = os.path.splitext(cleaned_data['file'].name)[1].strip('.')
            cleaned_data[langs_field_name] = \
                get_language_by_extension(problem_instance, ext)

        if not cleaned_data[langs_field_name]:
            if is_code_pasted:
                raise ValidationError(
                    _("You have to choose programming language."))
            else:
                raise ValidationError(_("Unrecognized file extension."))

        langs = get_allowed_languages_dict(problem_instance)
        if cleaned_data[langs_field_name] not in langs.keys():
            raise ValidationError(
                _("This language is not allowed for selected"
                  " problem."))

        if is_file_chosen:
            code = cleaned_data['file'].read()
        else:
            code = cleaned_data['code'].encode('utf-8')

        if problem_instance.controller \
                .check_repeated_submission(request, problem_instance, form):
            lines = iter(code.splitlines())
            md5 = hashlib.md5()
            for line in lines:
                md5.update(line)
            md5 = md5.hexdigest()
            session_md5_key = 'programs_%d_md5' % \
                    cleaned_data['problem_instance'].id

            if session_md5_key in request.session and \
                    md5 == request.session[session_md5_key]:
                del request.session[session_md5_key]
                raise ValidationError(
                    _("You have submitted the same file for this problem "
                      "again. Please resubmit if you really want "
                      "to submit the same file"))
            else:
                request.session[session_md5_key] = md5
                request.session.save()

        return cleaned_data
Beispiel #5
0
 def get_language_display(self):
     return get_language_by_extension(self.problem_instance, self.extension)
Beispiel #6
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']])
Beispiel #7
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_extension(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 = [('', '')]
        for lang in controller.get_allowed_languages():
            compiler_name = None
            compiler = controller.get_compiler_for_language(
                problem_instance, lang)
            if compiler is not None:
                available_compilers = getattr(settings, 'AVAILABLE_COMPILERS',
                                              {})
                compilers_for_language = available_compilers.get(lang)
                if compilers_for_language is not None:
                    compiler_info = compilers_for_language.get(compiler)
                    if compiler_info is not None:
                        compiler_name = compiler_info.get('display_name')
            langs = getattr(settings, 'SUBMITTABLE_LANGUAGES', {})
            lang_display = langs[lang]['display_name']
            if compiler_name is not None:
                choices.append(
                    (lang, "%s (%s)" % (lang_display, compiler_name)))
            else:
                choices.append((lang, lang_display))

        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)

        form.media.add_js([
            'common/submit_view.js',
        ])
Beispiel #8
0
 def get_language_display(self):
     return get_language_by_extension(self.problem_instance, self.extension)