epub_convert/web.py
2020-06-26 22:20:53 +08:00

65 lines
2.3 KiB
Python

import tempfile
import hashlib
from io import BytesIO
from flask import (
Flask, jsonify, redirect, request, render_template, send_file, url_for, safe_join
)
from werkzeug.utils import secure_filename
from convert import convert_epub, s2t
from pathlib import Path
app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False
app.config['MAX_CONTENT_LENGTH'] = 20 * 1024 * 1024
def human_file_size(bytes_count):
threshold = 1024
units = ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']
if bytes_count < threshold:
return f"{bytes_count} B"
ui = -1
while True:
bytes_count /= threshold
ui += 1
if bytes_count < threshold or ui == (len(units) - 1):
break
return f"{round(bytes_count, 1)} {units[ui]}"
@app.route("/", methods=["GET"])
def render_index():
limit = app.config["MAX_CONTENT_LENGTH"]
return render_template("index.html.j2", limit=limit, limit_human_readable=human_file_size(limit))
@app.route('/api/convert', methods=["POST"])
def upload_epub_sync():
if 'upload' not in request.files:
return jsonify({"status": False, "error": "No file is specified."}), 400
epub_file = request.files['upload']
if epub_file.filename == '':
return jsonify({"status": False, "error": "No file name."}), 400
# https://stackoverflow.com/questions/283707/size-of-an-open-file-object/283719#283719
epub_file.seek(0, 2)
end_position = epub_file.tell()
if end_position > app.config['MAX_CONTENT_LENGTH']:
return jsonify({"status": False, "error": f"File is too large. Maxium file size is {human_file_size(app.config['MAX_CONTENT_LENGTH'])}"}), 413
if epub_file and Path(epub_file.filename).suffix == ".epub":
output_buffer = BytesIO()
try:
_result = convert_epub(epub_file, output_buffer)
print(f"Converted Successfully. File: {s2t(epub_file.filename)}")
output_buffer.seek(0)
return send_file(output_buffer, as_attachment=True, attachment_filename=s2t(epub_file.filename))
except Exception as e:
error_class = e.__class__.__name__
return jsonify({"status": False, "error": error_class}), 500
else:
return jsonify({"status": False, "error": "Not an epub document"}), 415 # Unsupported Media Type
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)