mirror of
https://github.com/GSA/notifications-admin.git
synced 2025-12-14 09:03:33 -05:00
Add endpoint for generating an image of a letter
The PDF preview is all good, but it’s hard, finickeity and feels dirty to embed a PDF in a web page. It’s a more natural thing to embed an image in a web page. So this commit adds another endpoint to return an image of a letter template. It generates this image from the PDF preview, so the stack looks like: 1. `template.png` (generated in admin) 2. `template.pdf` (generated in admin) 3. HTML preview (generated by a `Renderer` in utils) 4. `Template` instance 5. serialised template from API 6. Template stored in database The library used to convert the PDF to an image is Wand[1], which binds to ImageMagick underneath. So in order to get this working locally on a Mac you will probably need to do: `brew install imagemagick ghostscript cairo pango`. To get it working on Ubuntu/EC2 is an exercise left to the reader… 1. http://docs.wand-py.org/en/0.4.4/
This commit is contained in:
@@ -25,7 +25,7 @@ Languages needed
|
|||||||
- [Node](https://nodejs.org/) 5.0.0 or greater
|
- [Node](https://nodejs.org/) 5.0.0 or greater
|
||||||
- [npm](https://www.npmjs.com/) 3.0.0 or greater
|
- [npm](https://www.npmjs.com/) 3.0.0 or greater
|
||||||
```shell
|
```shell
|
||||||
brew install node
|
brew install node imagemagick ghostscript cairo pango
|
||||||
```
|
```
|
||||||
|
|
||||||
[NPM](npmjs.org) is Node's package management tool. `n` is a tool for managing
|
[NPM](npmjs.org) is Node's package management tool. `n` is a tool for managing
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
$outline-width: 5px;
|
$outline-width: 5px;
|
||||||
|
|
||||||
.letter {
|
.letter {
|
||||||
|
|
||||||
font-family: Helvetica, Arial, sans-serif;
|
font-family: Helvetica, Arial, sans-serif;
|
||||||
box-shadow:
|
box-shadow:
|
||||||
1px 1px 0 0 $panel-colour,
|
1px 1px 0 0 $panel-colour,
|
||||||
@@ -8,6 +9,16 @@ $outline-width: 5px;
|
|||||||
-1px 1px 0 0 $panel-colour,
|
-1px 1px 0 0 $panel-colour,
|
||||||
-2px 2px 0 0 rgba($panel-colour, 0.5);
|
-2px 2px 0 0 rgba($panel-colour, 0.5);
|
||||||
outline: $outline-width solid rgba($text-colour, 0.1);
|
outline: $outline-width solid rgba($text-colour, 0.1);
|
||||||
padding: 20px;
|
padding: 0;
|
||||||
margin: $outline-width $outline-width $gutter;
|
margin: $outline-width $outline-width $gutter;
|
||||||
|
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from io import BytesIO
|
||||||
from string import ascii_uppercase
|
from string import ascii_uppercase
|
||||||
|
|
||||||
from flask import request, render_template, redirect, url_for, flash, abort
|
from flask import request, render_template, redirect, url_for, flash, abort, send_file
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
from flask_weasyprint import HTML, render_pdf
|
from flask_weasyprint import HTML, render_pdf
|
||||||
from dateutil.parser import parse
|
from dateutil.parser import parse
|
||||||
|
from wand.image import Image
|
||||||
|
|
||||||
from notifications_utils.template import Template
|
from notifications_utils.template import Template
|
||||||
from notifications_utils.recipients import first_column_headings
|
from notifications_utils.recipients import first_column_headings
|
||||||
@@ -64,6 +66,20 @@ def view_letter_template_as_pdf(service_id, template_id):
|
|||||||
return render_pdf(HTML(string=template.rendered))
|
return render_pdf(HTML(string=template.rendered))
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/services/<service_id>/templates/<template_id>.png")
|
||||||
|
@login_required
|
||||||
|
@user_has_permissions('view_activity', admin_override=True)
|
||||||
|
def view_letter_template_as_image(service_id, template_id):
|
||||||
|
output = BytesIO()
|
||||||
|
with Image(
|
||||||
|
blob=view_letter_template_as_pdf(service_id, template_id).get_data()
|
||||||
|
) as image:
|
||||||
|
with image.convert('png') as converted:
|
||||||
|
converted.save(file=output)
|
||||||
|
output.seek(0)
|
||||||
|
return send_file(output, mimetype='image/png')
|
||||||
|
|
||||||
|
|
||||||
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>")
|
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>")
|
||||||
@login_required
|
@login_required
|
||||||
@user_has_permissions(
|
@user_has_permissions(
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ RUN \
|
|||||||
zlib1g-dev \
|
zlib1g-dev \
|
||||||
libpango1.0-dev \
|
libpango1.0-dev \
|
||||||
libcairo2-dev \
|
libcairo2-dev \
|
||||||
|
libmagickwand-dev \
|
||||||
|
ghostscript \
|
||||||
|
|
||||||
&& echo "Install nodejs" \
|
&& echo "Install nodejs" \
|
||||||
&& cd /tmp \
|
&& cd /tmp \
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ pyexcel-xls==0.1.0
|
|||||||
pyexcel-xlsx==0.1.0
|
pyexcel-xlsx==0.1.0
|
||||||
pyexcel-ods3==0.1.1
|
pyexcel-ods3==0.1.1
|
||||||
pytz==2016.4
|
pytz==2016.4
|
||||||
|
wand==0.4.4
|
||||||
|
|
||||||
git+https://github.com/alphagov/notifications-python-client.git@3.0.1#egg=notifications-python-client==3.0.1
|
git+https://github.com/alphagov/notifications-python-client.git@3.0.1#egg=notifications-python-client==3.0.1
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ def test_should_show_page_for_one_template(
|
|||||||
'view, expected_content_type',
|
'view, expected_content_type',
|
||||||
[
|
[
|
||||||
('.view_letter_template_as_pdf', 'application/pdf'),
|
('.view_letter_template_as_pdf', 'application/pdf'),
|
||||||
|
('.view_letter_template_as_image', 'image/png'),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@patch("app.main.views.templates.LetterPreview.__call__")
|
@patch("app.main.views.templates.LetterPreview.__call__")
|
||||||
|
|||||||
Reference in New Issue
Block a user