Add an endpoint for generating a PDF of a letter

Previewing a letter is different to previewing an email or text message
because:

- a letter has a layout
- the layout is fixed, ie it doesn’t depend on the user’s device
- the ‘send yourself a test’ feature won’t be as useful because it has
  a lead time, so the feedback loop will be much longer

For these reasons a HTML-only preview of the letter won’t be enough (we
don’t think). A PDF is more appropriate because:

- it can replicate the layout of the letter exactly
- it is a print format, so the user could even print themselves a copy
  locally to get a feel for how it will look

This commit makes use of Flask WeasyPrint [1] to take a HTML
representation of the letter, convert it to a PDF and serve it back to
the user.

The actual work to generate the HTML and specify the layout is done in
utils, same as we do for rendering other messages.

1. https://pythonhosted.org/Flask-WeasyPrint/
This commit is contained in:
Chris Hill-Scott
2016-11-27 18:10:18 +00:00
parent 4f72cc20ef
commit d0f90eac7e
3 changed files with 55 additions and 1 deletions

View File

@@ -3,10 +3,12 @@ from string import ascii_uppercase
from flask import request, render_template, redirect, url_for, flash, abort
from flask_login import login_required
from flask_weasyprint import HTML, render_pdf
from dateutil.parser import parse
from notifications_utils.template import Template
from notifications_utils.recipients import first_column_headings
from notifications_utils.renderers import LetterPreview
from notifications_python_client.errors import HTTPError
from app.main import main
@@ -51,6 +53,17 @@ def view_template(service_id, template_id):
)
@main.route("/services/<service_id>/templates/<template_id>.pdf")
@login_required
@user_has_permissions('view_activity', admin_override=True)
def view_letter_template_as_pdf(service_id, template_id):
template = Template(
service_api_client.get_service_template(service_id, template_id)['data'],
renderer=LetterPreview()
)
return render_pdf(HTML(string=template.rendered))
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>")
@login_required
@user_has_permissions(