From dfd1b7f527415baf99c181a057bfeb12a0976c75 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Thu, 5 Jan 2017 14:24:05 +0100 Subject: [PATCH] check size and extension in js (and some minor improvements) --- edumed/settings/static.py | 1 + edumed/templates/base_super.html | 3 +-- stage2/forms.py | 12 ++++++++---- stage2/models.py | 2 +- stage2/static/js/checkfile.js | 25 ++++++++++++++++++++++++ stage2/templates/stage2/participant.html | 3 +++ stage2/views.py | 10 +++++----- 7 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 stage2/static/js/checkfile.js diff --git a/edumed/settings/static.py b/edumed/settings/static.py index a2f2c05..98da70c 100644 --- a/edumed/settings/static.py +++ b/edumed/settings/static.py @@ -54,6 +54,7 @@ PIPELINE_JS = { 'js/formset.js', 'pybb/js/pybbjs.js', 'fnpdjango/annoy/annoy.js', + 'js/checkfile.js', ), 'output_filename': 'compressed/base.js', }, diff --git a/edumed/templates/base_super.html b/edumed/templates/base_super.html index 8dbce4a..a4e93c1 100644 --- a/edumed/templates/base_super.html +++ b/edumed/templates/base_super.html @@ -2,7 +2,6 @@ {% load i18n static %} {% load fnp_common fnp_share fnp_lang macros %} {% load compressed static %} -{% load subdomainurls %} {% load piwik_tags %} {% macro title %}{% block title %}{% endblock %}{% endmacro %} @@ -41,7 +40,7 @@ style="position:absolute; opacity: 0.5; top:0; left: -83px; z-index:1000" --> {% if request.user.is_authenticated %} - Wyloguj + Wyloguj {% endif %}
diff --git a/stage2/forms.py b/stage2/forms.py index f7d248e..92af3a0 100644 --- a/stage2/forms.py +++ b/stage2/forms.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from django import forms from django.conf import settings -from django.core.exceptions import ValidationError from django.template.defaultfilters import filesizeformat from stage2.models import Attachment, Mark @@ -12,10 +11,13 @@ class AttachmentForm(forms.ModelForm): model = Attachment fields = ['file'] - def __init__(self, assignment, file_no, label, *args, **kwargs): + def __init__(self, assignment, file_no, label, extensions=None, *args, **kwargs): prefix = 'att%s-%s' % (assignment.id, file_no) super(AttachmentForm, self).__init__(*args, prefix=prefix, **kwargs) self.fields['file'].label = label + if extensions: + self.fields['file'].widget.attrs = {'data-ext': '|'.join(extensions)} + self.extensions = extensions def clean_file(self): file = self.cleaned_data['file'] @@ -23,6 +25,8 @@ class AttachmentForm(forms.ModelForm): raise forms.ValidationError( 'Please keep filesize under %s. Current filesize: %s' % ( filesizeformat(settings.MAX_UPLOAD_SIZE), filesizeformat(file.size))) + if self.extensions and ('.' not in file.name or file.name.rsplit('.', 1)[1].lower() not in self.extensions): + raise forms.ValidationError('Incorrect extension, should be one of: %s' % ', '.join(self.extensions)) return file @@ -42,7 +46,7 @@ class MarkForm(forms.ModelForm): def clean_points(self): points = self.cleaned_data['points'] if points > self.answer.assignment.max_points: - raise ValidationError('Too many points for this assignment') + raise forms.ValidationError('Too many points for this assignment') if points < 0: - raise ValidationError('Points cannot be negative') + raise forms.ValidationError('Points cannot be negative') return points diff --git a/stage2/models.py b/stage2/models.py index 1d4859f..38e0f19 100644 --- a/stage2/models.py +++ b/stage2/models.py @@ -65,7 +65,7 @@ class Assignment(models.Model): file_descriptions = JSONField(_('file descriptions')) class Meta: - ordering = ['deadline'] + ordering = ['deadline', 'title'] verbose_name = _('assignment') verbose_name_plural = _('assignments') diff --git a/stage2/static/js/checkfile.js b/stage2/static/js/checkfile.js new file mode 100644 index 0000000..f15c134 --- /dev/null +++ b/stage2/static/js/checkfile.js @@ -0,0 +1,25 @@ +$(function() { + "use strict"; + $('input[type=file]').on('change', function () { + if (window.FileReader && this.files && this.files[0]) { + var ok = true; + var name = this.files[0].name; + if (this.getAttribute('data-ext')) { + var ext = this.getAttribute('data-ext'); + var re = new RegExp('\\.(' + ext + ')$', 'i'); + if (!re.exec(name)) { + alert('Błędne rozszerzenie! Powinno być jedno z: ' + ext.replace(/\|/g, ', ')); + ok = false; + } + } + var size = this.files[0].size; + if (size > 10 * 1024 * 1024) { + alert('Rozmiar pliku nie może przekraczać 10 MB!'); + ok = false; + } + if (!ok) { + this.form.reset(); + } + } + }); +}); diff --git a/stage2/templates/stage2/participant.html b/stage2/templates/stage2/participant.html index fec4a49..f369bb4 100644 --- a/stage2/templates/stage2/participant.html +++ b/stage2/templates/stage2/participant.html @@ -1,11 +1,14 @@ {% extends 'base.html' %} {% load textile_pl from fnp_markup %} +{% load chunks %} {% block title %}Drugi etap{% endblock %} {% block body %}

Drugi etap Olimpiady Cyfrowej

+ {% chunk 'stage2_header' %} + {% for assignment in assignments %}

{{ assignment.title }} (do {{ assignment.deadline }})

{{ assignment.content|textile_pl }}

diff --git a/stage2/views.py b/stage2/views.py index 98e6dc7..c3e3eb7 100644 --- a/stage2/views.py +++ b/stage2/views.py @@ -16,9 +16,9 @@ def all_assignments(participant): for assignment in assignments: assignment.answer = assignment.answer_set.filter(participant=participant).first() assignment.forms = [ - (AttachmentForm(assignment=assignment, file_no=i, label=label), + (AttachmentForm(assignment=assignment, file_no=i, label=label, extensions=ext), assignment.answer.attachment_set.filter(file_no=i).first() if assignment.answer else None) - for i, label in enumerate(assignment.file_descriptions, 1)] + for i, (label, ext) in enumerate(assignment.file_descriptions, 1)] return assignments @@ -40,12 +40,12 @@ def upload(request, assignment_id, participant_id, key): now = timezone.now() if assignment.deadline < now: raise Http404 # TODO za późno - for i, label in enumerate(assignment.file_descriptions, 1): + for i, (label, ext) in enumerate(assignment.file_descriptions, 1): answer, created = Answer.objects.get_or_create(participant=participant, assignment=assignment) attachment, created = Attachment.objects.get_or_create(answer=answer, file_no=i) form = AttachmentForm( data=request.POST, files=request.FILES, - assignment=assignment, file_no=i, label=label, instance=attachment) + assignment=assignment, file_no=i, label=label, instance=attachment, extensions=ext) if form.is_valid(): form.save() return HttpResponseRedirect(reverse('stage2_participant', args=(participant_id, key))) @@ -95,7 +95,7 @@ def available_answers(assignment, expert, answer_with_errors=None, form_with_err attachments_by_file_no = {attachment.file_no: attachment for attachment in attachments} answer.attachments = [ (desc, attachments_by_file_no.get(i)) - for (i, desc) in enumerate(assignment.file_descriptions, 1)] + for (i, (desc, ext)) in enumerate(assignment.file_descriptions, 1)] if answer == answer_with_errors: answer.form = form_with_errors else: -- 2.20.1