mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-25 16:54:03 -04:00
Merge with master.
This commit is contained in:
39
app/main/views/_templates.py
Normal file
39
app/main/views/_templates.py
Normal file
@@ -0,0 +1,39 @@
|
||||
templates = [
|
||||
{
|
||||
'type': 'sms',
|
||||
'name': 'Confirmation',
|
||||
'body': 'Lasting power of attorney: We’ve received your application. Applications take between 8 and 10 weeks to process.' # noqa
|
||||
},
|
||||
{
|
||||
'type': 'sms',
|
||||
'name': 'Reminder',
|
||||
'body': 'Vehicle tax: Your vehicle tax for ((registration number)) expires on ((date)). Tax your vehicle at www.gov.uk/vehicle-tax' # noqa
|
||||
},
|
||||
{
|
||||
'type': 'sms',
|
||||
'name': 'Warning',
|
||||
'body': 'Vehicle tax: Your vehicle tax for ((registration number)) has expired. Tax your vehicle at www.gov.uk/vehicle-tax' # noqa
|
||||
},
|
||||
{
|
||||
'type': 'email',
|
||||
'name': 'Application alert 06/2016',
|
||||
'subject': 'Your lasting power of attorney application',
|
||||
'body': """Dear ((name)),
|
||||
|
||||
When you’ve made your lasting power of attorney (LPA), you need to register it \
|
||||
with the Office of the Public Guardian (OPG).
|
||||
|
||||
You can apply to register your LPA yourself if you’re able to make your own decisions.
|
||||
|
||||
Your attorney can also register it for you. You’ll be told if they do and you can \
|
||||
object to the registration.
|
||||
|
||||
It takes between 8 and 10 weeks to register an LPA if there are no mistakes in the application.
|
||||
"""
|
||||
},
|
||||
{
|
||||
'type': 'sms',
|
||||
'name': 'Air quality alert',
|
||||
'body': 'Air pollution levels will be ((level)) in ((region)) tomorrow.'
|
||||
},
|
||||
]
|
||||
@@ -1,4 +1,4 @@
|
||||
from flask import render_template, jsonify, redirect, session, url_for
|
||||
from flask import request, render_template, jsonify, redirect, session, url_for, abort
|
||||
from flask_login import login_required
|
||||
from app.main import main
|
||||
from app.main.dao import services_dao, users_dao
|
||||
@@ -8,11 +8,19 @@ from app.main.forms import AddServiceForm
|
||||
@main.route("/add-service", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_service():
|
||||
# TODO fix up this
|
||||
form = AddServiceForm(services_dao.find_all_service_names)
|
||||
services = services_dao.get_services()
|
||||
if len(services) > 0:
|
||||
heading = 'Set up notifications for your service'
|
||||
else:
|
||||
heading = 'Add a new service'
|
||||
if form.validate_on_submit():
|
||||
user = users_dao.get_user_by_id(session['user_id'])
|
||||
service_id = services_dao.insert_new_service(form.name.data, user)
|
||||
return redirect(url_for('main.service_dashboard', service_id=service_id))
|
||||
else:
|
||||
return render_template('views/add-service.html', form=form)
|
||||
return render_template(
|
||||
'views/add-service.html',
|
||||
form=form,
|
||||
heading=heading
|
||||
)
|
||||
|
||||
9
app/main/views/api_keys.py
Normal file
9
app/main/views/api_keys.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from flask import render_template
|
||||
from flask_login import login_required
|
||||
from app.main import main
|
||||
|
||||
|
||||
@main.route("/services/<int:service_id>/api-keys")
|
||||
@login_required
|
||||
def api_keys(service_id):
|
||||
return render_template('views/api-keys.html', service_id=service_id)
|
||||
@@ -36,9 +36,3 @@ def check_email(service_id):
|
||||
@login_required
|
||||
def manage_users(service_id):
|
||||
return render_template('views/manage-users.html', service_id=service_id)
|
||||
|
||||
|
||||
@main.route("/services/<int:service_id>/api-keys")
|
||||
@login_required
|
||||
def apikeys(service_id):
|
||||
return render_template('views/api-keys.html', service_id=service_id)
|
||||
|
||||
@@ -20,24 +20,15 @@ from werkzeug import secure_filename
|
||||
|
||||
from app.main import main
|
||||
from app.main.forms import CsvUploadForm
|
||||
from app.main.uploader import s3upload
|
||||
from app.main.uploader import (
|
||||
s3upload,
|
||||
s3download
|
||||
)
|
||||
|
||||
# TODO move this to the templates directory
|
||||
message_templates = [
|
||||
{
|
||||
'name': 'Reminder',
|
||||
'body': """
|
||||
Vehicle tax: Your vehicle tax for ((registration number)) expires on ((date)).
|
||||
Tax your vehicle at www.gov.uk/vehicle-tax
|
||||
"""
|
||||
},
|
||||
{
|
||||
'name': 'Warning',
|
||||
'body': """
|
||||
Vehicle tax: Your vehicle tax for ((registration number)) has expired.
|
||||
Tax your vehicle at www.gov.uk/vehicle-tax
|
||||
"""
|
||||
},
|
||||
from ._templates import templates
|
||||
|
||||
sms_templates = [
|
||||
template for template in templates if template['type'] == 'sms'
|
||||
]
|
||||
|
||||
|
||||
@@ -48,68 +39,52 @@ def send_sms(service_id):
|
||||
if form.validate_on_submit():
|
||||
try:
|
||||
csv_file = form.file.data
|
||||
filename = _format_filename(csv_file.filename)
|
||||
filepath = os.path.join(current_app.config['UPLOAD_FOLDER'],
|
||||
filename)
|
||||
csv_file.save(filepath)
|
||||
_check_file(csv_file.filename, filepath)
|
||||
filedata = _get_filedata(csv_file)
|
||||
upload_id = s3upload(service_id, filedata)
|
||||
return redirect(url_for('.check_sms',
|
||||
service_id=service_id,
|
||||
recipients=filename))
|
||||
except (IOError, ValueError) as e:
|
||||
upload_id=upload_id))
|
||||
except ValueError as e:
|
||||
message = 'There was a problem uploading: {}'.format(
|
||||
csv_file.filename)
|
||||
flash(message)
|
||||
if isinstance(e, ValueError):
|
||||
flash(str(e))
|
||||
os.remove(filepath)
|
||||
flash(str(e))
|
||||
return redirect(url_for('.send_sms', service_id=service_id))
|
||||
|
||||
return render_template('views/send-sms.html',
|
||||
message_templates=message_templates,
|
||||
message_templates=sms_templates,
|
||||
form=form,
|
||||
service_id=service_id)
|
||||
|
||||
|
||||
@main.route("/services/<int:service_id>/sms/check", methods=['GET', 'POST'])
|
||||
@main.route("/services/<int:service_id>/sms/check/<upload_id>",
|
||||
methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def check_sms(service_id):
|
||||
def check_sms(service_id, upload_id):
|
||||
if request.method == 'GET':
|
||||
filename = request.args.get('recipients')
|
||||
if not filename:
|
||||
abort(400)
|
||||
filepath = os.path.join(current_app.config['UPLOAD_FOLDER'],
|
||||
filename)
|
||||
upload_result = _build_upload_result(filepath)
|
||||
if upload_result.get('rejects'):
|
||||
flash('There was a problem with some of the numbers')
|
||||
|
||||
contents = s3download(service_id, upload_id)
|
||||
upload_result = _get_numbers(contents)
|
||||
# TODO get original file name
|
||||
return render_template(
|
||||
'views/check-sms.html',
|
||||
upload_result=upload_result,
|
||||
filename=filename,
|
||||
message_template=message_templates[0]['body'],
|
||||
filename='someupload_file_name.csv',
|
||||
message_template=sms_templates[0]['body'],
|
||||
service_id=service_id
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
filename = request.form['recipients']
|
||||
filepath = os.path.join(current_app.config['UPLOAD_FOLDER'],
|
||||
filename)
|
||||
try:
|
||||
upload_id = s3upload(filepath)
|
||||
# TODO when job is created record filename in job itself
|
||||
# so downstream pages can get the original filename that way
|
||||
session[upload_id] = filename
|
||||
return redirect(url_for('main.view_job', service_id=service_id, job_id=upload_id))
|
||||
except:
|
||||
flash('There as a problem saving the file')
|
||||
return redirect(url_for('.check_sms', recipients=filename))
|
||||
# TODO create the job with template, file location etc.
|
||||
return redirect(url_for('main.view_job',
|
||||
service_id=service_id,
|
||||
job_id=upload_id))
|
||||
|
||||
|
||||
def _check_file(filename, filepath):
|
||||
if os.stat(filepath).st_size == 0:
|
||||
message = 'The file {} contained no data'.format(filename)
|
||||
def _get_filedata(file):
|
||||
lines = file.read().decode('utf-8').splitlines()
|
||||
if len(lines) < 2: # must be at least header and one line
|
||||
message = 'The file {} contained no data'.format(file.filename)
|
||||
raise ValueError(message)
|
||||
return {'filename': file.filename, 'data': lines}
|
||||
|
||||
|
||||
def _format_filename(filename):
|
||||
@@ -119,24 +94,16 @@ def _format_filename(filename):
|
||||
return secure_filename(formatted_name)
|
||||
|
||||
|
||||
def _open(file):
|
||||
return open(file, 'r')
|
||||
|
||||
|
||||
def _build_upload_result(csv_file):
|
||||
try:
|
||||
file = _open(csv_file, 'r')
|
||||
pattern = re.compile(r'^\+44\s?\d{4}\s?\d{6}$')
|
||||
reader = csv.DictReader(
|
||||
file.read().splitlines(),
|
||||
lineterminator='\n',
|
||||
quoting=csv.QUOTE_NONE)
|
||||
valid, rejects = [], []
|
||||
for i, row in enumerate(reader):
|
||||
if pattern.match(row['phone']):
|
||||
valid.append(row)
|
||||
else:
|
||||
rejects.append({"line_number": i+2, "phone": row['phone']})
|
||||
return {"valid": valid, "rejects": rejects}
|
||||
finally:
|
||||
file.close()
|
||||
def _get_numbers(contents):
|
||||
pattern = re.compile(r'^\+44\s?\d{4}\s?\d{6}$') # need better validation
|
||||
reader = csv.DictReader(
|
||||
contents.split('\n'),
|
||||
lineterminator='\n',
|
||||
quoting=csv.QUOTE_NONE)
|
||||
valid, rejects = [], []
|
||||
for i, row in enumerate(reader):
|
||||
if pattern.match(row['phone']):
|
||||
valid.append(row)
|
||||
else:
|
||||
rejects.append({"line_number": i+2, "phone": row['phone']})
|
||||
return {"valid": valid, "rejects": rejects}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
from flask import request, render_template, redirect, url_for
|
||||
from flask import request, render_template, redirect, url_for, flash
|
||||
from flask_login import login_required
|
||||
|
||||
from app.main import main
|
||||
from app.main.forms import TemplateForm
|
||||
|
||||
from ._templates import templates
|
||||
|
||||
|
||||
@main.route("/services/<int:service_id>/templates")
|
||||
@login_required
|
||||
def manage_templates(service_id):
|
||||
return render_template(
|
||||
'views/manage-templates.html',
|
||||
service_id=service_id
|
||||
service_id=service_id,
|
||||
templates=templates,
|
||||
)
|
||||
|
||||
|
||||
@@ -31,21 +34,49 @@ def add_template(service_id):
|
||||
return redirect(url_for('.manage_templates', service_id=service_id))
|
||||
|
||||
|
||||
@main.route("/services/<int:service_id>/templates/<template_id>", methods=['GET', 'POST'])
|
||||
@main.route("/services/<int:service_id>/templates/<int:template_id>", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_template(service_id, template_id):
|
||||
|
||||
form = TemplateForm()
|
||||
|
||||
form.template_name.data = 'Reminder'
|
||||
form.template_body.data = 'Vehicle tax: Your vehicle tax for ((registration number)) expires on ((date)). Tax your vehicle at www.gov.uk/vehicle-tax' # noqa
|
||||
form.template_name.data = templates[template_id - 1]['name']
|
||||
form.template_body.data = templates[template_id - 1]['body']
|
||||
|
||||
if request.method == 'GET':
|
||||
return render_template(
|
||||
'views/edit-template.html',
|
||||
h1='Edit template',
|
||||
form=form,
|
||||
service_id=service_id
|
||||
service_id=service_id,
|
||||
template_id=template_id
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
return redirect(url_for('.manage_templates', service_id=service_id))
|
||||
|
||||
|
||||
@main.route("/services/<int:service_id>/templates/<int:template_id>/delete", methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_template(service_id, template_id):
|
||||
|
||||
form = TemplateForm()
|
||||
|
||||
form.template_name.data = templates[template_id - 1]['name']
|
||||
form.template_body.data = templates[template_id - 1]['body']
|
||||
|
||||
if request.method == 'GET':
|
||||
|
||||
flash('Are you sure you want to delete ‘{}’?'.format(form.template_name.data), 'delete')
|
||||
|
||||
return render_template(
|
||||
'views/edit-template.html',
|
||||
h1='Edit template',
|
||||
form=form,
|
||||
service_id=service_id,
|
||||
template_id=template_id
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
if request.form.get('delete'):
|
||||
return redirect(url_for('.manage_templates', service_id=service_id))
|
||||
else:
|
||||
return redirect(url_for('.manage_templates', service_id=service_id))
|
||||
|
||||
@@ -20,5 +20,5 @@ def verify():
|
||||
verify_codes_dao.use_code_for_user_and_type(user_id=user.id, code_type='sms')
|
||||
users_dao.activate_user(user.id)
|
||||
login_user(user)
|
||||
return redirect(url_for('.add_service'))
|
||||
return redirect(url_for('.add_service', first='first'))
|
||||
return render_template('views/verify.html', form=form)
|
||||
|
||||
Reference in New Issue
Block a user