From b6303eadc8783999b067103d111362d820b3632c Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Wed, 22 Apr 2020 00:57:06 +0200 Subject: Add cleaner and thread to clean --- Filer.py | 68 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/Filer.py b/Filer.py index ddafd08..bcd6165 100755 --- a/Filer.py +++ b/Filer.py @@ -1,10 +1,12 @@ #!venv/bin/python -import os import hashlib import base64 import time +from os import unlink, path, getenv, listdir, mkdir, urandom from shutil import rmtree +from threading import Thread +from random import randint from flask import Flask, render_template, jsonify, request, redirect, send_from_directory from flask_dropzone import Dropzone @@ -29,8 +31,8 @@ app.config['DROPZONE_DEFAULT_MESSAGE'] = 'Ziehe die Dateien hier hin, um sie hoc dropzone = Dropzone(app) -basedir = os.getenv('FILER_BASEDIR', './Daten') -filettl = int(os.getenv('FILER_FILETTL', 10)) +basedir = getenv('FILER_BASEDIR', './Daten') +filettl = int(getenv('FILER_FILETTL', 10)) #### ADMIN FACING DIRECTORY LISTS #### #### @@ -38,19 +40,19 @@ filettl = int(os.getenv('FILER_FILETTL', 10)) @app.route("/admin", methods=['GET']) def admin(): url_root = request.url_root.replace('http://', 'https://', 1) - users = os.listdir(os.path.join(basedir, 'Mandanten')) + users = listdir(path.join(basedir, 'Mandanten')) return render_template('admin.html', users = users, tree = make_tree(basedir, 'Public'), url_root = url_root) @app.route("/admin/Dokumente/", methods=['GET']) def admin_dokumente(user): - return render_template('mandant.html', admin = 'admin/', user = user, tree = make_tree(basedir, os.path.join('Dokumente', user))) + return render_template('mandant.html', admin = 'admin/', user = user, tree = make_tree(basedir, path.join('Dokumente', user))) @app.route("/admin/del-user/", methods=['POST']) def admin_deluser(user): method = request.form.get('_method', 'POST') if method == 'DELETE': - rmtree(os.path.join(basedir, 'Dokumente', secure_filename(user))) - os.unlink(os.path.join(basedir, 'Mandanten', secure_filename(user))) + rmtree(path.join(basedir, 'Dokumente', secure_filename(user))) + unlink(path.join(basedir, 'Mandanten', secure_filename(user))) return redirect('/admin') @app.route("/admin/new-user", methods=['POST']) @@ -61,7 +63,7 @@ def admin_newuser(): return "Username or password missing", 400 directory = secure_filename(user) - salt = os.urandom(4) + salt = urandom(4) sha = hashlib.sha1(password.encode('utf-8')) sha.update(salt) @@ -69,9 +71,9 @@ def admin_newuser(): tagged_digest_salt = '{{SSHA}}{}'.format(digest_salt_b64.decode('ascii')) try: - if not os.path.exists(os.path.join(basedir, 'Dokumente', directory)): - os.mkdir(os.path.join(basedir, 'Dokumente', directory)) - with open(os.path.join(basedir, 'Mandanten', directory), 'w+', encoding='utf-8') as htpasswd: + if not path.exists(path.join(basedir, 'Dokumente', directory)): + mkdir(path.join(basedir, 'Dokumente', directory)) + with open(path.join(basedir, 'Mandanten', directory), 'w+', encoding='utf-8') as htpasswd: htpasswd.write("{}:{}\n".format(user, tagged_digest_salt)) except OSError as error: return "Couldn't create user scope", 500 @@ -82,7 +84,7 @@ def admin_newuser(): #### @app.route("/Dokumente/", methods=['GET']) def mandant(user): - return render_template('mandant.html', admin = '', user = user, tree = make_tree(basedir, os.path.join('Dokumente', user))) + return render_template('mandant.html', admin = '', user = user, tree = make_tree(basedir, path.join('Dokumente', user))) #### UPLOAD FILE ROUTES #### #### @@ -94,7 +96,7 @@ def upload_mandant(user): if key.startswith('file'): username = secure_filename(user) filename = secure_filename(f.filename) - f.save(os.path.join(basedir, 'Dokumente', username, filename)) + f.save(path.join(basedir, 'Dokumente', username, filename)) return 'upload template' @app.route('/admin', methods=['POST']) @@ -102,7 +104,7 @@ def upload_admin(): for key, f in request.files.items(): if key.startswith('file'): filename = secure_filename(f.filename) - f.save(os.path.join(basedir, 'Public', filename)) + f.save(path.join(basedir, 'Public', filename)) return 'upload template' #### DELETE FILE ROUTES #### @@ -112,21 +114,21 @@ def upload_admin(): def delete_file_mandant(user, filename): method = request.form.get('_method', 'POST') if method == 'DELETE': - os.unlink(os.path.join(basedir, 'Dokumente', secure_filename(user), secure_filename(filename))) + unlink(path.join(basedir, 'Dokumente', secure_filename(user), secure_filename(filename))) return redirect('/Dokumente/'+user) @app.route('/admin/Dokumente//', methods=['POST']) def delete_file_mandant_admin(user, filename): method = request.form.get('_method', 'POST') if method == 'DELETE': - os.unlink(os.path.join(basedir, 'Dokumente', secure_filename(user), secure_filename(filename))) + unlink(path.join(basedir, 'Dokumente', secure_filename(user), secure_filename(filename))) return redirect('/admin/Dokumente/'+user) @app.route('/admin/Public/', methods=['POST']) def delete_file_admin(filename): method = request.form.get('_method', 'POST') if method == 'DELETE': - os.unlink(os.path.join(basedir, 'Public', secure_filename(filename))) + unlink(path.join(basedir, 'Public', secure_filename(filename))) return redirect('/admin') #### SERVE FILES RULES #### @@ -135,31 +137,45 @@ def delete_file_admin(filename): @app.route('/admin/Dokumente//', methods=['GET']) @app.route('/Dokumente//', methods=['GET']) def custom_static(user, filename): - return send_from_directory(os.path.join(basedir, 'Dokumente'), os.path.join(user, filename)) + return send_from_directory(path.join(basedir, 'Dokumente'), path.join(user, filename)) @app.route('/Public/') def custom_static_public(filename): - return send_from_directory(os.path.join(basedir, 'Public'), filename) + return send_from_directory(path.join(basedir, 'Public'), filename) -def make_tree(rel, path): - tree = dict(name=path, download=os.path.basename(path), children=[]) - try: lst = os.listdir(os.path.join(rel,path)) +def make_tree(rel, pathname): + tree = dict(name=pathname, download=path.basename(pathname), children=[]) + try: lst = listdir(path.join(rel,pathname)) except OSError: pass #ignore errors else: for name in lst: - fn = os.path.join(path, name) - if os.path.isdir(os.path.join(rel,fn)): + fn = path.join(pathname, name) + if path.isdir(path.join(rel,fn)): tree['children'].append(make_tree(rel, fn)) else: - ttl = filettl - int((time.time() - os.path.getmtime(os.path.join(rel,fn))) / (24*3600)) - tree['children'].append(dict(name=fn, download=name, ttl = ttl)) + ttl = filettl - int((time.time() - path.getmtime(path.join(rel,fn))) / (24*3600)) + if ttl < 0: + unlink(path.join(rel,fn)) + else: + tree['children'].append(dict(name=fn, download=name, ttl = ttl)) return tree +def cleaner_thread(): + while True: + make_tree(basedir, 'Dokumente') + # sleep for 6h plus jitter + time.sleep(21600 + randint(1, 1800)) + +thread = Thread(target=cleaner_thread, args=()) +thread.daemon = True +thread.start() + if __name__ == "__main__": parser = ArgumentParser(description="Filer") parser.add_argument("-H", "--host", help="Hostname of the Flask app " + "[default %s]" % "127.0.0.1", default="127.0.0.1") parser.add_argument("-P", "--port", help="Port for the Flask app " + "[default %s]" % "5000", default="5000") + args = parser.parse_args() app.run(host=args.host, port=int(args.port)) -- cgit v1.2.3