Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions course/page/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
"""


from mimetypes import add_type, guess_extension

import django.forms as forms
from crispy_forms.layout import Field, Layout
from django.utils.translation import gettext as _, gettext_lazy
Expand All @@ -39,6 +41,9 @@
from relate.utils import StyledForm, string_concat


add_type("application/x-ipynb+json", ".ipynb")


# {{{ upload question

class FileUploadForm(StyledForm):
Expand Down Expand Up @@ -76,9 +81,22 @@ def clean_uploaded_file(self):
% {"allowedsize": filesizeformat(self.max_file_size),
"uploadedsize": filesizeformat(uploaded_file.size)})

if self.mime_types is not None and self.mime_types == ["application/pdf"]:
if uploaded_file.read()[:4] != b"%PDF":
raise forms.ValidationError(_("Uploaded file is not a PDF."))
if self.mime_types is not None:
if self.mime_types == ["application/pdf"]:
if uploaded_file.read()[:4] != b"%PDF":
raise forms.ValidationError(_("Uploaded file is not a PDF."))
elif self.mime_types == ["application/x-ipynb+json"]:
try:
# make sure it is loadable json
import json
data = json.load(uploaded_file)

# check for a notebook format of at least 4
if int(data["nbformat"]) < 4:
raise ValueError(_("Invalid notebook format."))
except Exception:
raise forms.ValidationError(_("Uploaded file is not a "
"Jupyter notebook."))

return uploaded_file

Expand Down Expand Up @@ -132,6 +150,7 @@ class FileUploadQuestion(PageBaseWithTitle, PageBaseWithValue,
* ``application/pdf`` (will check for a PDF header)
* ``text/plain`` (no check performed)
* ``application/octet-stream`` (no check performed)
* ``application/x-ipynb+json`` (will check for JSON and nbformat>=4)

.. attribute:: maximum_megabytes

Expand All @@ -156,6 +175,7 @@ class FileUploadQuestion(PageBaseWithTitle, PageBaseWithValue,
"application/pdf",
"text/plain",
"application/octet-stream",
"application/x-ipynb+json",
]

def __init__(self, vctx, location, page_desc):
Expand Down Expand Up @@ -205,7 +225,6 @@ def body(self, page_context, page_data):
return markup_to_html(page_context, self.page_desc.prompt)

def get_submission_filename_pattern(self, page_context, mime_type):
from mimetypes import guess_extension
if mime_type is not None:
ext = guess_extension(mime_type)
else:
Expand Down Expand Up @@ -295,8 +314,6 @@ def normalized_bytes_answer(self, page_context, page_data, answer_data):
return None

subm_data, subm_mime = self.get_content_from_answer_data(answer_data)

from mimetypes import guess_extension
ext = guess_extension(subm_mime)

if ext is None:
Expand Down
1 change: 1 addition & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,7 @@ def test_content_type(self):
("images/django-logo.png", "image/png"),
("images/classroom.jpeg", "image/jpeg"),
("pdfs/sample.pdf", "application/pdf"),
("ipynbs/Ipynb_example.ipynb", "application/x-ipynb+json"),
)
for repo_file, content_type in tup:
with self.subTest(repo_file=repo_file):
Expand Down