diff --git a/requirements.txt b/requirements.txt index 2ec18e9..c69630d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -flask==1.1.1 +Flask==1.1.1 +Flask-Cors==3.0.8 diff --git a/vocoder/archive/.git-dont-delete-me b/vocoder/archive/.git-dont-delete-me new file mode 100644 index 0000000..e69de29 diff --git a/vocoder/archive/1576912779691.wav b/vocoder/archive/1576912779691.wav new file mode 100644 index 0000000..afc1d37 Binary files /dev/null and b/vocoder/archive/1576912779691.wav differ diff --git a/vocoder/archive/1576913885010.wav b/vocoder/archive/1576913885010.wav new file mode 100644 index 0000000..694d8b5 Binary files /dev/null and b/vocoder/archive/1576913885010.wav differ diff --git a/vocoder/archive/1576913887050.wav b/vocoder/archive/1576913887050.wav new file mode 100644 index 0000000..6859cf9 Binary files /dev/null and b/vocoder/archive/1576913887050.wav differ diff --git a/vocoder/archive/1576913915047.wav b/vocoder/archive/1576913915047.wav new file mode 100644 index 0000000..cc0c86c Binary files /dev/null and b/vocoder/archive/1576913915047.wav differ diff --git a/vocoder/server.py b/vocoder/server.py index 01cce1b..23d63ba 100644 --- a/vocoder/server.py +++ b/vocoder/server.py @@ -1,9 +1,23 @@ """Flask server for the vocoder back-end.""" -from flask import Flask, render_template, request +import os.path +from pathlib import Path + +from flask import Flask, render_template, request, send_from_directory +from flask_cors import CORS +from werkzeug.utils import secure_filename + +ALLOWED_UPLOAD_EXTENSIONS = {"wav"} +UPLOAD_DIRECTORY = Path(__file__).parent / "archive" +MAXIMUM_FILE_SIZE = 16 * 1024 * 1024 # 16 MB app = Flask(__name__) +app.config["UPLOAD_FOLDER"] = UPLOAD_DIRECTORY +app.config["MAX_CONTENT_LENGTH"] = MAXIMUM_FILE_SIZE + +CORS(app) + @app.route("/") def root(): @@ -11,16 +25,38 @@ def root(): return render_template("index.html") -@app.route("/add-to-archive/", methods=["POST"]) +def allowed_file(filename): + """Validate uploaded file extensions.""" + extension = filename.rsplit(".", 1)[1].lower() + return "." in filename and extension in ALLOWED_UPLOAD_EXTENSIONS + + +@app.route("/add-to-archive", methods=["POST"]) def add_to_archive(): - """Accept audio recordings for archiving.""" - # TODO: implement the saving of the files currently, - # I can't seem to get the file to send but the basic - # plumbing is in place - return ("faking it till we make it", 201) + """Archive recordings sent from the front-end.""" + try: + file = request.files["file"] + except KeyError: + return ("Missing file for upload", 400) + + if not allowed_file(file.filename): + return ("File extension not allowed", 400) + + secured = secure_filename(file.filename) + file.save(os.path.join(app.config["UPLOAD_FOLDER"], secured)) + + return ("file archived successfully", 201) + + +@app.route("/archives/") +def uploaded_file(filename): + """Retrieve an uploaded recording.""" + return send_from_directory(app.config["UPLOAD_FOLDER"], filename) -@app.route("/archive/") +@app.route("/archive") def archive(): """Serve the archive listing.""" - return render_template("archive.html") + listing = os.listdir(UPLOAD_DIRECTORY) + files = filter(lambda f: f.endswith(".wav"), listing) + return render_template("archive.html", files=files) diff --git a/vocoder/static/vocoder.js b/vocoder/static/vocoder.js index 8de1cc9..a7bd029 100644 --- a/vocoder/static/vocoder.js +++ b/vocoder/static/vocoder.js @@ -7,7 +7,7 @@ // https://developer.mozilla.org/en-US/docs/web/javascript/reference // -var archiveUrl = serverUrl + "/add-to-archive/"; +var archiveUrl = "http://localhost:5000/add-to-archive"; var canvasColour = "white"; var canvasHeight = 400; var canvasWidth = 800; @@ -19,7 +19,6 @@ var recordButton; var recorder; var recording; var recordingTimeout = 30000; // 30 seconds (in milliseconds) -var serverUrl = "http://localhost:5000"; // TODO: read from environment var shapes = []; var stopButton; @@ -57,13 +56,20 @@ function archive() { **/ var soundBlob = recording.getBlob(); - var httpRequestOptions = { - method: "POST", - body: new FormData().append("soundBlob", soundBlob), - headers: new Headers({ enctype: "multipart/form-data" }) - }; + var formData = new FormData(); + var date = new Date(); + var filename = date.getTime().toString() + ".wav"; + formData.append("file", soundBlob, filename); - httpDo(archiveUrl, httpRequestOptions); // TODO: add error handling and fix + var config = new Headers({ "Content-Type": "multipart/form-data" }); + + axios.post(archiveUrl, formData, config).catch(function(error) { + console.log( + "Upload failed!", + "Received the following message:", + error.response.data + ); + }); } function setupRecording() { diff --git a/vocoder/templates/archive.html b/vocoder/templates/archive.html index 2a53a52..c25248b 100644 --- a/vocoder/templates/archive.html +++ b/vocoder/templates/archive.html @@ -8,9 +8,14 @@ + - -

Coming Soon TM.

diff --git a/vocoder/templates/index.html b/vocoder/templates/index.html index 74ab25b..2b9853c 100644 --- a/vocoder/templates/index.html +++ b/vocoder/templates/index.html @@ -20,7 +20,7 @@ @@ -28,6 +28,7 @@ +