mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-04-21 09:40:55 -04:00
This is better than just keying into the JSON because it means you get an exception straight away when looking up a key that doesn’t exist (which via mocking you could ordinarily miss).
194 lines
6.3 KiB
Python
194 lines
6.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
import base64
|
|
import io
|
|
import os
|
|
from datetime import datetime
|
|
|
|
from flask import (
|
|
Response,
|
|
abort,
|
|
current_app,
|
|
jsonify,
|
|
render_template,
|
|
request,
|
|
stream_with_context,
|
|
url_for,
|
|
)
|
|
from flask_login import login_required
|
|
from notifications_python_client.errors import APIError
|
|
from notifications_utils.pdf import pdf_page_count
|
|
|
|
from app import (
|
|
current_service,
|
|
format_date_numeric,
|
|
job_api_client,
|
|
notification_api_client,
|
|
)
|
|
from app.main import main
|
|
from app.template_previews import get_page_count_for_letter
|
|
from app.utils import (
|
|
DELIVERED_STATUSES,
|
|
FAILURE_STATUSES,
|
|
generate_notifications_csv,
|
|
get_help_argument,
|
|
get_letter_timings,
|
|
get_template,
|
|
get_time_left,
|
|
parse_filter_args,
|
|
set_status_filters,
|
|
user_has_permissions,
|
|
)
|
|
|
|
|
|
@main.route("/services/<service_id>/notification/<uuid:notification_id>")
|
|
@login_required
|
|
@user_has_permissions('view_activity', 'send_messages')
|
|
def view_notification(service_id, notification_id):
|
|
notification = notification_api_client.get_notification(service_id, str(notification_id))
|
|
notification['template'].update({'reply_to_text': notification['reply_to_text']})
|
|
|
|
if notification['template']['is_precompiled_letter']:
|
|
file_contents = view_letter_notification_as_preview(service_id, notification_id, "pdf")
|
|
page_count = pdf_page_count(io.BytesIO(file_contents))
|
|
else:
|
|
page_count = get_page_count_for_letter(notification['template'])
|
|
|
|
template = get_template(
|
|
notification['template'],
|
|
current_service,
|
|
letter_preview_url=url_for(
|
|
'.view_letter_notification_as_preview',
|
|
service_id=service_id,
|
|
notification_id=notification_id,
|
|
filetype='png',
|
|
),
|
|
page_count=page_count,
|
|
show_recipient=True,
|
|
redact_missing_personalisation=True,
|
|
)
|
|
template.values = get_all_personalisation_from_notification(notification)
|
|
if notification['job']:
|
|
job = job_api_client.get_job(service_id, notification['job']['id'])['data']
|
|
else:
|
|
job = None
|
|
|
|
return render_template(
|
|
'views/notifications/notification.html',
|
|
finished=(notification['status'] in (DELIVERED_STATUSES + FAILURE_STATUSES)),
|
|
uploaded_file_name='Report',
|
|
template=template,
|
|
job=job,
|
|
updates_url=url_for(
|
|
".view_notification_updates",
|
|
service_id=service_id,
|
|
notification_id=notification['id'],
|
|
status=request.args.get('status'),
|
|
help=get_help_argument()
|
|
),
|
|
partials=get_single_notification_partials(notification),
|
|
created_by=notification.get('created_by'),
|
|
created_at=notification['created_at'],
|
|
help=get_help_argument(),
|
|
estimated_letter_delivery_date=get_letter_timings(notification['created_at']).earliest_delivery,
|
|
notification_id=notification['id'],
|
|
can_receive_inbound=(current_service.has_permission('inbound_sms')),
|
|
is_precompiled_letter=notification['template']['is_precompiled_letter']
|
|
)
|
|
|
|
|
|
def get_preview_error_image():
|
|
path = os.path.join(os.path.dirname(__file__), "..", "..", "static", "images", "preview_error.png")
|
|
with open(path, "rb") as file:
|
|
return file.read()
|
|
|
|
|
|
@main.route("/services/<service_id>/notification/<uuid:notification_id>.<filetype>")
|
|
@login_required
|
|
@user_has_permissions('view_activity')
|
|
def view_letter_notification_as_preview(service_id, notification_id, filetype):
|
|
|
|
if filetype not in ('pdf', 'png'):
|
|
abort(404)
|
|
|
|
try:
|
|
preview = notification_api_client.get_notification_letter_preview(
|
|
service_id,
|
|
notification_id,
|
|
filetype,
|
|
page=request.args.get('page')
|
|
)
|
|
|
|
display_file = base64.b64decode(preview['content'])
|
|
except APIError:
|
|
display_file = get_preview_error_image()
|
|
|
|
return display_file
|
|
|
|
|
|
@main.route("/services/<service_id>/notification/<notification_id>.json")
|
|
@user_has_permissions('view_activity', 'send_messages')
|
|
def view_notification_updates(service_id, notification_id):
|
|
return jsonify(**get_single_notification_partials(
|
|
notification_api_client.get_notification(service_id, notification_id)
|
|
))
|
|
|
|
|
|
def get_single_notification_partials(notification):
|
|
return {
|
|
'notifications': render_template(
|
|
'partials/notifications/notifications.html',
|
|
notification=notification,
|
|
more_than_one_page=False,
|
|
percentage_complete=100,
|
|
time_left=get_time_left(notification['created_at']),
|
|
),
|
|
'status': render_template(
|
|
'partials/notifications/status.html',
|
|
notification=notification
|
|
),
|
|
}
|
|
|
|
|
|
def get_all_personalisation_from_notification(notification):
|
|
|
|
if notification['template'].get('redact_personalisation'):
|
|
notification['personalisation'] = {}
|
|
|
|
if notification['template']['template_type'] == 'email':
|
|
notification['personalisation']['email_address'] = notification['to']
|
|
|
|
if notification['template']['template_type'] == 'sms':
|
|
notification['personalisation']['phone_number'] = notification['to']
|
|
|
|
return notification['personalisation']
|
|
|
|
|
|
@main.route("/services/<service_id>/download-notifications.csv")
|
|
@login_required
|
|
@user_has_permissions('view_activity')
|
|
def download_notifications_csv(service_id):
|
|
filter_args = parse_filter_args(request.args)
|
|
filter_args['status'] = set_status_filters(filter_args)
|
|
|
|
return Response(
|
|
stream_with_context(
|
|
generate_notifications_csv(
|
|
service_id=service_id,
|
|
job_id=None,
|
|
status=filter_args.get('status'),
|
|
page=request.args.get('page', 1),
|
|
page_size=10000,
|
|
format_for_csv=True,
|
|
template_type=filter_args.get('message_type'),
|
|
limit_days=current_app.config['ACTIVITY_STATS_LIMIT_DAYS'],
|
|
)
|
|
),
|
|
mimetype='text/csv',
|
|
headers={
|
|
'Content-Disposition': 'inline; filename="{} - {} - {} report.csv"'.format(
|
|
format_date_numeric(datetime.now().strftime("%Y-%m-%dT%H:%M:%S.%fZ")),
|
|
filter_args['message_type'][0],
|
|
current_service.name)
|
|
}
|
|
)
|