Rewrite PDF responses memory-based
This commit is contained in:
parent
067f6f96ac
commit
bfb5609c9a
4 changed files with 45 additions and 45 deletions
|
|
@ -1,5 +1,3 @@
|
|||
import os
|
||||
import tempfile
|
||||
from datetime import date
|
||||
|
||||
from django.conf import settings
|
||||
|
|
@ -50,10 +48,9 @@ class HorLine(Flowable):
|
|||
class EpcBaseDocTemplate(SimpleDocTemplate):
|
||||
points = '.' * 93
|
||||
|
||||
def __init__(self, filename, title=''):
|
||||
path = os.path.join(tempfile.gettempdir(), filename)
|
||||
def __init__(self, filelike, title=''):
|
||||
super().__init__(
|
||||
path,
|
||||
filelike,
|
||||
pagesize=A4,
|
||||
lefMargin=2.5 * cm, bottomMargin=1 * cm, topMargin=1 * cm, rightMargin=2.5 * cm
|
||||
)
|
||||
|
|
@ -117,10 +114,9 @@ class ChargeSheetPDF(EpcBaseDocTemplate):
|
|||
"""
|
||||
Génération des feuilles de charges en pdf.
|
||||
"""
|
||||
def __init__(self, teacher):
|
||||
def __init__(self, out, teacher):
|
||||
self.teacher = teacher
|
||||
filename = slugify('{0}_{1}'.format(teacher.last_name, teacher.first_name)) + '.pdf'
|
||||
super().__init__(filename)
|
||||
super().__init__(out)
|
||||
self.addPageTemplates([
|
||||
PageTemplate(id='FirstPage', frames=[self.page_frame], onPage=self.header)
|
||||
])
|
||||
|
|
@ -185,8 +181,8 @@ class UpdateDataFormPDF(EpcBaseDocTemplate):
|
|||
"""
|
||||
Génération des formulaires PDF de mise à jour des données.
|
||||
"""
|
||||
def __init__(self, filename, return_date):
|
||||
super().__init__(filename)
|
||||
def __init__(self, out, return_date):
|
||||
super().__init__(out)
|
||||
self.text = (
|
||||
"Afin de mettre à jour nos bases de données, nous vous serions reconnaissant "
|
||||
"de contrôler les données ci-dessous qui vous concernent selon votre filière "
|
||||
|
|
@ -415,12 +411,9 @@ class CompensationForm:
|
|||
|
||||
|
||||
class ExpertEdeLetterPdf(CompensationForm, EpcBaseDocTemplate):
|
||||
def __init__(self, student):
|
||||
def __init__(self, out, student):
|
||||
self.student = student
|
||||
filename = slugify(
|
||||
'{0}_{1}'.format(self.student.last_name, self.student.first_name)
|
||||
) + '_Expert.pdf'
|
||||
super().__init__(filename)
|
||||
super().__init__(out)
|
||||
self.addPageTemplates([
|
||||
PageTemplate(id='FirstPage', frames=[self.page_frame], onPage=self.header),
|
||||
PageTemplate(id='ISOPage', frames=[self.page_frame], onPage=self.header_iso),
|
||||
|
|
@ -501,12 +494,9 @@ class ExpertEdeLetterPdf(CompensationForm, EpcBaseDocTemplate):
|
|||
|
||||
|
||||
class MentorCompensationPdfForm(CompensationForm, EpcBaseDocTemplate):
|
||||
def __init__(self, student):
|
||||
def __init__(self, out, student):
|
||||
self.student = student
|
||||
filename = slugify(
|
||||
'{0}_{1}'.format(self.student.last_name, self.student.first_name)
|
||||
) + '_Indemn_mentor.pdf'
|
||||
super().__init__(filename)
|
||||
super().__init__(out)
|
||||
self.addPageTemplates([
|
||||
PageTemplate(id='FirstPage', frames=[self.page_frame], onPage=self.header_iso)
|
||||
])
|
||||
|
|
@ -533,10 +523,9 @@ class KlassListPDF(EpcBaseDocTemplate):
|
|||
"""
|
||||
Génération des rôles de classes en pdf.
|
||||
"""
|
||||
def __init__(self, klass):
|
||||
def __init__(self, out, klass):
|
||||
self.klass = klass
|
||||
filename = slugify('{0}'.format(klass.name)) + '.pdf'
|
||||
super().__init__(filename)
|
||||
super().__init__(out)
|
||||
|
||||
self.addPageTemplates([
|
||||
PageTemplate(id='FirstPage', frames=[self.page_frame], onPage=self.header),
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ tél. 032 886 33 00
|
|||
'attachment; filename="dupond_albin_Expert.pdf"'
|
||||
)
|
||||
self.assertEqual(response['Content-Type'], 'application/pdf')
|
||||
self.assertGreater(len(response.content), 200)
|
||||
self.assertGreater(int(response['Content-Length']), 1000)
|
||||
# Expert without corporation
|
||||
st.expert = CorpContact.objects.create(first_name='James', last_name='Bond')
|
||||
st.save()
|
||||
|
|
@ -361,7 +361,7 @@ tél. 032 886 33 00
|
|||
'attachment; filename="dupond_albin_Indemn_mentor.pdf"'
|
||||
)
|
||||
self.assertEqual(response['Content-Type'], 'application/pdf')
|
||||
self.assertGreater(len(response.content), 200)
|
||||
self.assertGreater(int(response['Content-Length']), 1000)
|
||||
|
||||
def test_EDEpe_klass(self):
|
||||
lev3 = Level.objects.create(name='3')
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import io
|
||||
import json
|
||||
import os
|
||||
|
||||
|
|
@ -8,7 +9,7 @@ from django.contrib import messages
|
|||
from django.contrib.auth.mixins import PermissionRequiredMixin
|
||||
from django.core.mail import EmailMessage
|
||||
from django.db.models import Count
|
||||
from django.http import HttpResponse, HttpResponseNotAllowed, HttpResponseRedirect
|
||||
from django.http import FileResponse, HttpResponse, HttpResponseNotAllowed, HttpResponseRedirect
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.template import loader
|
||||
from django.urls import reverse, reverse_lazy
|
||||
|
|
@ -536,9 +537,10 @@ class PrintUpdateForm(ZippedFilesBaseView):
|
|||
def generate_files(self):
|
||||
for klass in Klass.objects.filter(level__gte=2
|
||||
).exclude(section__name='MP_ASSC').exclude(section__name='MP_ASE'):
|
||||
pdf = UpdateDataFormPDF('{0}.pdf'.format(klass.name), self.return_date)
|
||||
buff = io.BytesIO()
|
||||
pdf = UpdateDataFormPDF(buff, self.return_date)
|
||||
pdf.produce(klass)
|
||||
yield pdf.filename
|
||||
yield ('{0}.pdf'.format(klass.name), buff.getvalue())
|
||||
|
||||
|
||||
def print_expert_ede_compensation_form(request, pk):
|
||||
|
|
@ -554,13 +556,14 @@ def print_expert_ede_compensation_form(request, pk):
|
|||
+ missing
|
||||
))
|
||||
return redirect(reverse("admin:stages_student_change", args=(student.pk,)))
|
||||
pdf = ExpertEdeLetterPdf(student)
|
||||
buff = io.BytesIO()
|
||||
pdf = ExpertEdeLetterPdf(buff, student)
|
||||
pdf.produce()
|
||||
|
||||
with open(pdf.filename, mode='rb') as fh:
|
||||
response = HttpResponse(fh.read(), content_type='application/pdf')
|
||||
response['Content-Disposition'] = 'attachment; filename="{0}"'.format(os.path.basename(pdf.filename))
|
||||
return response
|
||||
filename = slugify(
|
||||
'{0}_{1}'.format(student.last_name, student.first_name)
|
||||
) + '_Expert.pdf'
|
||||
buff.seek(0)
|
||||
return FileResponse(buff, as_attachment=True, filename=filename)
|
||||
|
||||
|
||||
def print_mentor_ede_compensation_form(request, pk):
|
||||
|
|
@ -571,13 +574,16 @@ def print_mentor_ede_compensation_form(request, pk):
|
|||
if not student.mentor:
|
||||
messages.error(request, "Aucun mentor n'est attribué à cet étudiant")
|
||||
return redirect(reverse("admin:stages_student_change", args=(student.pk,)))
|
||||
pdf = MentorCompensationPdfForm(student)
|
||||
buff = io.BytesIO()
|
||||
pdf = MentorCompensationPdfForm(buff, student)
|
||||
pdf.produce()
|
||||
filename = slugify(
|
||||
'{0}_{1}'.format(student.last_name, student.first_name)
|
||||
) + '_Indemn_mentor.pdf'
|
||||
buff.seek(0)
|
||||
return FileResponse(buff, as_attachment=True, filename=filename)
|
||||
|
||||
|
||||
with open(pdf.filename, mode='rb') as fh:
|
||||
response = HttpResponse(fh.read(), content_type='application/pdf')
|
||||
response['Content-Disposition'] = 'attachment; filename="{0}"'.format(os.path.basename(pdf.filename))
|
||||
return response
|
||||
|
||||
|
||||
class PrintKlassList(ZippedFilesBaseView):
|
||||
|
|
@ -585,9 +591,11 @@ class PrintKlassList(ZippedFilesBaseView):
|
|||
|
||||
def generate_files(self):
|
||||
for klass in Klass.active.order_by('section', 'name'):
|
||||
pdf = KlassListPDF(klass)
|
||||
buff = io.BytesIO()
|
||||
pdf = KlassListPDF(buff, klass)
|
||||
pdf.produce(klass)
|
||||
yield pdf.filename
|
||||
filename = slugify('{0}.pdf'.format(klass.name))
|
||||
yield (filename, buff.getvalue())
|
||||
|
||||
|
||||
class PrintChargeSheet(ZippedFilesBaseView):
|
||||
|
|
@ -601,6 +609,8 @@ class PrintChargeSheet(ZippedFilesBaseView):
|
|||
queryset = Teacher.objects.filter(pk__in=self.request.GET.get('ids').split(','))
|
||||
for teacher in queryset:
|
||||
activities = teacher.calc_activity()
|
||||
pdf = ChargeSheetPDF(teacher)
|
||||
buff = io.BytesIO()
|
||||
pdf = ChargeSheetPDF(buff, teacher)
|
||||
pdf.produce(activities)
|
||||
yield pdf.filename
|
||||
filename = slugify('{0}_{1}.pdf'.format(teacher.last_name, teacher.first_name))
|
||||
yield (filename, buff.getvalue())
|
||||
|
|
|
|||
|
|
@ -56,13 +56,14 @@ class ZippedFilesBaseView(View):
|
|||
filename = 'to_be_defined.zip'
|
||||
|
||||
def generate_files(self):
|
||||
"""Generator yielding (file_name, file_data) tuples."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
tmp_file = tempfile.NamedTemporaryFile()
|
||||
with zipfile.ZipFile(tmp_file, mode='w', compression=zipfile.ZIP_DEFLATED) as filezip:
|
||||
for file_name in self.generate_files():
|
||||
filezip.write(file_name, arcname=os.path.basename(file_name))
|
||||
for file_name, file_data in self.generate_files():
|
||||
filezip.writestr(file_name, file_data)
|
||||
|
||||
with open(filezip.filename, mode='rb') as fh:
|
||||
response = HttpResponse(fh.read(), content_type='application/zip')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue