Example #1
0
def copy_template(service_id, template_id):
    from_service = request.args.get('from_service')

    current_user.belongs_to_service_or_403(from_service)

    template = service_api_client.get_service_template(from_service,
                                                       template_id)['data']

    template_folder = template_folder_api_client.get_template_folder(
        from_service, template['folder'])
    if not current_user.has_template_folder_permission(template_folder):
        abort(403)

    if request.method == 'POST':
        return add_service_template(service_id, template['template_type'])

    template['template_content'] = template['content']
    template['name'] = _get_template_copy_name(template,
                                               current_service.all_templates)
    form = form_objects[template['template_type']](**template)

    return render_template(
        'views/edit-{}-template.html'.format(template['template_type']),
        form=form,
        template=template,
        heading_action='Add',
        services=current_user.service_ids,
    )
Example #2
0
def copy_template(service_id, template_id):

    if not user_api_client.user_belongs_to_service(
            current_user, request.args.get('from_service')):
        abort(403)

    template = service_api_client.get_service_template(
        request.args.get('from_service'),
        str(template_id),
    )['data']

    if request.method == 'POST':
        return add_service_template(service_id, template['template_type'])

    template['template_content'] = template['content']
    template['name'] = 'Copy of ‘{}’'.format(template['name'])
    form = form_objects[template['template_type']](**template)

    return render_template(
        'views/edit-{}-template.html'.format(template['template_type']),
        form=form,
        template_type=template['template_type'],
        heading_action='Add',
        services=user_api_client.get_service_ids_for_user(current_user),
    )
Example #3
0
def view_job(service_id, job_id):

    job = job_api_client.get_job(service_id, job_id)['data']
    filter_args = _parse_filter_args(request.args)
    filter_args['status'] = _set_status_filters(filter_args)

    return render_template(
        'views/jobs/job.html',
        finished=job.get('notifications_sent', 0) and ((
            job.get('notifications_sent', 0) -
            job.get('notifications_delivered', 0) -
            job.get('notifications_failed', 0)
        ) == 0),
        uploaded_file_name=job['original_file_name'],
        template=Template(
            service_api_client.get_service_template(
                service_id=service_id,
                template_id=job['template'],
                version=job['template_version']
            )['data'],
            prefix=current_service['name']
        ),
        status=request.args.get('status', ''),
        updates_url=url_for(
            ".view_job_updates",
            service_id=service_id,
            job_id=job['id'],
            status=request.args.get('status', ''),
            help=get_help_argument()
        ),
        partials=get_job_partials(job),
        help=get_help_argument()
    )
Example #4
0
def send_test(service_id, template_id):
    session['recipient'] = None
    session['placeholders'] = {}
    session['send_test_letter_page_count'] = None

    db_template = service_api_client.get_service_template(service_id, template_id)['data']
    if db_template['template_type'] == 'letter':
        session['sender_id'] = None

    if email_or_sms_not_enabled(db_template['template_type'], current_service['permissions']):
        return redirect(url_for(
            '.action_blocked',
            service_id=service_id,
            notification_type=db_template['template_type'],
            return_to='view_template',
            template_id=template_id))

    return redirect(url_for(
        {
            'main.send_test': '.send_test_step',
            'main.send_one_off': '.send_one_off_step',
        }[request.endpoint],
        service_id=service_id,
        template_id=template_id,
        step_index=0,
        help=get_help_argument(),
    ))
Example #5
0
def send_from_api(service_id, template_id):
    return render_template('views/send-from-api.html',
                           template=Template(
                               service_api_client.get_service_template(
                                   service_id, template_id)['data'],
                               prefix=current_service['name'],
                               sms_sender=current_service['sms_sender']))
