Files
binary_quiz_backend/app.py
2020-06-14 11:32:13 +02:00

104 lines
2.8 KiB
Python

import os
import shutil
import subprocess
import tempfile
import zipfile
import datetime
from flask_cors import CORS
MIN_BITS = 2
MAX_BITS = 16
MIN_NUM_PROBLEMS = 1
MAX_NUM_PROBLEMS = 99
from flask import Flask, request, send_file
app = Flask(__name__)
app.config["SEND_FILE_MAX_AGE_DEFAULT"] = 0
# TODO: disable this when not using localhost
CORS(app)
def make_answers_path(path):
path, filename = os.path.split(path)
new_filename = f"{filename.split('.pdf')[0]}-answers.pdf"
return os.path.join(path, new_filename)
def make_zip_path():
return f"/tmp/problems_and_answers_{str(datetime.datetime.now().timestamp()).replace('.', '_')}.zip"
def make_zip_archive(*filepaths):
zip_path = make_zip_path()
with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED) as zfd:
for filepath in filepaths:
zfd.write(filepath, os.path.basename(filepath))
return zip_path
def clear_tempdir():
temp_files = os.listdir("/tmp")
for f in temp_files:
if f.endswith(".zip"):
os.unlink(os.path.join("/tmp", f))
def validate_bits_and_num_probs(bits, num_problems):
if bits > MAX_BITS:
return f"max bits is {MAX_BITS}", 400
elif bits < MIN_BITS:
return f"min bits is {MIN_BITS}", 400
elif num_problems > MAX_NUM_PROBLEMS:
return f"max num_problems is {MAX_NUM_PROBLEMS}", 400
elif num_problems < MIN_NUM_PROBLEMS:
return f"max num_problems is {MIN_NUM_PROBLEMS}", 400
@app.route("/")
def everything():
if not request.args:
return "Hello World!"
try:
bits, num_problems = request.args["bits"], request.args["num_problems"]
except KeyError:
return "please provide both bits and num_problems", 400
bits, num_problems = int(bits), int(num_problems)
not_valid = validate_bits_and_num_probs(bits, num_problems)
if not_valid:
return not_valid
include_answers = True
if "make_answers" in request.args and request.args["make_answers"] == "false":
include_answers = False
make_zip = include_answers
with tempfile.NamedTemporaryFile(mode="w", suffix=".pdf") as fout:
subprocess.call(
f"binary {bits} {num_problems} --pdf --output-filepath={fout.name} ",
shell=True,
)
if make_zip:
clear_tempdir()
filepath = make_zip_archive(fout.name, make_answers_path(fout.name))
mimetype = "application/zip"
else:
filepath = fout.name
mimetype = "application/pdf"
print(filepath)
return send_file(
filepath,
as_attachment=True,
attachment_filename=os.path.basename(filepath),
mimetype=mimetype,
cache_timeout=0,
)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=4444, debug=True)