aboutsummaryrefslogtreecommitdiff
path: root/qc_app/entry.py
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2022-06-10 08:06:47 +0300
committerFrederick Muriuki Muriithi2022-06-10 08:06:47 +0300
commit557d1d5c19ab518fa7abb3229c6d9042867e6c00 (patch)
tree97b2ca39fe49600da74dbfa9ca358fa97f114a92 /qc_app/entry.py
parent35a9cf67a9e055925f11a12c9fb964e5dbeb5525 (diff)
downloadgn-uploader-557d1d5c19ab518fa7abb3229c6d9042867e6c00.tar.gz
Enable upload of zipfiles
Diffstat (limited to 'qc_app/entry.py')
-rw-r--r--qc_app/entry.py96
1 files changed, 75 insertions, 21 deletions
diff --git a/qc_app/entry.py b/qc_app/entry.py
index b7b4b6f..25e2eed 100644
--- a/qc_app/entry.py
+++ b/qc_app/entry.py
@@ -1,5 +1,10 @@
"""Entry-point module"""
import os
+import random
+import string
+import mimetypes
+from typing import Tuple
+from zipfile import ZipFile, is_zipfile
from werkzeug.utils import secure_filename
from flask import (
@@ -13,38 +18,87 @@ from flask import (
entrybp = Blueprint("entry", __name__)
+def errors(request) -> Tuple[str, ...]:
+ """Return a tuple of the errors found in the `request`. If no error is
+ found, then an empty tuple is returned."""
+ def __filetype_error__():
+ return (
+ ("Invalid file type provided.",)
+ if request.form["filetype"] not in ("average", "standard-error")
+ else tuple())
+
+ def __file_missing_error__():
+ return (
+ ("No file was uploaded.",)
+ if ("qc_text_file" not in request.files or
+ request.files["qc_text_file"].filename == "")
+ else tuple())
+
+ def __file_mimetype_error__():
+ text_file = request.files["qc_text_file"]
+ return (
+ (
+ ("Invalid file! Expected a tab-separated-values file, or a zip "
+ "file of the a tab-separated-values file."),)
+ if text_file.mimetype
+ not in ("text/tab-separated-values", "application/zip")
+ else tuple())
+
+ return (
+ __filetype_error__() +
+ (__file_missing_error__() or __file_mimetype_error__()))
+
+def zip_file_errors(filepath, upload_dir) -> Tuple[str, ...]:
+ """Check the uploaded zip file for errors."""
+ zfile_errors = ("Fail always!!",)
+ if is_zipfile(filepath):
+ zfile = ZipFile(filepath, "r")
+ infolist = zfile.infolist()
+ if len(infolist) != 1:
+ zfile_errors = zfile_errors + (
+ ("Expected exactly one (1) member file within the uploaded zip "
+ "file. Got {len(infolist)} member files."))
+ if len(infolist) == 1 and infolist[0].is_dir():
+ zfile_errors = zfile_errors + (
+ ("Expected a member text file in the uploaded zip file. Got a "
+ "directory/folder."))
+
+ if len(infolist) == 1 and not infolist[0].is_dir():
+ zfile.extract(infolist[0], path=upload_dir)
+ mime = mimetypes.guess_type(f"{upload_dir}/{infolist[0].filename}")
+ if mime[0] != "text/tab-separated-values":
+ zfile_errors = zfile_errors + (
+ ("Expected the member text file in the uploaded zip file to"
+ " be a tab-separated file."))
+
+ return zfile_errors
+
@entrybp.route("/", methods=["GET", "POST"])
def upload_file():
"""Enables uploading the files"""
+ upload_dir = app.config["UPLOAD_FOLDER"]
if request.method == "GET":
return render_template("index.html")
- errors = False
- if request.form["filetype"] not in ("average", "standard-error"):
- flash("Invalid file type provided.", "alert-error")
- errors = True
+ request_errors = errors(request)
+ if request_errors:
+ for error in request_errors:
+ flash(error, "alert-error")
+ return render_template("index.html")
- if ("qc_text_file" not in request.files or
- request.files["qc_text_file"].filename == ""):
- flash("No file was uploaded.", "alert-error")
- errors = True
+ filename = secure_filename(request.files["qc_text_file"].filename)
+ if not os.path.exists(upload_dir):
+ os.mkdir(upload_dir)
- text_file = request.files["qc_text_file"]
- if text_file.mimetype != "text/tab-separated-values":
- flash("Invalid file! Expected a tab-separated-values file.",
- "alert-error")
- errors = True
+ filepath = os.path.join(upload_dir, filename)
+ request.files["qc_text_file"].save(os.path.join(upload_dir, filename))
- if errors:
+ zip_errors = zip_file_errors(filepath, upload_dir)
+ if zip_errors:
+ for error in zip_errors:
+ flash(error, "alert-error")
return render_template("index.html")
- filename = secure_filename(text_file.filename)
- if not os.path.exists(app.config["UPLOAD_FOLDER"]):
- os.mkdir(app.config["UPLOAD_FOLDER"])
-
- filepath = os.path.join(app.config["UPLOAD_FOLDER"], filename)
- text_file.save(os.path.join(app.config["UPLOAD_FOLDER"], filename))
-
return redirect(url_for(
"parse.parse", filename=filename,
filetype=request.form["filetype"]))