Example #6
0
def view_job(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)['data']
    if job['job_status'] == 'cancelled':
        abort(404)

    filter_args = parse_filter_args(request.args)
    filter_args['status'] = set_status_filters(filter_args)

    total_notifications = job.get('notification_count', 0)
    processed_notifications = job.get('notifications_delivered', 0) + job.get(
        'notifications_failed', 0)

    template = service_api_client.get_service_template(
        service_id=service_id,
        template_id=job['template'],
        version=job['template_version'])['data']

    return render_template(
        'views/jobs/job.html',
        finished=(total_notifications == processed_notifications),
        uploaded_file_name=job['original_file_name'],
        template_id=job['template'],
        status=request.args.get('status', ''),
        updates_url=url_for(
            ".view_job_updates",
            service_id=service_id,
            job_id=job['id'],
            status=request.args.get('status', ''),
        ),
        partials=get_job_partials(job, template),
        just_sent=bool(
            request.args.get('just_sent') == 'yes'
            and template['template_type'] == 'letter'))
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)
Example #8
0
def view_job_csv(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)['data']
    template = service_api_client.get_service_template(
        service_id=service_id,
        template_id=job['template'],
        version=job['template_version']
    )['data']
    filter_args = _parse_filter_args(request.args)
    filter_args['status'] = _set_status_filters(filter_args)

    return (
        generate_notifications_csv(
            notification_api_client.get_notifications_for_service(
                service_id,
                job_id,
                status=filter_args.get('status'),
                page_size=job['notification_count']
            )['notifications']
        ),
        200,
        {
            'Content-Type': 'text/csv; charset=utf-8',
            'Content-Disposition': 'inline; filename="{} - {}.csv"'.format(
                template['name'],
                format_datetime_short(job['created_at'])
            )
        }
    )
Example #9
0
def view_job_csv(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)["data"]
    template = service_api_client.get_service_template(
        service_id=service_id,
        template_id=job["template"],
        version=job["template_version"],
    )["data"]
    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=job_id,
                status=filter_args.get("status"),
                page=request.args.get("page", 1),
                page_size=5000,
                format_for_csv=True,
                template_type=template["template_type"],
            )),
        mimetype="text/csv",
        headers={
            "Content-Disposition":
            'inline; filename="{} - {}.csv"'.format(
                template["name"], format_datetime_short(job["created_at"]))
        },
    )
Example #10
0
def _check_notification(service_id, template_id, exception=None):
    db_template = service_api_client.get_service_template(service_id, template_id)['data']
    email_reply_to = None
    sms_sender = None
    if db_template['template_type'] == 'email':
        email_reply_to = get_email_reply_to_address_from_session(service_id)
    elif db_template['template_type'] == 'sms':
        sms_sender = get_sms_sender_from_session(service_id)
    template = get_template(
        db_template,
        current_service,
        show_recipient=True,
        email_reply_to=email_reply_to,
        sms_sender=sms_sender
    )

    # go back to start of process
    back_link = get_back_link(service_id, template_id, 0)

    if (
        not session.get('recipient') or
        not all_placeholders_in_session(template.placeholders)
    ):
        return redirect(back_link)

    template.values = get_recipient_and_placeholders_from_session(template.template_type)
    return render_template(
        'views/notifications/check.html',
        template=template,
        back_link=back_link,
        help=get_help_argument(),

        **(get_template_error_dict(exception) if exception else {})
    )
Example #11
0
def view_job_csv(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)['data']
    template = service_api_client.get_service_template(
        service_id=service_id,
        template_id=job['template'],
        version=job['template_version']
    )['data']
    filter_args = _parse_filter_args(request.args)
    filter_args['status'] = _set_status_filters(filter_args)

    return (
        generate_notifications_csv(
            notification_api_client.get_notifications_for_service(
                service_id,
                job_id,
                status=filter_args.get('status'),
                page_size=job['notification_count']
            )['notifications']
        ),
        200,
        {
            'Content-Type': 'text/csv; charset=utf-8',
            'Content-Disposition': 'inline; filename="{} - {}.csv"'.format(
                template['name'],
                format_datetime_short(job['created_at'])
            )
        }
    )
Example #12
0
def view_job_csv(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)['data']
    template = service_api_client.get_service_template(
        service_id=service_id,
        template_id=job['template'],
        version=job['template_version'])['data']
    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=job_id,
            status=filter_args.get('status'),
            page=request.args.get('page', 1),
            page_size=5000,
            format_for_csv=True,
            template_type=template['template_type'],
        )),
                    mimetype='text/csv',
                    headers={
                        'Content-Disposition':
                        'inline; filename="{} - {}.csv"'.format(
                            template['name'],
                            format_datetime_short(job['created_at']))
                    })
