# -*- coding: utf-8 -*- import os, sys, time import json from datetime import datetime from flask import ( Flask, render_template, jsonify, current_app, Response, redirect, url_for, request, g, session, send_file, send_from_directory, abort, ) from werkzeug.utils import secure_filename from revprox import ReverseProxied from utils import ( random_token, db_store_file, file_details, file_list, db_add_download, db_get_file, db_delete_file, ) __MINI_FLEES_VERSION__ = "20230818.0" app = Flask(__name__) app.config.from_object(__name__) app.config.from_prefixed_env() app.debug = True app.secret_key = app.config["APP_SECRET_KEY"] app.wsgi_app = ReverseProxied(app.wsgi_app) @app.route("/") def index(): return "", 200 @app.route("/upload", methods=["POST"]) def upload(): if request.method == "POST": file = request.files.get("file") name = request.headers.get("Name", None) if name is None: return "Name required", 500 secret = request.headers.get("Secret", "") if secret != app.config["ACCESS_TOKEN"]: return "Error", 401 max_dl = request.headers.get("Max-Downloads", app.config["DEFAULT_MAX_DL"]) expires = int(time.time()) + int(app.config["DEFAULT_EXPIRE"]) if "Expires-days" in request.headers: expires = int(time.time()) + 24 * 3600 * int( request.headers.get("Expires-days") ) if "Expires-hours" in request.headers: expires = int(time.time()) + 3600 * int( request.headers.get("Expires-hours") ) if file: safe_filename = secure_filename(name) token = random_token() folder = os.path.join(app.config["DATAFOLDER"], token) os.mkdir(folder) filename = os.path.join(folder, safe_filename) file.save(filename) db_store_file(token, safe_filename, expires, max_dl) download_url = f"{app.config['PUBLIC_URL']}/dl/{token}/{safe_filename}" return "File uploaded\n%s\n" % (download_url,), 200 else: return "Use the 'file' variable to upload\n", 400 @app.route("/details//", methods=["GET"]) def details(token, name): secret = request.headers.get("Secret", "") if secret != app.config["ACCESS_TOKEN"]: return "Error", 401 details = file_details(token, name) return jsonify(details), 200 @app.route("/delete//", methods=["GET"]) def delete_file(name, token): secret = request.headers.get("Secret", "") if secret != app.config["ACCESS_TOKEN"]: return "Error", 401 try: os.remove(os.path.join(os.getenv("DATAFOLDER"), token, name)) except Exception: pass db_delete_file(token, name) return "OK", 200 @app.route("/ls", methods=["GET"]) def ls(): secret = request.headers.get("Secret", "") if secret != app.config["ACCESS_TOKEN"]: return "Error", 401 return "\n".join(file_list()), 200 @app.route("/dl//", methods=["GET"]) def download(name, token): return download_file(token, name) @app.route("/script/client", methods=["GET"]) def script_client(): return render_template( "client.py", name=name, token=token, rooturl=request.url_root ) @app.route("/script/flip", methods=["GET"]) def script_flip(): return render_template( "flip", name=name, token=token, rooturl=request.url_root, version=__FLEES_VERSION__, ) def download_file(token, name): full_path = os.path.join(os.getenv("FLASK_DATAFOLDER"), token, name) if not os.path.exists(full_path): return "Error", 404 db_stat = db_get_file(token, name) if db_stat: added, expires, downloads, max_dl = db_stat else: return "Error", 404 if downloads >= max_dl: return "Expired", 401 if expires < time.time(): return "Expired", 401 db_add_download(token, name) return send_from_directory( directory=os.path.join(os.getenv("FLASK_DATAFOLDER"), token), path=name ) def print_debug(s): if app.config["DEBUG"]: sys.stderr.write(str(s) + "\n") sys.stderr.flush() if __name__ == "__main__": app.run(debug=True)