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
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
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', ])
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
def get_language_display(self): return get_language_by_extension(self.problem_instance, self.extension)
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']])
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', ])
def get_language_display(self): return get_language_by_extension(self.problem_instance, self.extension)