check size and extension in js (and some minor improvements)
authorJan Szejko <janek37@gmail.com>
Thu, 5 Jan 2017 13:24:05 +0000 (14:24 +0100)
committerJan Szejko <janek37@gmail.com>
Thu, 5 Jan 2017 13:24:05 +0000 (14:24 +0100)
edumed/settings/static.py
edumed/templates/base_super.html
stage2/forms.py
stage2/models.py
stage2/static/js/checkfile.js [new file with mode: 0644]
stage2/templates/stage2/participant.html
stage2/views.py

index a2f2c05..98da70c 100644 (file)
@@ -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',
     },
index 8dbce4a..a4e93c1 100644 (file)
@@ -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 %}
-                <a href="{% url 'logout' subdomain=None %}" style="position: absolute; top:5px; right: 10px; font-size: 12px;">Wyloguj</a>
+                <a href="{% url 'logout' %}" style="position: absolute; top:5px; right: 10px; font-size: 12px;">Wyloguj</a>
             {% endif %}
             <div id="header-top">
             <a id="logo" href="/">{% block logo %}<img src="{% static "img/logo-oc.png" %}" alt="Olimpiada Cyfrowa" height="73"/>{% endblock %}</a>
index f7d248e..92af3a0 100644 (file)
@@ -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
index 1d4859f..38e0f19 100644 (file)
@@ -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 (file)
index 0000000..f15c134
--- /dev/null
@@ -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();
+            }
+        }
+    });
+});
index fec4a49..f369bb4 100644 (file)
@@ -1,11 +1,14 @@
 {% extends 'base.html' %}
 {% load textile_pl from fnp_markup %}
+{% load chunks %}
 
 {% block title %}Drugi etap{% endblock %}
 
 {% block body %}
   <h1>Drugi etap Olimpiady Cyfrowej</h1>
 
+  {% chunk 'stage2_header' %}
+
   {% for assignment in assignments %}
     <h2>{{ assignment.title }} (do {{ assignment.deadline }})</h2>
     <p>{{ assignment.content|textile_pl }}</p>
index 98e6dc7..c3e3eb7 100644 (file)
@@ -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: