mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-03-10 21:32:25 -04:00
Utils is better structured to handle the logic of what thing to show for what template type, especially now that what we show for different template types in different contexts has diverged significantly. See https://github.com/alphagov/notifications-utils/commit/6b39c1a for an example of this code moving into utils Depends on and implements: https://github.com/alphagov/notifications-utils/pull/84 The main reason for doing this is to get Paul’s fix for the misaligned CSV columns: https://github.com/alphagov/notifications-utils/pull/87
277 lines
9.4 KiB
Python
277 lines
9.4 KiB
Python
from datetime import datetime, timedelta
|
|
from string import ascii_uppercase
|
|
|
|
from flask import request, render_template, redirect, url_for, flash, abort
|
|
from flask_login import login_required
|
|
from dateutil.parser import parse
|
|
|
|
from notifications_utils.template import Template
|
|
from notifications_utils.recipients import first_column_headings
|
|
from notifications_python_client.errors import HTTPError
|
|
|
|
from app.main import main
|
|
from app.utils import user_has_permissions, get_renderer
|
|
from app.main.forms import SMSTemplateForm, EmailTemplateForm, LetterTemplateForm
|
|
from app.main.views.send import get_example_csv_rows
|
|
from app import service_api_client, current_service, template_statistics_client
|
|
|
|
|
|
form_objects = {
|
|
'email': EmailTemplateForm,
|
|
'sms': SMSTemplateForm,
|
|
'letter': LetterTemplateForm
|
|
}
|
|
|
|
page_headings = {
|
|
'email': 'email',
|
|
'sms': 'text message'
|
|
}
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>")
|
|
@login_required
|
|
@user_has_permissions(
|
|
'view_activity',
|
|
'send_texts',
|
|
'send_emails',
|
|
'manage_templates',
|
|
'manage_api_keys',
|
|
admin_override=True, any_=True
|
|
)
|
|
def view_template(service_id, template_id):
|
|
template = Template(
|
|
service_api_client.get_service_template(service_id, template_id)['data']
|
|
)
|
|
template.renderer = get_renderer(
|
|
template.template_type, current_service, show_recipient=False, expand_emails=True
|
|
)
|
|
return render_template(
|
|
'views/templates/template.html',
|
|
template=template
|
|
)
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/version/<int:version>")
|
|
@login_required
|
|
@user_has_permissions(
|
|
'view_activity',
|
|
'send_texts',
|
|
'send_emails',
|
|
'manage_templates',
|
|
'manage_api_keys',
|
|
admin_override=True,
|
|
any_=True
|
|
)
|
|
def view_template_version(service_id, template_id, version):
|
|
template = Template(
|
|
service_api_client.get_service_template(service_id, template_id, version)['data']
|
|
)
|
|
template.renderer = get_renderer(
|
|
template.template_type, current_service, show_recipient=False, expand_emails=True
|
|
)
|
|
return render_template(
|
|
'views/templates/template_history.html',
|
|
template=template
|
|
)
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/add-<template_type>", methods=['GET', 'POST'])
|
|
@login_required
|
|
@user_has_permissions('manage_templates', admin_override=True)
|
|
def add_service_template(service_id, template_type):
|
|
if template_type not in ['sms', 'email', 'letter']:
|
|
abort(404)
|
|
if not current_service['can_send_letters'] and template_type == 'letter':
|
|
abort(403)
|
|
|
|
form = form_objects[template_type]()
|
|
if form.validate_on_submit():
|
|
try:
|
|
service_api_client.create_service_template(
|
|
form.name.data,
|
|
template_type,
|
|
form.template_content.data,
|
|
service_id,
|
|
form.subject.data if hasattr(form, 'subject') else None
|
|
)
|
|
except HTTPError as e:
|
|
if e.status_code == 400:
|
|
if 'content' in e.message and any(['character count greater than' in x for x in e.message['content']]):
|
|
form.template_content.errors.extend(e.message['content'])
|
|
else:
|
|
raise e
|
|
else:
|
|
raise e
|
|
else:
|
|
return redirect(
|
|
url_for('.choose_template', service_id=service_id, template_type=template_type)
|
|
)
|
|
|
|
return render_template(
|
|
'views/edit-{}-template.html'.format(template_type),
|
|
form=form,
|
|
template_type=template_type,
|
|
heading_action='Add'
|
|
)
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/edit", methods=['GET', 'POST'])
|
|
@login_required
|
|
@user_has_permissions('manage_templates', admin_override=True)
|
|
def edit_service_template(service_id, template_id):
|
|
template = service_api_client.get_service_template(service_id, template_id)['data']
|
|
template['template_content'] = template['content']
|
|
form = form_objects[template['template_type']](**template)
|
|
|
|
if form.validate_on_submit():
|
|
subject = form.subject.data if hasattr(form, 'subject') else None
|
|
new_template = Template({
|
|
'name': form.name.data,
|
|
'content': form.template_content.data,
|
|
'subject': subject,
|
|
'template_type': template['template_type'],
|
|
'id': template['id']
|
|
})
|
|
template_change = Template(template).compare_to(new_template)
|
|
if template_change.has_different_placeholders and not request.form.get('confirm'):
|
|
return render_template(
|
|
'views/templates/breaking-change.html',
|
|
template_change=template_change,
|
|
new_template=new_template,
|
|
column_headings=list(ascii_uppercase[:len(new_template.placeholders) + 1]),
|
|
example_rows=[
|
|
first_column_headings[new_template.template_type] + list(new_template.placeholders),
|
|
get_example_csv_rows(new_template),
|
|
get_example_csv_rows(new_template)
|
|
],
|
|
form=form
|
|
)
|
|
try:
|
|
service_api_client.update_service_template(
|
|
template_id,
|
|
form.name.data,
|
|
template['template_type'],
|
|
form.template_content.data,
|
|
service_id,
|
|
subject
|
|
)
|
|
except HTTPError as e:
|
|
if e.status_code == 400:
|
|
if 'content' in e.message and any(['character count greater than' in x for x in e.message['content']]):
|
|
form.template_content.errors.extend(e.message['content'])
|
|
else:
|
|
raise e
|
|
else:
|
|
raise e
|
|
else:
|
|
return redirect(url_for(
|
|
'.view_template',
|
|
service_id=service_id,
|
|
template_id=template_id
|
|
))
|
|
return render_template(
|
|
'views/edit-{}-template.html'.format(template['template_type']),
|
|
form=form,
|
|
template_id=template_id,
|
|
template_type=template['template_type'],
|
|
heading_action='Edit'
|
|
)
|
|
|
|
|
|
@main.route("/services/<service_id>/templates/<template_id>/delete", methods=['GET', 'POST'])
|
|
@login_required
|
|
@user_has_permissions('manage_templates', admin_override=True)
|
|
def delete_service_template(service_id, template_id):
|
|
template = service_api_client.get_service_template(service_id, template_id)['data']
|
|
|
|
if request.method == 'POST':
|
|
service_api_client.delete_service_template(service_id, template_id)
|
|
return redirect(url_for(
|
|
'.choose_template',
|
|
service_id=service_id,
|
|
template_type=template['template_type']
|
|
))
|
|
|
|
template['template_content'] = template['content']
|
|
form = form_objects[template['template_type']](**template)
|
|
|
|
try:
|
|
last_used_notification = template_statistics_client.get_template_statistics_for_template(
|
|
service_id, template['id']
|
|
)
|
|
message = '{} was last used {} ago'.format(
|
|
last_used_notification['template']['name'],
|
|
get_human_readable_delta(
|
|
parse(last_used_notification['created_at']).replace(tzinfo=None),
|
|
datetime.utcnow())
|
|
)
|
|
except HTTPError as e:
|
|
if e.status_code == 404:
|
|
message = '{} has never been used'.format(template['name'])
|
|
else:
|
|
raise e
|
|
|
|
flash('{}. Are you sure you want to delete it?'.format(message), 'delete')
|
|
return render_template(
|
|
'views/edit-{}-template.html'.format(template['template_type']),
|
|
h1='Edit template',
|
|
form=form,
|
|
template_id=template_id)
|
|
|
|
|
|
@main.route('/services/<service_id>/templates/<template_id>/versions')
|
|
@login_required
|
|
@user_has_permissions(
|
|
'view_activity',
|
|
'send_texts',
|
|
'send_emails',
|
|
'manage_templates',
|
|
'manage_api_keys',
|
|
admin_override=True,
|
|
any_=True
|
|
)
|
|
def view_template_versions(service_id, template_id):
|
|
|
|
versions = []
|
|
for template in service_api_client.get_service_template_versions(service_id, template_id)['data']:
|
|
template = Template(template)
|
|
template.renderer = get_renderer(
|
|
template.template_type, current_service, show_recipient=False, expand_emails=True
|
|
)
|
|
versions.append(template)
|
|
|
|
return render_template(
|
|
'views/templates/choose_history.html',
|
|
versions=versions
|
|
)
|
|
|
|
|
|
def get_last_use_message(template_name, template_statistics):
|
|
try:
|
|
most_recent_use = max(
|
|
parse(template_stats['updated_at']).replace(tzinfo=None)
|
|
for template_stats in template_statistics
|
|
)
|
|
except ValueError:
|
|
return '{} has never been used'.format(template_name)
|
|
|
|
return '{} was last used {} ago'.format(
|
|
template_name,
|
|
get_human_readable_delta(most_recent_use, datetime.utcnow())
|
|
)
|
|
|
|
|
|
def get_human_readable_delta(from_time, until_time):
|
|
delta = until_time - from_time
|
|
if delta < timedelta(seconds=60):
|
|
return 'under a minute'
|
|
elif delta < timedelta(hours=1):
|
|
minutes = int(delta.seconds / 60)
|
|
return '{} minute{}'.format(minutes, '' if minutes == 1 else 's')
|
|
elif delta < timedelta(days=1):
|
|
hours = int(delta.seconds / 3600)
|
|
return '{} hour{}'.format(hours, '' if hours == 1 else 's')
|
|
else:
|
|
days = delta.days
|
|
return '{} day{}'.format(days, '' if days == 1 else 's')
|