Example #13
0
def copy_template(service_id, template_id):
    from_service = request.args.get("from_service")

    current_user.belongs_to_service_or_403(from_service)

    template = service_api_client.get_service_template(
        from_service, str(template_id))["data"]

    template_folder = template_folder_api_client.get_template_folder(
        from_service, template["folder"])
    if not current_user.has_template_folder_permission(template_folder):
        abort(403)

    if request.method == "POST":
        return add_service_template(
            service_id,
            template["template_type"],
            template_folder_id=template_folder.get("id"),
        )

    template["template_content"] = template["content"]
    template["name"] = _get_template_copy_name(template,
                                               current_service.all_templates)
    form = form_objects[template["template_type"]](**template)

    return render_template(
        f"views/edit-{template['template_type']}-template.html",
        form=form,
        template=template,
        heading=_l("Copy email template") if template["template_type"]
        == "email" else _l("Copy text message template"),
        service_id=service_id,
        services=current_user.service_ids,
    )
Example #14
0
def view_template(service_id, template_id):
    if not current_user.has_permissions('view_activity'):
        return redirect(
            url_for('.send_one_off',
                    service_id=service_id,
                    template_id=template_id))
    template = service_api_client.get_service_template(
        service_id, str(template_id))['data']
    if template["template_type"] == "letter":
        letter_contact_details = service_api_client.get_letter_contacts(
            service_id)
        default_letter_contact_block_id = next(
            (x['id'] for x in letter_contact_details if x['is_default']), None)
    else:
        default_letter_contact_block_id = None
    return render_template(
        'views/templates/template.html',
        template=get_template(
            template,
            current_service,
            expand_emails=True,
            letter_preview_url=url_for(
                '.view_letter_template_preview',
                service_id=service_id,
                template_id=template_id,
                filetype='png',
            ),
            show_recipient=True,
            page_count=get_page_count_for_letter(template),
        ),
        default_letter_contact_block_id=default_letter_contact_block_id,
    )
Example #15
0
def view_job(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)["data"]

    if job["job_status"] == "cancelled":
        abort(404)

    filter_args = _parse_filter_args(request.args)
    filter_args["status"] = _set_status_filters(filter_args)

    total_notifications = job.get("notification_count", 0)
    processed_notifications = job.get("notifications_delivered", 0) + job.get("notifications_failed", 0)

    return render_template(
        "views/jobs/job.html",
        finished=(total_notifications == processed_notifications),
        uploaded_file_name=job["original_file_name"],
        template=get_template(
            service_api_client.get_service_template(
                service_id=service_id, template_id=job["template"], version=job["template_version"]
            )["data"],
            current_service,
        ),
        status=request.args.get("status", ""),
        updates_url=url_for(
            ".view_job_updates",
            service_id=service_id,
            job_id=job["id"],
            status=request.args.get("status", ""),
            help=get_help_argument(),
        ),
        partials=get_job_partials(job),
        help=get_help_argument(),
    )
Example #16
0
def set_template_sender(service_id, template_id):
    template = service_api_client.get_service_template(service_id,
                                                       template_id)['data']
    sender_details = get_template_sender_form_dict(service_id, template)
    no_senders = sender_details.get('no_senders', False)

    form = SetTemplateSenderForm(
        sender=sender_details['current_choice'],
        sender_choices=sender_details['value_and_label'],
    )
    option_hints = {sender_details['default_sender']: '(Default)'}

    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,
        )
        return redirect(
            url_for('.view_template',
                    service_id=service_id,
                    template_id=template_id))

    return render_template('views/templates/set-template-sender.html',
                           form=form,
                           template_id=template_id,
                           no_senders=no_senders,
                           option_hints=option_hints)
Example #17
0
def view_template_version(service_id, template_id, version):
    return render_template(
        'views/templates/template_history.html',
        template=Template(
            service_api_client.get_service_template(service_id, template_id, version)['data'],
            prefix=current_service['name']
        )
    )
