fix: better handle "entered" agendas (#7721)
* fix: don't assume file has open method The open method is specific to Django's uploaded file classes, where it just calls seek(0) * refactor: better upload/enter agenda abstraction
This commit is contained in:
parent
7d6d7e1c44
commit
4b912d55a5
|
@ -727,7 +727,7 @@ def save_session_minutes_revision(session, file, ext, request, encoding=None, ap
|
||||||
def handle_upload_file(file, filename, meeting, subdir, request=None, encoding=None):
|
def handle_upload_file(file, filename, meeting, subdir, request=None, encoding=None):
|
||||||
"""Accept an uploaded materials file
|
"""Accept an uploaded materials file
|
||||||
|
|
||||||
This function takes a file object, a filename and a meeting object and subdir as string.
|
This function takes a _binary mode_ file object, a filename and a meeting object and subdir as string.
|
||||||
It saves the file to the appropriate directory, get_materials_path() + subdir.
|
It saves the file to the appropriate directory, get_materials_path() + subdir.
|
||||||
If the file is a zip file, it creates a new directory in 'slides', which is the basename of the
|
If the file is a zip file, it creates a new directory in 'slides', which is the basename of the
|
||||||
zip file and unzips the file in the new directory.
|
zip file and unzips the file in the new directory.
|
||||||
|
@ -749,9 +749,18 @@ def handle_upload_file(file, filename, meeting, subdir, request=None, encoding=N
|
||||||
pass # if the file is already gone, so be it
|
pass # if the file is already gone, so be it
|
||||||
|
|
||||||
with (path / filename).open('wb+') as destination:
|
with (path / filename).open('wb+') as destination:
|
||||||
|
# prep file for reading
|
||||||
|
if hasattr(file, "chunks"):
|
||||||
|
chunks = file.chunks()
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
file.seek(0)
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
chunks = [file.read()] # pretend we have chunks
|
||||||
|
|
||||||
if filename.suffix in settings.MEETING_VALID_MIME_TYPE_EXTENSIONS['text/html']:
|
if filename.suffix in settings.MEETING_VALID_MIME_TYPE_EXTENSIONS['text/html']:
|
||||||
file.open()
|
text = b"".join(chunks)
|
||||||
text = file.read()
|
|
||||||
if encoding:
|
if encoding:
|
||||||
try:
|
try:
|
||||||
text = text.decode(encoding)
|
text = text.decode(encoding)
|
||||||
|
@ -778,11 +787,8 @@ def handle_upload_file(file, filename, meeting, subdir, request=None, encoding=N
|
||||||
f"please check the resulting content. "
|
f"please check the resulting content. "
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
if hasattr(file, 'chunks'):
|
for chunk in chunks:
|
||||||
for chunk in file.chunks():
|
destination.write(chunk)
|
||||||
destination.write(chunk)
|
|
||||||
else:
|
|
||||||
destination.write(file.read())
|
|
||||||
|
|
||||||
# unzip zipfile
|
# unzip zipfile
|
||||||
if is_zipfile:
|
if is_zipfile:
|
||||||
|
|
|
@ -33,6 +33,7 @@ from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.core.validators import URLValidator
|
from django.core.validators import URLValidator
|
||||||
from django.urls import reverse,reverse_lazy
|
from django.urls import reverse,reverse_lazy
|
||||||
from django.db.models import F, Max, Q
|
from django.db.models import F, Max, Q
|
||||||
|
@ -2795,6 +2796,17 @@ class UploadOrEnterAgendaForm(UploadAgendaForm):
|
||||||
elif submission_method == "enter":
|
elif submission_method == "enter":
|
||||||
require_field("content")
|
require_field("content")
|
||||||
|
|
||||||
|
def get_file(self):
|
||||||
|
"""Get content as a file-like object"""
|
||||||
|
if self.cleaned_data.get("submission_method") == "upload":
|
||||||
|
return self.cleaned_data["file"]
|
||||||
|
else:
|
||||||
|
return SimpleUploadedFile(
|
||||||
|
name="uploaded.md",
|
||||||
|
content=self.cleaned_data["content"].encode("utf-8"),
|
||||||
|
content_type="text/markdown;charset=utf-8",
|
||||||
|
)
|
||||||
|
|
||||||
def upload_session_agenda(request, session_id, num):
|
def upload_session_agenda(request, session_id, num):
|
||||||
# num is redundant, but we're dragging it along an artifact of where we are in the current URL structure
|
# num is redundant, but we're dragging it along an artifact of where we are in the current URL structure
|
||||||
session = get_object_or_404(Session,pk=session_id)
|
session = get_object_or_404(Session,pk=session_id)
|
||||||
|
@ -2815,21 +2827,8 @@ def upload_session_agenda(request, session_id, num):
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = UploadOrEnterAgendaForm(show_apply_to_all_checkbox,request.POST,request.FILES)
|
form = UploadOrEnterAgendaForm(show_apply_to_all_checkbox,request.POST,request.FILES)
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
submission_method = form.cleaned_data['submission_method']
|
file = form.get_file()
|
||||||
if submission_method == "upload":
|
_, ext = os.path.splitext(file.name)
|
||||||
file = request.FILES['file']
|
|
||||||
_, ext = os.path.splitext(file.name)
|
|
||||||
else:
|
|
||||||
if agenda_sp:
|
|
||||||
doc = agenda_sp.document
|
|
||||||
_, ext = os.path.splitext(doc.uploaded_filename)
|
|
||||||
else:
|
|
||||||
ext = ".md"
|
|
||||||
fd, name = tempfile.mkstemp(suffix=ext, text=True)
|
|
||||||
os.close(fd)
|
|
||||||
with open(name, "w") as file:
|
|
||||||
file.write(form.cleaned_data['content'])
|
|
||||||
file = open(name, "rb")
|
|
||||||
apply_to_all = session.type.slug == 'regular'
|
apply_to_all = session.type.slug == 'regular'
|
||||||
if show_apply_to_all_checkbox:
|
if show_apply_to_all_checkbox:
|
||||||
apply_to_all = form.cleaned_data['apply_to_all']
|
apply_to_all = form.cleaned_data['apply_to_all']
|
||||||
|
|
Loading…
Reference in a new issue