2019-11-07 13:31:02 +00:00
|
|
|
|
from functools import partial
|
2016-05-27 16:21:29 +01:00
|
|
|
|
|
2023-08-25 08:57:24 -07:00
|
|
|
|
from flask import abort, flash, jsonify, redirect, render_template, request, url_for
|
2019-07-01 15:22:08 +01:00
|
|
|
|
from flask_login import current_user
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from notifications_python_client.errors import HTTPError
|
2022-12-05 15:33:44 -05:00
|
|
|
|
from notifications_utils import SMS_CHAR_COUNT_LIMIT
|
2016-04-12 09:55:51 +01:00
|
|
|
|
|
2018-07-19 12:30:04 +01:00
|
|
|
|
from app import (
|
|
|
|
|
|
current_service,
|
2020-02-04 16:00:51 +00:00
|
|
|
|
format_delta,
|
2020-01-22 16:13:25 +00:00
|
|
|
|
nl2br,
|
2018-07-19 12:30:04 +01:00
|
|
|
|
service_api_client,
|
2018-11-01 17:11:58 +00:00
|
|
|
|
template_folder_api_client,
|
2018-07-19 12:30:04 +01:00
|
|
|
|
template_statistics_client,
|
|
|
|
|
|
)
|
2021-01-06 11:54:27 +00:00
|
|
|
|
from app.formatters import character_count, message_count
|
2022-12-06 09:10:00 -05:00
|
|
|
|
from app.main import main
|
2017-03-14 10:46:38 +00:00
|
|
|
|
from app.main.forms import (
|
|
|
|
|
|
EmailTemplateForm,
|
2021-04-13 13:59:51 +01:00
|
|
|
|
SearchTemplatesForm,
|
2018-01-03 10:44:36 +00:00
|
|
|
|
SetTemplateSenderForm,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
SMSTemplateForm,
|
2018-11-08 11:56:29 +00:00
|
|
|
|
TemplateAndFoldersSelectionForm,
|
2018-11-01 17:11:58 +00:00
|
|
|
|
TemplateFolderForm,
|
2017-03-14 10:46:38 +00:00
|
|
|
|
)
|
2019-11-29 13:03:23 +00:00
|
|
|
|
from app.main.views.send import get_sender_details
|
2018-10-26 16:30:37 +01:00
|
|
|
|
from app.models.service import Service
|
2019-01-07 14:49:33 +00:00
|
|
|
|
from app.models.template_list import TemplateList, TemplateLists
|
2021-06-09 15:15:35 +01:00
|
|
|
|
from app.utils import NOTIFICATION_TYPES, should_skip_template_page
|
|
|
|
|
|
from app.utils.templates import get_template
|
2022-12-05 15:33:44 -05:00
|
|
|
|
from app.utils.user import user_has_permissions
|
2015-12-20 00:00:01 +00:00
|
|
|
|
|
2016-02-22 14:45:13 +00:00
|
|
|
|
form_objects = {
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"email": EmailTemplateForm,
|
|
|
|
|
|
"sms": SMSTemplateForm,
|
2016-02-22 14:45:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/templates/<uuid:template_id>")
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2016-04-12 09:55:51 +01:00
|
|
|
|
def view_template(service_id, template_id):
|
2019-03-19 16:25:44 +00:00
|
|
|
|
template = current_service.get_template(template_id)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_folder = current_service.get_template_folder(template["folder"])
|
2019-03-20 17:27:22 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
user_has_template_permission = current_user.has_template_folder_permission(
|
|
|
|
|
|
template_folder
|
|
|
|
|
|
)
|
2021-07-21 16:06:23 +01:00
|
|
|
|
if should_skip_template_page(template):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(".set_sender", service_id=service_id, template_id=template_id)
|
|
|
|
|
|
)
|
2019-07-08 11:25:06 +01:00
|
|
|
|
|
2016-04-12 09:55:51 +01:00
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/template.html",
|
2016-12-08 11:50:59 +00:00
|
|
|
|
template=get_template(
|
2017-04-20 10:40:15 +01:00
|
|
|
|
template,
|
2016-12-08 11:50:59 +00:00
|
|
|
|
current_service,
|
2017-03-10 17:39:38 +00:00
|
|
|
|
show_recipient=True,
|
2017-04-20 10:40:15 +01:00
|
|
|
|
),
|
2019-03-20 17:27:22 +00:00
|
|
|
|
user_has_template_permission=user_has_template_permission,
|
2016-04-12 09:55:51 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route("/services/<uuid:service_id>/templates/all", methods=["GET", "POST"])
|
|
|
|
|
|
@main.route("/services/<uuid:service_id>/templates", methods=["GET", "POST"])
|
|
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/folders/<uuid:template_folder_id>",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
|
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/<template_type:template_type>",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
|
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/all/folders/<uuid:template_folder_id>",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
2019-11-29 13:03:23 +00:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/<template_type:template_type>/folders/<uuid:template_folder_id>",
|
2023-08-25 09:12:23 -07:00
|
|
|
|
methods=["GET", "POST"],
|
2019-11-29 13:03:23 +00:00
|
|
|
|
)
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2023-08-25 09:12:23 -07:00
|
|
|
|
def choose_template(service_id, template_type="all", template_folder_id=None):
|
2019-03-20 17:27:22 +00:00
|
|
|
|
template_folder = current_service.get_template_folder(template_folder_id)
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
user_has_template_folder_permission = current_user.has_template_folder_permission(
|
|
|
|
|
|
template_folder
|
|
|
|
|
|
)
|
2017-06-13 15:27:29 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_list = TemplateList(
|
|
|
|
|
|
current_service, template_type, template_folder_id, current_user
|
|
|
|
|
|
)
|
2018-11-23 16:29:21 +00:00
|
|
|
|
|
2022-05-26 16:46:17 +01:00
|
|
|
|
all_template_folders = [
|
2023-08-25 09:12:23 -07:00
|
|
|
|
item.folder
|
|
|
|
|
|
for item in TemplateList(service=current_service, user=current_user)
|
|
|
|
|
|
if item.is_folder
|
2022-05-26 16:46:17 +01:00
|
|
|
|
]
|
|
|
|
|
|
|
2018-11-08 14:16:46 +00:00
|
|
|
|
templates_and_folders_form = TemplateAndFoldersSelectionForm(
|
2022-05-26 16:46:17 +01:00
|
|
|
|
all_template_folders=all_template_folders,
|
2018-11-23 16:29:21 +00:00
|
|
|
|
template_list=template_list,
|
2018-11-08 14:16:46 +00:00
|
|
|
|
template_type=template_type,
|
2020-07-01 16:43:08 +01:00
|
|
|
|
available_template_types=current_service.available_template_types,
|
2018-11-28 13:48:13 +00:00
|
|
|
|
allow_adding_copy_of_template=(
|
2019-06-07 12:22:15 +01:00
|
|
|
|
current_service.all_templates or len(current_user.service_ids) > 1
|
2018-11-28 13:48:13 +00:00
|
|
|
|
),
|
2018-11-08 14:16:46 +00:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
option_hints = {template_folder_id: "current folder"}
|
2018-12-18 14:40:53 +00:00
|
|
|
|
|
2020-08-11 15:44:17 +01:00
|
|
|
|
single_notification_channel = None
|
2023-08-25 09:12:23 -07:00
|
|
|
|
notification_channels = list(
|
|
|
|
|
|
set(current_service.permissions).intersection(NOTIFICATION_TYPES)
|
|
|
|
|
|
)
|
2020-08-11 15:44:17 +01:00
|
|
|
|
if len(notification_channels) == 1:
|
|
|
|
|
|
single_notification_channel = notification_channels[0]
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if request.method == "POST" and templates_and_folders_form.validate_on_submit():
|
|
|
|
|
|
if not current_user.has_permissions("manage_templates"):
|
2018-11-20 18:03:57 +00:00
|
|
|
|
abort(403)
|
2018-12-05 11:30:47 +00:00
|
|
|
|
try:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return process_folder_management_form(
|
|
|
|
|
|
templates_and_folders_form, template_folder_id
|
|
|
|
|
|
)
|
2018-12-17 15:24:24 +00:00
|
|
|
|
except HTTPError as e:
|
2018-12-05 11:30:47 +00:00
|
|
|
|
flash(e.message)
|
2020-07-01 16:43:08 +01:00
|
|
|
|
elif templates_and_folders_form.trying_to_add_unavailable_template_type:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".action_blocked",
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
notification_type=templates_and_folders_form.add_template_by_template_type.data,
|
|
|
|
|
|
return_to="add_new_template",
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2018-11-14 17:30:22 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if "templates_and_folders" in templates_and_folders_form.errors:
|
|
|
|
|
|
flash("Select at least one template or folder")
|
2018-12-07 16:38:48 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
initial_state = request.args.get("initial_state")
|
|
|
|
|
|
if request.method == "GET" and initial_state:
|
2019-02-14 16:27:13 +00:00
|
|
|
|
templates_and_folders_form.op = initial_state
|
|
|
|
|
|
|
2017-06-13 15:28:33 +01:00
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/choose.html",
|
2018-11-06 13:06:35 +00:00
|
|
|
|
current_template_folder_id=template_folder_id,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_folder_path=current_service.get_template_folder_path(
|
|
|
|
|
|
template_folder_id
|
|
|
|
|
|
),
|
2018-11-23 16:29:21 +00:00
|
|
|
|
template_list=template_list,
|
2018-11-20 12:18:18 +00:00
|
|
|
|
show_search_box=current_service.count_of_templates_and_folders > 7,
|
2018-10-25 07:59:50 +01:00
|
|
|
|
show_template_nav=(
|
|
|
|
|
|
current_service.has_multiple_template_types
|
2018-11-05 15:26:59 +00:00
|
|
|
|
and (len(current_service.all_templates) > 2)
|
2018-10-25 07:59:50 +01:00
|
|
|
|
),
|
2018-11-08 14:16:46 +00:00
|
|
|
|
template_nav_items=get_template_nav_items(template_folder_id),
|
2017-06-13 15:28:33 +01:00
|
|
|
|
template_type=template_type,
|
2021-04-13 13:59:51 +01:00
|
|
|
|
search_form=SearchTemplatesForm(current_service.api_keys),
|
2018-12-04 14:47:05 +00:00
|
|
|
|
templates_and_folders_form=templates_and_folders_form,
|
2019-01-02 17:12:18 +00:00
|
|
|
|
move_to_children=templates_and_folders_form.move_to.children(),
|
2019-03-20 17:27:22 +00:00
|
|
|
|
user_has_template_folder_permission=user_has_template_folder_permission,
|
2020-08-11 15:44:17 +01:00
|
|
|
|
single_notification_channel=single_notification_channel,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
option_hints=option_hints,
|
2017-06-13 15:28:33 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-15 17:31:07 +00:00
|
|
|
|
def process_folder_management_form(form, current_folder_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
current_service.get_template_folder_with_user_permission_or_403(
|
|
|
|
|
|
current_folder_id, current_user
|
|
|
|
|
|
)
|
2018-11-15 17:31:07 +00:00
|
|
|
|
new_folder_id = None
|
2018-11-08 14:46:18 +00:00
|
|
|
|
|
2018-11-28 13:48:13 +00:00
|
|
|
|
if form.is_add_template_op:
|
|
|
|
|
|
return _add_template_by_type(
|
|
|
|
|
|
form.add_template_by_template_type.data,
|
|
|
|
|
|
current_folder_id,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if form.is_add_folder_op:
|
2018-11-15 17:31:07 +00:00
|
|
|
|
new_folder_id = template_folder_api_client.create_template_folder(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
current_service.id, name=form.get_folder_name(), parent_id=current_folder_id
|
2018-11-15 17:31:07 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
if form.is_move_op:
|
|
|
|
|
|
# if we've just made a folder, we also want to move there
|
|
|
|
|
|
move_to_id = new_folder_id or form.move_to.data
|
|
|
|
|
|
|
|
|
|
|
|
current_service.move_to_folder(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
ids_to_move=form.templates_and_folders.data, move_to=move_to_id
|
2018-11-15 17:31:07 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return redirect(request.url)
|
2018-11-08 14:46:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
2018-11-12 09:16:14 +00:00
|
|
|
|
def get_template_nav_label(value):
|
|
|
|
|
|
return {
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"all": "All",
|
|
|
|
|
|
"sms": "Text message",
|
|
|
|
|
|
"email": "Email",
|
2018-11-12 09:16:14 +00:00
|
|
|
|
}[value]
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-08 14:16:46 +00:00
|
|
|
|
def get_template_nav_items(template_folder_id):
|
|
|
|
|
|
return [
|
|
|
|
|
|
(
|
2018-11-12 09:16:14 +00:00
|
|
|
|
get_template_nav_label(key),
|
2018-11-08 14:16:46 +00:00
|
|
|
|
key,
|
|
|
|
|
|
url_for(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
".choose_template",
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
template_type=key,
|
|
|
|
|
|
template_folder_id=template_folder_id,
|
2018-11-08 14:16:46 +00:00
|
|
|
|
),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"",
|
2018-11-08 14:16:46 +00:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
for key in ["all"] + current_service.available_template_types
|
2018-11-08 14:16:46 +00:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-12-05 15:33:44 -05:00
|
|
|
|
def _view_template_version(service_id, template_id, version):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return dict(
|
|
|
|
|
|
template=get_template(
|
|
|
|
|
|
current_service.get_template(template_id, version=version), current_service
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2016-12-20 11:56:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/<uuid:template_id>/version/<int:version>"
|
|
|
|
|
|
)
|
2018-08-06 11:09:57 +01:00
|
|
|
|
@user_has_permissions()
|
2016-05-11 11:20:45 +01:00
|
|
|
|
def view_template_version(service_id, template_id, version):
|
|
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/template_history.html",
|
|
|
|
|
|
**_view_template_version(
|
|
|
|
|
|
service_id=service_id, template_id=template_id, version=version
|
|
|
|
|
|
),
|
2016-05-11 11:20:45 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-28 13:48:13 +00:00
|
|
|
|
def _add_template_by_type(template_type, template_folder_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if template_type == "copy-existing":
|
|
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".choose_template_to_copy",
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2018-11-28 13:48:13 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".add_service_template",
|
2018-11-28 13:48:13 +00:00
|
|
|
|
service_id=current_service.id,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_type=template_type,
|
|
|
|
|
|
template_folder_id=template_folder_id,
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2018-11-28 13:48:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route("/services/<uuid:service_id>/templates/copy")
|
|
|
|
|
|
@main.route("/services/<uuid:service_id>/templates/copy/from-folder/<uuid:from_folder>")
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/copy/from-service/<uuid:from_service>"
|
|
|
|
|
|
)
|
2019-11-29 13:03:23 +00:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/copy/from-service/<uuid:from_service>/from-folder/<uuid:from_folder>"
|
|
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@user_has_permissions("manage_templates")
|
2019-01-07 14:49:33 +00:00
|
|
|
|
def choose_template_to_copy(
|
|
|
|
|
|
service_id,
|
|
|
|
|
|
from_service=None,
|
|
|
|
|
|
from_folder=None,
|
|
|
|
|
|
):
|
|
|
|
|
|
if from_service:
|
|
|
|
|
|
current_user.belongs_to_service_or_403(from_service)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service = Service(service_api_client.get_service(from_service)["data"])
|
2019-01-07 14:49:33 +00:00
|
|
|
|
|
|
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/copy.html",
|
2019-01-07 14:49:33 +00:00
|
|
|
|
services_templates_and_folders=TemplateList(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service, template_folder_id=from_folder, user=current_user
|
2019-01-07 14:49:33 +00:00
|
|
|
|
),
|
|
|
|
|
|
template_folder_path=service.get_template_folder_path(from_folder),
|
|
|
|
|
|
from_service=service,
|
2021-04-13 13:59:51 +01:00
|
|
|
|
search_form=SearchTemplatesForm(current_service.api_keys),
|
2019-01-07 14:49:33 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/copy.html",
|
2019-06-07 12:38:48 +01:00
|
|
|
|
services_templates_and_folders=TemplateLists(current_user),
|
2021-04-13 13:59:51 +01:00
|
|
|
|
search_form=SearchTemplatesForm(current_service.api_keys),
|
2019-01-07 14:49:33 +00:00
|
|
|
|
)
|
2018-07-19 12:30:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/copy/<uuid:template_id>",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2018-07-19 12:30:04 +01:00
|
|
|
|
def copy_template(service_id, template_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
from_service = request.args.get("from_service")
|
2018-07-19 12:30:04 +01:00
|
|
|
|
|
2019-04-03 13:59:44 +01:00
|
|
|
|
current_user.belongs_to_service_or_403(from_service)
|
2018-07-19 12:30:04 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template = service_api_client.get_service_template(from_service, template_id)[
|
|
|
|
|
|
"data"
|
|
|
|
|
|
]
|
2018-07-31 16:20:10 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_folder = template_folder_api_client.get_template_folder(
|
|
|
|
|
|
from_service, template["folder"]
|
|
|
|
|
|
)
|
2019-04-02 15:23:46 +01:00
|
|
|
|
if not current_user.has_template_folder_permission(template_folder):
|
2019-03-20 16:41:01 +00:00
|
|
|
|
abort(403)
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if request.method == "POST":
|
|
|
|
|
|
return add_service_template(service_id, template["template_type"])
|
2018-07-31 16:20:10 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template["template_content"] = template["content"]
|
|
|
|
|
|
template["name"] = _get_template_copy_name(template, current_service.all_templates)
|
|
|
|
|
|
form = form_objects[template["template_type"]](**template)
|
2018-07-19 12:30:04 +01:00
|
|
|
|
|
|
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/edit-{}-template.html".format(template["template_type"]),
|
2018-07-19 12:30:04 +01:00
|
|
|
|
form=form,
|
2019-04-29 11:44:05 +01:00
|
|
|
|
template=template,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
heading_action="Add",
|
2019-06-07 12:22:15 +01:00
|
|
|
|
services=current_user.service_ids,
|
2018-07-19 12:30:04 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-11-13 15:06:39 +00:00
|
|
|
|
def _get_template_copy_name(template, existing_templates):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_names = [existing["name"] for existing in existing_templates]
|
2018-11-13 15:06:39 +00:00
|
|
|
|
|
|
|
|
|
|
for index in reversed(range(1, 10)):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if "{} (copy {})".format(template["name"], index) in template_names:
|
|
|
|
|
|
return "{} (copy {})".format(template["name"], index + 1)
|
2018-11-13 15:06:39 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if "{} (copy)".format(template["name"]) in template_names:
|
|
|
|
|
|
return "{} (copy 2)".format(template["name"])
|
2018-11-13 15:06:39 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return "{} (copy)".format(template["name"])
|
2018-11-13 15:06:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/action-blocked/"
|
|
|
|
|
|
"<template_type:notification_type>/<return_to>"
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
@main.route(
|
|
|
|
|
|
(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/action-blocked/"
|
|
|
|
|
|
"<template_type:notification_type>/<return_to>/<uuid:template_id>"
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2019-11-07 13:31:02 +00:00
|
|
|
|
def action_blocked(service_id, notification_type, return_to, template_id=None):
|
|
|
|
|
|
back_link = {
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"add_new_template": partial(
|
|
|
|
|
|
url_for, ".choose_template", service_id=current_service.id
|
2019-11-07 13:31:02 +00:00
|
|
|
|
),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"templates": partial(
|
|
|
|
|
|
url_for, ".choose_template", service_id=current_service.id
|
2019-11-07 13:31:02 +00:00
|
|
|
|
),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"view_template": partial(
|
|
|
|
|
|
url_for,
|
|
|
|
|
|
".view_template",
|
|
|
|
|
|
service_id=current_service.id,
|
|
|
|
|
|
template_id=template_id,
|
2019-11-07 13:31:02 +00:00
|
|
|
|
),
|
|
|
|
|
|
}.get(return_to)
|
2017-06-30 10:55:59 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return (
|
|
|
|
|
|
render_template(
|
|
|
|
|
|
"views/templates/action_blocked.html",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
notification_type=notification_type,
|
|
|
|
|
|
back_link=back_link(),
|
|
|
|
|
|
),
|
|
|
|
|
|
403,
|
|
|
|
|
|
)
|
2017-06-30 10:55:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/folders/<uuid:template_folder_id>/manage",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2018-11-12 16:37:37 +00:00
|
|
|
|
def manage_template_folder(service_id, template_folder_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_folder = current_service.get_template_folder_with_user_permission_or_403(
|
|
|
|
|
|
template_folder_id, current_user
|
|
|
|
|
|
)
|
2018-11-13 16:05:05 +00:00
|
|
|
|
form = TemplateFolderForm(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
name=template_folder["name"],
|
|
|
|
|
|
users_with_permission=template_folder.get("users_with_permission", None),
|
|
|
|
|
|
all_service_users=[
|
|
|
|
|
|
user for user in current_service.active_users if user.id != current_user.id
|
|
|
|
|
|
],
|
2018-11-13 16:05:05 +00:00
|
|
|
|
)
|
2018-11-12 16:37:37 +00:00
|
|
|
|
if form.validate_on_submit():
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if (
|
|
|
|
|
|
current_user.has_permissions("manage_service")
|
|
|
|
|
|
and form.users_with_permission.all_service_users
|
|
|
|
|
|
):
|
2019-04-02 12:26:41 +01:00
|
|
|
|
users_with_permission = form.users_with_permission.data + [current_user.id]
|
|
|
|
|
|
else:
|
|
|
|
|
|
users_with_permission = None
|
2018-11-12 16:37:37 +00:00
|
|
|
|
template_folder_api_client.update_template_folder(
|
2019-03-15 17:19:18 +00:00
|
|
|
|
current_service.id,
|
|
|
|
|
|
template_folder_id,
|
|
|
|
|
|
name=form.name.data,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
users_with_permission=users_with_permission,
|
2018-11-12 16:37:37 +00:00
|
|
|
|
)
|
|
|
|
|
|
return redirect(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
url_for(
|
|
|
|
|
|
".choose_template",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_folder_id=template_folder_id,
|
|
|
|
|
|
)
|
2018-11-12 16:37:37 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/manage-template-folder.html",
|
2018-11-12 16:37:37 +00:00
|
|
|
|
form=form,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_folder_path=current_service.get_template_folder_path(
|
|
|
|
|
|
template_folder_id
|
|
|
|
|
|
),
|
2018-11-13 15:49:25 +00:00
|
|
|
|
current_service_id=current_service.id,
|
2018-11-16 11:21:27 +00:00
|
|
|
|
template_folder_id=template_folder_id,
|
2019-03-15 14:13:27 +00:00
|
|
|
|
template_type="all",
|
2018-11-12 16:37:37 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/folders/<uuid:template_folder_id>/delete",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2018-11-13 15:49:25 +00:00
|
|
|
|
def delete_template_folder(service_id, template_folder_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_folder = current_service.get_template_folder_with_user_permission_or_403(
|
|
|
|
|
|
template_folder_id, current_user
|
|
|
|
|
|
)
|
|
|
|
|
|
template_list = TemplateList(
|
|
|
|
|
|
service=current_service, template_folder_id=template_folder_id
|
|
|
|
|
|
)
|
2018-11-20 10:43:56 +00:00
|
|
|
|
|
2022-05-26 13:53:12 +01:00
|
|
|
|
if not template_list.folder_is_empty:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
flash("You must empty this folder before you can delete it", "info")
|
2018-11-14 17:07:23 +00:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
".choose_template",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_type="all",
|
|
|
|
|
|
template_folder_id=template_folder_id,
|
2018-11-14 17:07:23 +00:00
|
|
|
|
)
|
|
|
|
|
|
)
|
2018-11-14 15:57:23 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if request.method == "POST":
|
2018-11-14 12:16:57 +00:00
|
|
|
|
try:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_folder_api_client.delete_template_folder(
|
|
|
|
|
|
current_service.id, template_folder_id
|
|
|
|
|
|
)
|
2018-11-13 17:56:47 +00:00
|
|
|
|
|
2018-11-14 12:16:57 +00:00
|
|
|
|
return redirect(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
url_for(
|
|
|
|
|
|
".choose_template",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_folder_id=template_folder["parent_id"],
|
|
|
|
|
|
)
|
2018-11-14 12:16:57 +00:00
|
|
|
|
)
|
|
|
|
|
|
except HTTPError as e:
|
|
|
|
|
|
msg = "Folder is not empty"
|
|
|
|
|
|
if e.status_code == 400 and msg in e.message:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
flash("You must empty this folder before you can delete it", "info")
|
2018-11-14 17:07:23 +00:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
".choose_template",
|
2018-11-14 17:07:23 +00:00
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_type="all",
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_folder_id=template_folder_id,
|
2018-11-14 17:07:23 +00:00
|
|
|
|
)
|
|
|
|
|
|
)
|
2018-11-14 12:16:57 +00:00
|
|
|
|
else:
|
|
|
|
|
|
abort(500, e)
|
2019-03-20 17:04:44 +00:00
|
|
|
|
else:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
flash(
|
|
|
|
|
|
"Are you sure you want to delete the ‘{}’ folder?".format(
|
|
|
|
|
|
template_folder["name"]
|
|
|
|
|
|
),
|
|
|
|
|
|
"delete",
|
|
|
|
|
|
)
|
2019-03-20 17:04:44 +00:00
|
|
|
|
return manage_template_folder(service_id, template_folder_id)
|
2018-11-13 15:49:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-04 11:07:55 +00:00
|
|
|
|
@main.route(
|
2019-11-04 11:20:08 +00:00
|
|
|
|
"/services/<uuid:service_id>/templates/add-<template_type:template_type>",
|
2023-08-25 09:12:23 -07:00
|
|
|
|
methods=["GET", "POST"],
|
2019-11-04 11:07:55 +00:00
|
|
|
|
)
|
|
|
|
|
|
@main.route(
|
2019-11-04 11:20:08 +00:00
|
|
|
|
"/services/<uuid:service_id>/templates/folders/<uuid:template_folder_id>/add-<template_type:template_type>",
|
2023-08-25 09:12:23 -07:00
|
|
|
|
methods=["GET", "POST"],
|
2019-11-04 11:07:55 +00:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@user_has_permissions("manage_templates")
|
2018-11-06 13:06:35 +00:00
|
|
|
|
def add_service_template(service_id, template_type, template_folder_id=None):
|
2020-07-01 16:43:08 +01:00
|
|
|
|
if template_type not in current_service.available_template_types:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".action_blocked",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
notification_type=template_type,
|
|
|
|
|
|
template_folder_id=template_folder_id,
|
|
|
|
|
|
return_to="templates",
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2016-01-11 13:15:10 +00:00
|
|
|
|
|
2016-02-22 14:45:13 +00:00
|
|
|
|
form = form_objects[template_type]()
|
2016-01-19 15:54:12 +00:00
|
|
|
|
if form.validate_on_submit():
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if form.process_type.data == "priority":
|
2017-01-18 15:11:34 +00:00
|
|
|
|
abort_403_if_not_admin_user()
|
2016-04-29 09:38:59 +01:00
|
|
|
|
try:
|
2017-03-14 13:39:21 +00:00
|
|
|
|
new_template = service_api_client.create_service_template(
|
2016-04-29 09:38:59 +01:00
|
|
|
|
form.name.data,
|
|
|
|
|
|
template_type,
|
|
|
|
|
|
form.template_content.data,
|
|
|
|
|
|
service_id,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
form.subject.data if hasattr(form, "subject") else None,
|
|
|
|
|
|
template_folder_id,
|
2016-04-29 09:38:59 +01:00
|
|
|
|
)
|
|
|
|
|
|
except HTTPError as e:
|
2017-02-15 15:06:47 +00:00
|
|
|
|
if (
|
2019-01-29 15:43:59 +00:00
|
|
|
|
e.status_code == 400
|
2023-08-25 09:12:23 -07:00
|
|
|
|
and "content" in e.message
|
|
|
|
|
|
and any(
|
|
|
|
|
|
["character count greater than" in x for x in e.message["content"]]
|
|
|
|
|
|
)
|
2017-02-15 15:06:47 +00:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
form.template_content.errors.extend(e.message["content"])
|
2016-04-29 09:38:59 +01:00
|
|
|
|
else:
|
|
|
|
|
|
raise e
|
|
|
|
|
|
else:
|
|
|
|
|
|
return redirect(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
url_for(
|
|
|
|
|
|
".view_template",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=new_template["data"]["id"],
|
|
|
|
|
|
)
|
2016-04-29 09:38:59 +01:00
|
|
|
|
)
|
2017-07-04 17:25:35 +01:00
|
|
|
|
|
2020-07-01 16:43:08 +01:00
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/edit-{}-template.html".format(template_type),
|
2020-07-01 16:43:08 +01:00
|
|
|
|
form=form,
|
|
|
|
|
|
template_type=template_type,
|
|
|
|
|
|
template_folder_id=template_folder_id,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
heading_action="New",
|
2020-07-01 16:43:08 +01:00
|
|
|
|
)
|
2016-01-13 13:24:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-18 15:11:34 +00:00
|
|
|
|
def abort_403_if_not_admin_user():
|
2018-02-27 16:45:20 +00:00
|
|
|
|
if not current_user.platform_admin:
|
2017-01-18 15:11:34 +00:00
|
|
|
|
abort(403)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/<uuid:template_id>/edit",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2016-01-19 15:54:12 +00:00
|
|
|
|
def edit_service_template(service_id, template_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(
|
|
|
|
|
|
template_id, current_user
|
|
|
|
|
|
)
|
|
|
|
|
|
template["template_content"] = template["content"]
|
|
|
|
|
|
form = form_objects[template["template_type"]](**template)
|
2016-01-19 15:54:12 +00:00
|
|
|
|
if form.validate_on_submit():
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if form.process_type.data != template["process_type"]:
|
2017-01-18 15:11:34 +00:00
|
|
|
|
abort_403_if_not_admin_user()
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
subject = form.subject.data if hasattr(form, "subject") else None
|
2018-12-18 18:22:03 +00:00
|
|
|
|
|
|
|
|
|
|
new_template_data = {
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"name": form.name.data,
|
|
|
|
|
|
"content": form.template_content.data,
|
|
|
|
|
|
"subject": subject,
|
|
|
|
|
|
"template_type": template["template_type"],
|
|
|
|
|
|
"id": template["id"],
|
|
|
|
|
|
"process_type": form.process_type.data,
|
|
|
|
|
|
"reply_to_text": template["reply_to_text"],
|
2018-12-18 18:22:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
new_template = get_template(new_template_data, current_service)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_change = get_template(template, current_service).compare_to(
|
|
|
|
|
|
new_template
|
|
|
|
|
|
)
|
2019-11-12 16:57:01 +00:00
|
|
|
|
|
|
|
|
|
|
if (
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template_change.placeholders_added
|
|
|
|
|
|
and not request.form.get("confirm")
|
|
|
|
|
|
and current_service.api_keys
|
2019-11-12 16:57:01 +00:00
|
|
|
|
):
|
2016-05-27 16:21:29 +01:00
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/breaking-change.html",
|
2016-05-27 16:21:29 +01:00
|
|
|
|
template_change=template_change,
|
2017-03-06 13:08:27 +00:00
|
|
|
|
new_template=new_template,
|
2019-11-12 16:59:39 +00:00
|
|
|
|
form=form,
|
2016-05-27 16:21:29 +01:00
|
|
|
|
)
|
2016-04-29 09:38:59 +01:00
|
|
|
|
try:
|
|
|
|
|
|
service_api_client.update_service_template(
|
|
|
|
|
|
template_id,
|
|
|
|
|
|
form.name.data,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template["template_type"],
|
2016-04-29 09:38:59 +01:00
|
|
|
|
form.template_content.data,
|
|
|
|
|
|
service_id,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
subject,
|
2016-04-29 09:38:59 +01:00
|
|
|
|
)
|
|
|
|
|
|
except HTTPError as e:
|
|
|
|
|
|
if e.status_code == 400:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
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"])
|
2016-04-29 09:38:59 +01:00
|
|
|
|
else:
|
|
|
|
|
|
raise e
|
|
|
|
|
|
else:
|
|
|
|
|
|
raise e
|
|
|
|
|
|
else:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".view_template", service_id=service_id, template_id=template_id
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2017-06-30 10:55:59 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if template["template_type"] not in current_service.available_template_types:
|
|
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".action_blocked",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
notification_type=template["template_type"],
|
|
|
|
|
|
return_to="view_template",
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2017-06-30 10:55:59 +01:00
|
|
|
|
else:
|
|
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/edit-{}-template.html".format(template["template_type"]),
|
2017-06-30 10:55:59 +01:00
|
|
|
|
form=form,
|
2019-04-29 11:44:05 +01:00
|
|
|
|
template=template,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
heading_action="Edit",
|
2017-06-30 10:55:59 +01:00
|
|
|
|
)
|
2016-01-14 09:44:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
2021-01-06 11:54:27 +00:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/count-<template_type:template_type>-length",
|
2023-08-25 09:12:23 -07:00
|
|
|
|
methods=["POST"],
|
2021-01-06 11:54:27 +00:00
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions()
|
|
|
|
|
|
def count_content_length(service_id, template_type):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if template_type not in {"sms"}:
|
2021-01-06 11:54:27 +00:00
|
|
|
|
abort(404)
|
|
|
|
|
|
|
|
|
|
|
|
error, message = _get_content_count_error_and_message_for_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
get_template(
|
|
|
|
|
|
{
|
|
|
|
|
|
"template_type": template_type,
|
|
|
|
|
|
"content": request.form.get("template_content", ""),
|
|
|
|
|
|
},
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
)
|
2021-01-06 11:54:27 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return jsonify(
|
|
|
|
|
|
{
|
|
|
|
|
|
"html": render_template(
|
|
|
|
|
|
"partials/templates/content-count-message.html",
|
|
|
|
|
|
error=error,
|
|
|
|
|
|
message=message,
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
)
|
2021-01-06 11:54:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _get_content_count_error_and_message_for_template(template):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if template.template_type == "sms":
|
2021-01-06 11:54:27 +00:00
|
|
|
|
if template.is_message_too_long():
|
|
|
|
|
|
return True, (
|
2023-08-25 09:12:23 -07:00
|
|
|
|
f"You have "
|
|
|
|
|
|
f"{character_count(template.content_count_without_prefix - SMS_CHAR_COUNT_LIMIT)} "
|
|
|
|
|
|
f"too many"
|
2021-01-06 11:54:27 +00:00
|
|
|
|
)
|
|
|
|
|
|
if template.placeholders:
|
|
|
|
|
|
return False, (
|
2023-08-25 09:12:23 -07:00
|
|
|
|
f"Will be charged as {message_count(template.fragment_count, template.template_type)} "
|
|
|
|
|
|
f"(not including personalization)"
|
2021-01-06 11:54:27 +00:00
|
|
|
|
)
|
|
|
|
|
|
return False, (
|
2023-08-25 09:12:23 -07:00
|
|
|
|
f"Will be charged as {message_count(template.fragment_count, template.template_type)} "
|
2021-01-06 11:54:27 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/<uuid:template_id>/delete",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2016-01-19 15:54:12 +00:00
|
|
|
|
def delete_service_template(service_id, template_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(
|
|
|
|
|
|
template_id, current_user
|
|
|
|
|
|
)
|
2016-01-19 15:54:12 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
if request.method == "POST":
|
2016-03-30 10:23:39 +01:00
|
|
|
|
service_api_client.delete_service_template(service_id, template_id)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".choose_template",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_folder_id=template["folder"],
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2016-01-19 15:54:12 +00:00
|
|
|
|
|
2016-08-22 16:25:35 +01:00
|
|
|
|
try:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
last_used_notification = (
|
|
|
|
|
|
template_statistics_client.get_last_used_date_for_template(
|
|
|
|
|
|
service_id, template["id"]
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
message = (
|
|
|
|
|
|
"This template has never been used."
|
|
|
|
|
|
if not last_used_notification
|
|
|
|
|
|
else "This template was last used {}.".format(
|
|
|
|
|
|
format_delta(last_used_notification)
|
|
|
|
|
|
)
|
2016-08-22 16:25:35 +01:00
|
|
|
|
)
|
2017-07-26 12:04:07 +01:00
|
|
|
|
|
2016-08-22 16:25:35 +01:00
|
|
|
|
except HTTPError as e:
|
|
|
|
|
|
if e.status_code == 404:
|
2017-07-24 14:55:39 +01:00
|
|
|
|
message = None
|
2016-08-24 11:26:34 +01:00
|
|
|
|
else:
|
|
|
|
|
|
raise e
|
2016-08-22 16:25:35 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
flash(
|
|
|
|
|
|
[
|
|
|
|
|
|
"Are you sure you want to delete ‘{}’?".format(template["name"]),
|
|
|
|
|
|
message,
|
|
|
|
|
|
template["name"],
|
|
|
|
|
|
],
|
|
|
|
|
|
"delete",
|
|
|
|
|
|
)
|
2016-01-19 15:54:12 +00:00
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/template.html",
|
2017-04-18 13:01:58 +01:00
|
|
|
|
template=get_template(
|
|
|
|
|
|
template,
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
show_recipient=True,
|
2017-10-16 16:35:35 +01:00
|
|
|
|
),
|
2019-03-20 17:27:22 +00:00
|
|
|
|
user_has_template_permission=True,
|
2017-04-18 13:01:58 +01:00
|
|
|
|
)
|
2016-05-11 11:20:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/<uuid:template_id>/redact", methods=["GET"]
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2017-06-27 14:35:37 +01:00
|
|
|
|
def confirm_redact_template(service_id, template_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(
|
|
|
|
|
|
template_id, current_user
|
|
|
|
|
|
)
|
2017-10-16 16:35:35 +01:00
|
|
|
|
|
2017-06-26 14:41:00 +01:00
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/template.html",
|
2017-06-26 14:41:00 +01:00
|
|
|
|
template=get_template(
|
2017-10-16 16:35:35 +01:00
|
|
|
|
template,
|
2017-06-26 14:41:00 +01:00
|
|
|
|
current_service,
|
|
|
|
|
|
show_recipient=True,
|
|
|
|
|
|
),
|
2019-03-20 17:27:22 +00:00
|
|
|
|
user_has_template_permission=True,
|
2017-06-26 14:41:00 +01:00
|
|
|
|
show_redaction_message=True,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/<uuid:template_id>/redact", methods=["POST"]
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2017-06-27 14:35:37 +01:00
|
|
|
|
def redact_template(service_id, template_id):
|
|
|
|
|
|
service_api_client.redact_service_template(service_id, template_id)
|
|
|
|
|
|
|
|
|
|
|
|
flash(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"Personalized content will be hidden for messages sent with this template",
|
|
|
|
|
|
"default_with_tick",
|
2017-06-27 14:35:37 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
".view_template",
|
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
2017-06-27 14:35:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route("/services/<uuid:service_id>/templates/<uuid:template_id>/versions")
|
|
|
|
|
|
@user_has_permissions("view_activity")
|
2016-05-11 11:20:45 +01:00
|
|
|
|
def view_template_versions(service_id, template_id):
|
|
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/choose_history.html",
|
2016-12-08 11:50:59 +00:00
|
|
|
|
versions=[
|
2016-12-20 14:38:34 +00:00
|
|
|
|
get_template(
|
|
|
|
|
|
template,
|
|
|
|
|
|
current_service,
|
|
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
for template in service_api_client.get_service_template_versions(
|
|
|
|
|
|
service_id, template_id
|
|
|
|
|
|
)["data"]
|
|
|
|
|
|
],
|
2016-05-11 11:20:45 +01:00
|
|
|
|
)
|
2016-06-06 11:09:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@main.route(
|
|
|
|
|
|
"/services/<uuid:service_id>/templates/<uuid:template_id>/set-template-sender",
|
|
|
|
|
|
methods=["GET", "POST"],
|
|
|
|
|
|
)
|
|
|
|
|
|
@user_has_permissions("manage_templates")
|
2018-01-03 10:44:36 +00:00
|
|
|
|
def set_template_sender(service_id, template_id):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
template = current_service.get_template_with_user_permission_or_403(
|
|
|
|
|
|
template_id, current_user
|
|
|
|
|
|
)
|
2018-01-03 10:44:36 +00:00
|
|
|
|
sender_details = get_template_sender_form_dict(service_id, template)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
no_senders = sender_details.get("no_senders", False)
|
2018-01-03 10:44:36 +00:00
|
|
|
|
|
|
|
|
|
|
form = SetTemplateSenderForm(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
sender=sender_details["current_choice"],
|
|
|
|
|
|
sender_choices=sender_details["value_and_label"],
|
2018-01-03 10:44:36 +00:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
form.sender.param_extensions = {"items": []}
|
|
|
|
|
|
for item_value, _item_label in sender_details["value_and_label"]:
|
|
|
|
|
|
if item_value == sender_details["default_sender"]:
|
|
|
|
|
|
extensions = {"hint": {"text": "(Default)"}}
|
2021-01-13 14:58:39 +00:00
|
|
|
|
else:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
extensions = (
|
|
|
|
|
|
{}
|
|
|
|
|
|
) # if no extensions needed, send an empty dict to preserve order of items
|
2021-01-13 14:58:39 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
form.sender.param_extensions["items"].append(extensions)
|
2018-01-03 10:44:36 +00:00
|
|
|
|
|
|
|
|
|
|
if form.validate_on_submit():
|
|
|
|
|
|
service_api_client.update_service_template_sender(
|
|
|
|
|
|
service_id,
|
|
|
|
|
|
template_id,
|
|
|
|
|
|
form.sender.data if form.sender.data else None,
|
|
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return redirect(
|
|
|
|
|
|
url_for(".view_template", service_id=service_id, template_id=template_id)
|
|
|
|
|
|
)
|
2018-01-03 10:44:36 +00:00
|
|
|
|
|
|
|
|
|
|
return render_template(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"views/templates/set-template-sender.html",
|
2018-01-03 10:44:36 +00:00
|
|
|
|
form=form,
|
|
|
|
|
|
template_id=template_id,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
no_senders=no_senders,
|
2018-01-03 10:44:36 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_template_sender_form_dict(service_id, template):
|
|
|
|
|
|
context = {
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"email": {"field_name": "email_address"},
|
|
|
|
|
|
"sms": {"field_name": "sms_sender"},
|
|
|
|
|
|
}[template["template_type"]]
|
2018-01-03 10:44:36 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
sender_format = context["field_name"]
|
|
|
|
|
|
service_senders = get_sender_details(service_id, template["template_type"])
|
|
|
|
|
|
context["default_sender"] = next(
|
|
|
|
|
|
(x["id"] for x in service_senders if x["is_default"]), "Not set"
|
2018-01-03 10:44:36 +00:00
|
|
|
|
)
|
|
|
|
|
|
if not service_senders:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
context["no_senders"] = True
|
2018-01-03 10:44:36 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
context["value_and_label"] = [
|
|
|
|
|
|
(sender["id"], nl2br(sender[sender_format])) for sender in service_senders
|
|
|
|
|
|
]
|
|
|
|
|
|
context["value_and_label"].insert(
|
|
|
|
|
|
0, ("", "Blank")
|
|
|
|
|
|
) # Add blank option to start of list
|
2018-01-03 10:44:36 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
context["current_choice"] = ""
|
2018-01-03 10:44:36 +00:00
|
|
|
|
return context
|