Example #18
0
def view_template(service_id, template_id):
    return render_template(
        'views/templates/template.html',
        template=Template(
            service_api_client.get_service_template(service_id, template_id)['data'],
            prefix=current_service['name']
        )
    )
Example #19
0
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_heading[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'
    )
Example #20
0
def send_messages(service_id, template_id):
    session['sender_id'] = None
    db_template = service_api_client.get_service_template(service_id, template_id)['data']

    if email_or_sms_not_enabled(db_template['template_type'], current_service['permissions']):
        return redirect(url_for(
            '.action_blocked',
            service_id=service_id,
            notification_type=db_template['template_type'],
            return_to='view_template',
            template_id=template_id
        ))

    template = get_template(
        db_template,
        current_service,
        show_recipient=True,
        expand_emails=True,
        letter_preview_url=url_for(
            '.view_letter_template_preview',
            service_id=service_id,
            template_id=template_id,
            filetype='png',
            page_count=get_page_count_for_letter(db_template),
        ),
    )

    form = CsvUploadForm()
    if form.validate_on_submit():
        try:
            upload_id = s3upload(
                service_id,
                Spreadsheet.from_file(form.file.data, filename=form.file.data.filename).as_dict,
                current_app.config['AWS_REGION']
            )
            session['upload_data'] = {
                "template_id": template_id,
                "original_file_name": form.file.data.filename
            }
            return redirect(url_for('.check_messages',
                                    service_id=service_id,
                                    upload_id=upload_id,
                                    template_type=template.template_type))
        except (UnicodeDecodeError, BadZipFile, XLRDError):
            flash('Couldn’t read {}. Try using a different file format.'.format(
                form.file.data.filename
            ))

    column_headings = first_column_headings[template.template_type] + list(template.placeholders)

    return render_template(
        'views/send.html',
        template=template,
        column_headings=list(ascii_uppercase[:len(column_headings)]),
        example=[column_headings, get_example_csv_rows(template)],
        form=form
    )
