diff --git a/edivorce/apps/core/templates/pdf/images_to_pdf.html b/edivorce/apps/core/templates/pdf/images_to_pdf.html
new file mode 100644
index 00000000..aaf9a707
--- /dev/null
+++ b/edivorce/apps/core/templates/pdf/images_to_pdf.html
@@ -0,0 +1,40 @@
+{% load static %}
+{% load format_utils %}
+
+
+
+
+
+
+
+ {{ form }}
+
+
+
+
+
+ {% include 'partials/gtm_head.html' %}
+
+
+
+
+
+
+ {% for image in images %}
+

+ {% if not forloop.last %}
+
+ {% endif %}
+ {% endfor %}
+
+
+
+
diff --git a/edivorce/apps/core/templatetags/format_utils.py b/edivorce/apps/core/templatetags/format_utils.py
index 3401dde2..ae6d422c 100644
--- a/edivorce/apps/core/templatetags/format_utils.py
+++ b/edivorce/apps/core/templatetags/format_utils.py
@@ -191,3 +191,19 @@ def agreed_child_support_amount(context, claimant_id, line_breaks=True):
return context.get('amount_income_over_high_income_limit_{}'.format(claimant_id), '')
else:
return linebreaksli(context.get('amount_income_over_high_income_limit_{}'.format(claimant_id), ''))
+
+
+@register.filter
+def css_rotate(image):
+ """ Gets extra CSS needed for image rotation when generating PDFs """
+ if image.rotation == 90 or image.rotation == 270:
+ height = image.width
+ width = image.height
+ else:
+ height = image.height
+ width = image.width
+
+ if width == 0 or height/width < 1.3:
+ return 'width: 100%'
+ else:
+ return 'height: 26.7cm'
diff --git a/edivorce/apps/core/urls.py b/edivorce/apps/core/urls.py
index 0deb0204..f37c1737 100644
--- a/edivorce/apps/core/urls.py
+++ b/edivorce/apps/core/urls.py
@@ -7,7 +7,7 @@ urlpatterns = [
# url(r'^guide$', styleguide.guide),
url(r'^api/response$', api.UserResponseHandler.as_view()),
url(r'^api/documents/$', api.DocumentCreateView.as_view(), name='documents'),
- path('api/documents//', api.get_document_file_by_key, name='file_by_key'),
+ path('api/documents///', api.get_document_file_by_key, name='document_by_key'),
# we add an extra 'x' to the file extension so the siteminder proxy doesn't treat it as an image
path('api/documents///x//', api.DocumentView.as_view(), name='document'),
@@ -32,6 +32,7 @@ urlpatterns = [
# url(r'^headers$', system.headers),
url(r'^pdf-form(?P[0-9]{1,3}(_we|_claimant1|_claimant2)?)$', pdf.form, name="pdf_form"),
+ path('pdf-images///', pdf.images_to_pdf, name='pdf_images'),
url(r'^prequalification/step_(?P[0-9]{2})$', main.prequalification, name="prequalification"),
url(r'^question/(?P.*)/(?P.*)/$', main.question, name="question_steps"),
url(r'^question/(?P.*)$', main.question, name="question_steps"),
diff --git a/edivorce/apps/core/views/api.py b/edivorce/apps/core/views/api.py
index eb397b49..a6a42108 100644
--- a/edivorce/apps/core/views/api.py
+++ b/edivorce/apps/core/views/api.py
@@ -5,6 +5,7 @@ from rest_framework import permissions, status
from rest_framework.generics import CreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView
from rest_framework.views import APIView
from rest_framework.response import Response
+from PIL import Image
from ..models import Document, Question
from ..serializer import CreateDocumentSerializer, DocumentMetadataSerializer, UserResponseSerializer
@@ -87,9 +88,44 @@ class DocumentView(RetrieveUpdateDestroyAPIView):
return HttpResponse(file_contents, content_type=content_type)
-def get_document_file_by_key(request, file_key):
+def get_document_file_by_key(request, file_key, rotation):
file = Document.get_file(file_key)
if not file:
return HttpResponseNotFound()
content_type = Document.content_type_from_filename(file.name)
- return HttpResponse(file, content_type=content_type)
+
+ # if it's a PDF or it doesn't require rotation
+ if content_type == 'application/pdf' or rotation == 0:
+ try:
+ return HttpResponse(file, content_type=content_type)
+ except TypeError:
+ raise Http404("File not found")
+
+ # if the file needs to be rotated
+ rot_img = __rotate_image(file, rotation)
+ extension = __get_file_extension(file)
+
+ try:
+ response = HttpResponse(content_type=content_type)
+ rot_img.save(response, extension)
+ return response
+ except TypeError:
+ raise Http404("File not found")
+
+
+def __get_file_extension(file):
+ extension = re.split(r'[\._]', file.name.upper())[-1]
+ if extension == "JPG" or extension == "JPE":
+ return "JPEG"
+ return extension
+
+
+def __rotate_image(file, rotation):
+ im = Image.open(file)
+
+ if rotation == 90:
+ return im.transpose(Image.ROTATE_270)
+ elif rotation == 270:
+ return im.transpose(Image.ROTATE_90)
+ else:
+ return im.transpose(Image.ROTATE_180)
diff --git a/edivorce/apps/core/views/pdf.py b/edivorce/apps/core/views/pdf.py
index 5d307203..00fc472e 100644
--- a/edivorce/apps/core/views/pdf.py
+++ b/edivorce/apps/core/views/pdf.py
@@ -9,6 +9,7 @@ from django.template.loader import render_to_string
import requests
from ..decorators import bceid_required
+from ..models import Document
from ..utils.derived import get_derived_data
from ..utils.user_response import get_data_for_user
@@ -66,8 +67,12 @@ def __render_form(request, form_name, context):
if output_as_html:
context['css_root'] = settings.FORCE_SCRIPT_NAME[:-1]
+ template_name = form_name
+ if not form_name.startswith('form'):
+ template_name = 'images_to_pdf'
+
# render to form as HTML
- rendered_html = render_to_string('pdf/' + form_name + '.html',
+ rendered_html = render_to_string('pdf/' + template_name + '.html',
context=context, request=request)
# if '?html' is in the querystring, then return the plain html
@@ -93,3 +98,30 @@ def __add_claimant_info(responses, claimant):
claimant_info[claimant_key] = responses[key]
responses.update(claimant_info)
return responses
+
+
+@bceid_required
+def images_to_pdf(request, doc_type, party_code):
+ documents = Document.objects.filter(
+ bceid_user=request.user, doc_type=doc_type, party_code=party_code)
+
+ if not documents:
+ return HttpResponse(status=204)
+
+ if party_code == 1:
+ form_name = doc_type + "_claimant1"
+ elif party_code == 2:
+ form_name = doc_type + "_claimant2"
+ else:
+ form_name = doc_type
+
+ if documents[0].filename.endswith(('.pdf', '.PDF')):
+ response = HttpResponse(documents[0].file.read(), content_type='application/pdf')
+ response['Content-Disposition'] = 'inline;filename=' + form_name + '.pdf'
+ return response
+
+ return __render_form(request, form_name, {
+ 'css_root': settings.WEASYPRINT_CSS_LOOPBACK,
+ 'images': documents,
+ 'form': form_name
+ })
diff --git a/requirements.txt b/requirements.txt
index 936bc4af..31d972b5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -19,6 +19,7 @@ gunicorn==20.0.4
idna==2.10
libsass==0.20.0
marshmallow==3.7.1
+Pillow==7.2.0
promise==2.3
psycopg2==2.8.5
python-dotenv==0.14.0
diff --git a/vue/src/components/Uploader/Uploader.vue b/vue/src/components/Uploader/Uploader.vue
index 15ed3967..c1a54d8c 100644
--- a/vue/src/components/Uploader/Uploader.vue
+++ b/vue/src/components/Uploader/Uploader.vue
@@ -98,6 +98,9 @@
(Maximum {{ maxMegabytes }} MB)
+
+ {{ pdfURL }}
+
{{ warningText }}