mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-05 02:42:26 -05:00
Changed page flow to first save file and then redirect to check.
On check numbers in file are validated. Posting to check then uploads file to s3
This commit is contained in:
15
app/main/uploader.py
Normal file
15
app/main/uploader.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import os
|
||||
import uuid
|
||||
|
||||
from boto3 import resource
|
||||
|
||||
|
||||
# TODO add service name to bucket name as well
|
||||
def s3upload(filepath):
|
||||
filename = filepath.split(os.path.sep)[-1]
|
||||
upload_id = str(uuid.uuid4())
|
||||
s3 = resource('s3')
|
||||
s3.create_bucket(Bucket=upload_id)
|
||||
key = s3.Object(upload_id, filename)
|
||||
key.put(Body=open(filepath, 'rb'), ServerSideEncryption='AES256')
|
||||
return upload_id
|
||||
@@ -1,11 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import time
|
||||
from flask import render_template
|
||||
|
||||
from flask import (
|
||||
render_template,
|
||||
session
|
||||
)
|
||||
from flask_login import login_required
|
||||
|
||||
from app.main import main
|
||||
|
||||
from ._jobs import jobs
|
||||
|
||||
now = time.strftime('%H:%M')
|
||||
@@ -55,6 +58,11 @@ def showjobs(service_id):
|
||||
@main.route("/services/<int:service_id>/jobs/<job_id>")
|
||||
@login_required
|
||||
def showjob(service_id, job_id):
|
||||
|
||||
# TODO the uploaded file name could be part of job definition
|
||||
# so won't need to be passed on from last view via session
|
||||
uploaded_file_name = session.get(job_id)
|
||||
|
||||
return render_template(
|
||||
'views/job.html',
|
||||
messages=messages,
|
||||
@@ -68,7 +76,7 @@ def showjob(service_id, job_id):
|
||||
])
|
||||
},
|
||||
cost=u'£0.00',
|
||||
uploaded_file_name='dispatch_20151114.csv',
|
||||
uploaded_file_name=uploaded_file_name,
|
||||
uploaded_file_time=now,
|
||||
template_used='Test message 1',
|
||||
flash_message=u'We’ve started sending your messages',
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import csv
|
||||
import re
|
||||
import os
|
||||
|
||||
from datetime import date
|
||||
|
||||
from flask import (
|
||||
request,
|
||||
@@ -12,9 +15,11 @@ from flask import (
|
||||
)
|
||||
|
||||
from flask_login import login_required
|
||||
from werkzeug import secure_filename
|
||||
|
||||
from app.main import main
|
||||
from app.main.forms import CsvUploadForm
|
||||
from app.main.uploader import s3upload
|
||||
|
||||
# TODO move this to the templates directory
|
||||
message_templates = [
|
||||
@@ -39,26 +44,27 @@ message_templates = [
|
||||
@login_required
|
||||
def sendsms(service_id):
|
||||
form = CsvUploadForm()
|
||||
if form.validate_on_submit():
|
||||
csv_file = form.file.data
|
||||
|
||||
# in memory handing is temporary until next story to save csv file
|
||||
if form.validate_on_submit():
|
||||
try:
|
||||
results = _build_upload_result(csv_file)
|
||||
except Exception:
|
||||
message = 'There was a problem with the file: {}'.format(
|
||||
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)
|
||||
return redirect(url_for('.checksms',
|
||||
service_id=service_id,
|
||||
recipients=filename))
|
||||
except (IOError, 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)
|
||||
return redirect(url_for('.sendsms', service_id=service_id))
|
||||
|
||||
if not results['valid'] and not results['rejects']:
|
||||
message = "The file {} contained no data".format(csv_file.filename)
|
||||
flash(message, 'error')
|
||||
return redirect(url_for('.sendsms', service_id=service_id))
|
||||
|
||||
session[csv_file.filename] = results
|
||||
return redirect(url_for('.checksms', service_id=service_id, recipients=csv_file.filename))
|
||||
|
||||
return render_template('views/send-sms.html',
|
||||
message_templates=message_templates,
|
||||
form=form,
|
||||
@@ -69,33 +75,59 @@ def sendsms(service_id):
|
||||
@login_required
|
||||
def checksms(service_id):
|
||||
if request.method == 'GET':
|
||||
|
||||
recipients_filename = request.args.get('recipients')
|
||||
# upload results in session until file is persisted in next story
|
||||
upload_result = session.get(recipients_filename)
|
||||
filename = request.args.get('recipients')
|
||||
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')
|
||||
|
||||
return render_template(
|
||||
'views/check-sms.html',
|
||||
upload_result=upload_result,
|
||||
filename=filename,
|
||||
message_template=message_templates[0]['body'],
|
||||
service_id=service_id
|
||||
)
|
||||
elif request.method == 'POST':
|
||||
return redirect(url_for('.showjob', service_id=service_id, job_id=456))
|
||||
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('.showjob', service_id=service_id, job_id=upload_id))
|
||||
except:
|
||||
flash('There as a problem saving the file')
|
||||
return redirect(url_for('.checksms', recipients=filename))
|
||||
|
||||
|
||||
def _check_file(filename, filepath):
|
||||
if os.stat(filepath).st_size == 0:
|
||||
message = 'The file {} contained no data'.format(filename)
|
||||
raise ValueError(message)
|
||||
|
||||
|
||||
def _format_filename(filename):
|
||||
d = date.today()
|
||||
basename, extenstion = filename.split('.')
|
||||
formatted_name = '{}_{}.csv'.format(basename, d.strftime('%Y%m%d'))
|
||||
return secure_filename(formatted_name)
|
||||
|
||||
|
||||
def _build_upload_result(csv_file):
|
||||
pattern = re.compile(r'^\+44\s?\d{4}\s?\d{6}$')
|
||||
reader = csv.DictReader(
|
||||
csv_file.read().decode('utf-8').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']})
|
||||
with open(csv_file) as f:
|
||||
reader = csv.DictReader(
|
||||
f,
|
||||
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}
|
||||
|
||||
@@ -59,6 +59,8 @@
|
||||
back_link = url_for(".sendsms", service_id=service_id)
|
||||
)}}
|
||||
|
||||
<input type='hidden' name='recipients' value='{{filename}}'>
|
||||
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user