Example #21
0
def view_template_version(service_id, template_id, version):
    return render_template(
        'views/templates/template_history.html',
        template=get_template(
            service_api_client.get_service_template(service_id, template_id, version)['data'],
            current_service,
            expand_emails=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_heading[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')
Example #23
0
def get_example_csv(service_id, template_id):
    template = Template(service_api_client.get_service_template(service_id, template_id)['data'])
    return Spreadsheet.from_rows([
        [first_column_heading[template.template_type]] + list(template.placeholders),
        get_example_csv_rows(template)
    ]).as_csv_data, 200, {
        'Content-Type': 'text/csv; charset=utf-8',
        'Content-Disposition': 'inline; filename="{}.csv"'.format(template.name)
    }
Example #24
0
def view_letter_template_preview(service_id, template_id, filetype):
    if filetype not in ('pdf', 'png'):
        abort(404)

    db_template = service_api_client.get_service_template(
        service_id, template_id)['data']

    return TemplatePreview.from_database_object(db_template,
                                                filetype,
                                                page=request.args.get('page'))
def view_template_versions(service_id, template_id):
    return render_template(
        'views/templates/choose_history.html',
        template=Template(service_api_client.get_service_template(
            service_id, template_id)['data'],
                          prefix=current_service['name']),
        versions=[
            Template(template, prefix=current_service['name'])
            for template in service_api_client.get_service_template_versions(
                service_id, template_id)['data']
        ])
Example #26
0
def get_example_csv(service_id, template_id):
    template = get_template(
        service_api_client.get_service_template(service_id, template_id)['data'], current_service
    )
    return Spreadsheet.from_rows([
        first_column_headings[template.template_type] + list(template.placeholders),
        get_example_csv_rows(template)
    ]).as_csv_data, 200, {
        'Content-Type': 'text/csv; charset=utf-8',
        'Content-Disposition': 'inline; filename="{}.csv"'.format(template.name)
    }
Example #27
0
def view_job_updates(service_id, job_id):

    job = job_api_client.get_job(service_id, job_id)['data']

    return jsonify(**get_job_partials(
        job,
        service_api_client.get_service_template(
            service_id=current_service.id,
            template_id=job['template'],
            version=job['template_version'])['data'],
    ))
Example #28
0
def send_from_api(service_id, template_id):
    template = Template(
        service_api_client.get_service_template(service_id, template_id)['data'],
        prefix=current_service['name']
    )
    personalisation = {
        placeholder: "..." for placeholder in template.placeholders
    }
    return render_template(
        'views/send-from-api.html',
        template=template,
        personalisation=json.dumps(personalisation, indent=4) if personalisation else None
    )
Example #29
0
def _view_template_version(service_id, template_id, version, letters_as_pdf=False):
    return dict(template=get_template(
        service_api_client.get_service_template(service_id, template_id, version=version)['data'],
        current_service,
        expand_emails=True,
        letter_preview_url=url_for(
            '.view_template_version_preview',
            service_id=service_id,
            template_id=template_id,
            version=version,
            filetype='png',
        ) if not letters_as_pdf else None
    ))
Example #30
0
def view_template_versions(service_id, template_id):
    return render_template(
        'views/templates/choose_history.html',
        template=Template(
            service_api_client.get_service_template(service_id, template_id)['data'],
            prefix=current_service['name']
        ),
        versions=[
            Template(
                template,
                prefix=current_service['name']
            ) for template in service_api_client.get_service_template_versions(service_id, template_id)['data']
        ]
    )
Example #31
0
def view_template_as_dvla_markup(service_id, template_id):

    template = service_api_client.get_service_template(service_id, str(template_id))['data']

    if template['template_type'] != 'letter':
        abort(404)

    return Response(
        str(LetterDVLATemplate(
            template,
            notification_reference=1,
        )),
        mimetype='text/plain',
    )
Example #32
0
def set_sender(service_id, template_id):
    session['sender_id'] = None
    redirect_to_one_off = redirect(
        url_for('.send_one_off',
                service_id=service_id,
                template_id=template_id))

    template = service_api_client.get_service_template(service_id,
                                                       template_id)['data']

    if template['template_type'] == 'letter':
        return redirect_to_one_off

    sender_details = get_sender_details(service_id, template['template_type'])
    if len(sender_details) <= 1:
        return redirect_to_one_off

    sender_context = get_sender_context(sender_details,
                                        template['template_type'])

    form = SetSenderForm(sender=sender_context['default_id'],
                         sender_choices=sender_context['value_and_label'],
                         sender_label=sender_context['description'])
    option_hints = {sender_context['default_id']: '(Default)'}
    if sender_context.get('receives_text_message', None):
        option_hints.update(
            {sender_context['receives_text_message']: '(Receives replies)'})
    if sender_context.get('default_and_receives', None):
        option_hints = {
            sender_context['default_and_receives']:
            '(Default and receives replies)'
        }

    if form.validate_on_submit():
        session['sender_id'] = form.sender.data
        return redirect(
            url_for('.send_one_off',
                    service_id=service_id,
                    template_id=template_id))

    return render_template('views/templates/set-sender.html',
                           form=form,
                           template_id=template_id,
                           sender_context={
                               'title': sender_context['title'],
                               'description': sender_context['description']
                           },
                           option_hints=option_hints)
Example #33
0
def start_tour(service_id, template_id):

    template = service_api_client.get_service_template(service_id, str(template_id))['data']

    if template['template_type'] != 'sms':
        abort(404)

    return render_template(
        'views/templates/start-tour.html',
        template=get_template(
            template,
            current_service,
            show_recipient=True,
        ),
        help='1',
    )
Example #34
0
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,
        ))

    try:
        last_used_notification = template_statistics_client.get_template_statistics_for_template(
            service_id, template['id']
        )
        message = 'It was last used {} ago'.format(
            'more than seven days' if not last_used_notification else 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 = None
        else:
            raise e

    return render_template(
        'views/templates/template.html',
        template_delete_confirmation_message=(
            'Are you sure you want to delete {}?'.format(template['name']),
            message,
        ),
        template=get_template(
            template,
            current_service,
            expand_emails=True,
            letter_preview_url=url_for(
                '.view_letter_template_preview',
                service_id=service_id,
                template_id=template['id'],
                filetype='png',
            ),
            show_recipient=True,
        ),
    )
Example #35
0
def view_job(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)['data']
    if job['job_status'] == 'cancelled':
        abort(404)

    filter_args = parse_filter_args(request.args)
    filter_args['status'] = set_status_filters(filter_args)

    total_notifications = job.get('notification_count', 0)
    processed_notifications = job.get('notifications_delivered', 0) + job.get('notifications_failed', 0)

    template = service_api_client.get_service_template(
        service_id=service_id,
        template_id=job['template'],
        version=job['template_version']
    )['data']

    just_sent_message = 'Your {} been sent. Printing starts {} at 5:30pm.'.format(
        'letter has' if job['notification_count'] == 1 else 'letters have',
        printing_today_or_tomorrow()
    )
    partials = get_job_partials(job, template)
    can_cancel_letter_job = partials["can_letter_job_be_cancelled"]

    return render_template(
        'views/jobs/job.html',
        finished=(total_notifications == processed_notifications),
        uploaded_file_name=job['original_file_name'],
        template_id=job['template'],
        job_id=job_id,
        status=request.args.get('status', ''),
        updates_url=url_for(
            ".view_job_updates",
            service_id=service_id,
            job_id=job['id'],
            status=request.args.get('status', ''),
        ),
        partials=partials,
        just_sent=bool(
            request.args.get('just_sent') == 'yes'
            and template['template_type'] == 'letter'
        ),
        just_sent_message=just_sent_message,
        can_cancel_letter_job=can_cancel_letter_job,
    )
Example #36
0
def view_job(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)["data"]
    if job["job_status"] == "cancelled":
        abort(404)

    filter_args = parse_filter_args(request.args)
    filter_args["status"] = set_status_filters(filter_args)

    total_notifications = job.get("notification_count", 0)
    processed_notifications = job.get("notifications_delivered", 0) + job.get(
        "notifications_failed", 0)

    template = service_api_client.get_service_template(
        service_id=service_id,
        template_id=job["template"],
        version=job["template_version"],
    )["data"]

    just_sent_message = "Your {} been sent. Printing starts {} at 5:30pm.".format(
        "letter has" if job["notification_count"] == 1 else "letters have",
        printing_today_or_tomorrow(),
    )
    partials = get_job_partials(job, template)
    can_cancel_letter_job = partials["can_letter_job_be_cancelled"]

    return render_template(
        "views/jobs/job.html",
        finished=(total_notifications == processed_notifications),
        uploaded_file_name=job["original_file_name"],
        template_id=job["template"],
        job_id=job_id,
        status=request.args.get("status", ""),
        updates_url=url_for(
            ".view_job_updates",
            service_id=service_id,
            job_id=job["id"],
            status=request.args.get("status", ""),
        ),
        partials=partials,
        just_sent=bool(
            request.args.get("just_sent") == "yes"
            and template["template_type"] == "letter"),
        just_sent_message=just_sent_message,
        can_cancel_letter_job=can_cancel_letter_job,
    )
Example #37
0
def get_example_csv(service_id, template_id):
    template = get_template(
        service_api_client.get_service_template(service_id,
                                                template_id)["data"],
        current_service,
    )
    return (
        Spreadsheet.from_rows([
            get_spreadsheet_column_headings_from_template(template),
            get_example_csv_rows(template),
        ]).as_csv_data,
        200,
        {
            "Content-Type":
            "text/csv; charset=utf-8",
            "Content-Disposition":
            'inline; filename="{}.csv"'.format(template.name),
        },
    )
Example #38
0
def confirm_redact_template(service_id, template_id):
    template = service_api_client.get_service_template(service_id, template_id)['data']

    return render_template(
        'views/templates/template.html',
        template=get_template(
            template,
            current_service,
            expand_emails=True,
            letter_preview_url=url_for(
                '.view_letter_template_preview',
                service_id=service_id,
                template_id=template_id,
                filetype='png',
            ),
            show_recipient=True,
        ),
        show_redaction_message=True,
    )
Example #39
0
def send_test(service_id, template_id):

    file_name = current_app.config['TEST_MESSAGE_FILENAME']

    template = Template(
        service_api_client.get_service_template(service_id, template_id)['data'],
        prefix=current_service['name']
    )

    if len(template.placeholders) == 0 or request.method == 'POST':
        upload_id = s3upload(
            service_id,
            {
                'file_name': file_name,
                'data': Spreadsheet.from_rows([
                    [first_column_heading[template.template_type]] + list(template.placeholders),
                    get_example_csv_rows(template, use_example_as_example=False, submitted_fields=request.form)
                ]).as_csv_data
            },
            current_app.config['AWS_REGION']
        )
        session['upload_data'] = {
            "template_id": template_id,
            "original_file_name": file_name
        }
        return redirect(url_for(
            '.check_messages',
            upload_id=upload_id,
            service_id=service_id,
            template_type=template.template_type,
            from_test=True,
            help=2 if request.args.get('help') else 0
        ))

    return render_template(
        'views/send-test.html',
        template=template,
        recipient_column=first_column_heading[template.template_type],
        example=[get_example_csv_rows(template, use_example_as_example=False)],
        help=get_help_argument()
    )
Example #40
0
def send_test(service_id, template_id):

    file_name = current_app.config['TEST_MESSAGE_FILENAME']

    template = Template(service_api_client.get_service_template(
        service_id, template_id)['data'],
                        prefix=current_service['name'],
                        sms_sender=current_service['sms_sender'])

    if len(template.placeholders) == 0 or request.method == 'POST':
        upload_id = s3upload(
            service_id, {
                'file_name':
                file_name,
                'data':
                Spreadsheet.from_rows([
                    [first_column_heading[template.template_type]] +
                    list(template.placeholders),
                    get_example_csv_rows(template,
                                         use_example_as_example=False,
                                         submitted_fields=request.form)
                ]).as_csv_data
            }, current_app.config['AWS_REGION'])
        session['upload_data'] = {
            "template_id": template_id,
            "original_file_name": file_name
        }
        return redirect(
            url_for('.check_messages',
                    upload_id=upload_id,
                    service_id=service_id,
                    template_type=template.template_type,
                    from_test=True,
                    help=2 if request.args.get('help') else 0))

    return render_template(
        'views/send-test.html',
        template=template,
        recipient_column=first_column_heading[template.template_type],
        example=[get_example_csv_rows(template, use_example_as_example=False)],
        help=get_help_argument())
Example #41
0
def send_test_preview(service_id, template_id, filetype):

    if filetype not in ('pdf', 'png'):
        abort(404)

    db_template = service_api_client.get_service_template(service_id, template_id)['data']

    template = get_template(
        db_template,
        current_service,
        letter_preview_url=url_for(
            '.send_test_preview',
            service_id=service_id,
            template_id=template_id,
            filetype='png',
        ),
    )

    template.values = get_normalised_placeholders_from_session()

    return TemplatePreview.from_utils_template(template, filetype, page=request.args.get('page'))
Example #42
0
def view_job_csv(service_id, job_id):
    job = job_api_client.get_job(service_id, job_id)["data"]
    template = service_api_client.get_service_template(
        service_id=service_id, template_id=job["template"], version=job["template_version"]
    )["data"]
    filter_args = _parse_filter_args(request.args)
    filter_args["status"] = _set_status_filters(filter_args)

    return (
        generate_notifications_csv(
            notification_api_client.get_notifications_for_service(
                service_id, job_id, status=filter_args.get("status"), page_size=job["notification_count"]
            )["notifications"]
        ),
        200,
        {
            "Content-Type": "text/csv; charset=utf-8",
            "Content-Disposition": 'inline; filename="{} - {}.csv"'.format(
                template["name"], format_datetime_short(job["created_at"])
            ),
        },
    )
Example #43
0
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)

    template_statistics = template_statistics_client.get_template_statistics_for_template(service_id, template['id'])
    last_use_message = get_last_use_message(form.name.data, template_statistics)
    flash('{}. Are you sure you want to delete it?'.format(last_use_message), 'delete')
    return render_template(
        'views/edit-{}-template.html'.format(template['template_type']),
        h1='Edit template',
        form=form,
        template_id=template_id)
Example #44
0
def send_messages(service_id, template_id):
    template = Template(
        service_api_client.get_service_template(service_id, template_id)['data'],
        prefix=current_service['name']
    )

    form = CsvUploadForm()
    if form.validate_on_submit():
        try:
            upload_id = s3upload(
                service_id,
                Spreadsheet.from_file(form.file.data, filename=form.file.data.filename).as_dict,
                current_app.config['AWS_REGION']
            )
            session['upload_data'] = {
                "template_id": template_id,
                "original_file_name": form.file.data.filename
            }
            return redirect(url_for('.check_messages',
                                    service_id=service_id,
                                    upload_id=upload_id,
                                    template_type=template.template_type))
        except (UnicodeDecodeError, BadZipFile, XLRDError):
            flash('Couldn’t read {}. Try using a different file format.'.format(
                form.file.data.filename
            ))

    return render_template(
        'views/send.html',
        template=template,
        column_headings=list(ascii_uppercase[:len(template.placeholders) + 1]),
        example=[
            [first_column_heading[template.template_type]] + list(template.placeholders),
            get_example_csv_rows(template)
        ],
        form=form
    )
Example #45
0
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)
Example #46
0
def check_messages(service_id, template_type, upload_id):

    if not session.get('upload_data'):
        return redirect(url_for('main.choose_template', service_id=service_id, template_type=template_type))

    users = user_api_client.get_users_for_service(service_id=service_id)
    today = datetime.utcnow().date().strftime('%Y-%m-%d')

    statistics = statistics_api_client.get_statistics_for_service_for_day(service_id, today)
    if not statistics:
        statistics = {}

    contents = s3download(service_id, upload_id)
    if not contents:
        flash('There was a problem reading your upload file')

    template = service_api_client.get_service_template(
        service_id,
        session['upload_data'].get('template_id')
    )['data']

    template = Template(
        template,
        prefix=current_service['name']
    )

    recipients = RecipientCSV(
        contents,
        template_type=template.template_type,
        placeholders=template.placeholders,
        max_initial_rows_shown=50,
        max_errors_shown=50,
        whitelist=itertools.chain.from_iterable(
            [user.mobile_number, user.email_address] for user in users
        ) if current_service['restricted'] else None
    )

    if request.args.get('from_test'):
        extra_args = {'help': 1} if request.args.get('help', '0') != '0' else {}
        if len(template.placeholders):
            back_link = url_for(
                '.send_test', service_id=service_id, template_id=template.id, **extra_args
            )
        else:
            back_link = url_for(
                '.choose_template', service_id=service_id, template_type=template.template_type, **extra_args
            )
    else:
        back_link = url_for('.send_messages', service_id=service_id, template_id=template.id)

    with suppress(StopIteration):
        template.values = next(recipients.rows)
        first_recipient = template.values.get(recipients.recipient_column_header, '')

    session['upload_data']['notification_count'] = len(list(recipients.rows))
    session['upload_data']['valid'] = not recipients.has_errors
    return render_template(
        'views/check.html',
        recipients=recipients,
        first_recipient=first_recipient,
        template=template,
        errors=recipients.has_errors,
        row_errors=get_errors_for_csv(recipients, template.template_type),
        count_of_recipients=session['upload_data']['notification_count'],
        count_of_displayed_recipients=(
            len(list(recipients.initial_annotated_rows_with_errors))
            if any(recipients.rows_with_errors) and not recipients.missing_column_headers else
            len(list(recipients.initial_annotated_rows))
        ),
        original_file_name=session['upload_data'].get('original_file_name'),
        upload_id=upload_id,
        form=CsvUploadForm(),
        statistics=statistics,
        back_link=back_link,
        help=get_help_argument()
    )
Example #47
0
def view_letter_template_as_pdf(service_id, template_id):
    return render_pdf(HTML(string=str(
        LetterPreviewTemplate(
            service_api_client.get_service_template(service_id, template_id)['data'],
        )
    )))