diff --git a/interface.py b/interface.py index 76b9624..f79a083 100644 --- a/interface.py +++ b/interface.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -from flask import Flask, render_template, request, redirect +from flask import Flask, render_template, request, redirect, send_file import variables as var import util import os.path @@ -149,6 +149,36 @@ def upload(): else: return redirect("./", code=409) +@web.route('/download', methods=["GET"]) +def download(): + if 'file' in request.args: + requested_file = request.args['file'] + if '../' not in requested_file: + folder_path = var.music_folder + files = util.get_recursive_filelist_sorted(var.music_folder) + + if requested_file in files: + filepath = os.path.join(folder_path, requested_file) + try: + return send_file(filepath, as_attachment=True) + except Exception as e: + self.log.exception(e) + self.Error(400) + elif 'directory' in request.args: + requested_dir = request.args['directory'] + folder_path = var.music_folder + requested_dir_fullpath = os.path.abspath(os.path.join(folder_path, requested_dir)) + '/' + if requested_dir_fullpath.startswith(folder_path): + prefix = secure_filename(os.path.relpath(requested_dir_fullpath, folder_path)) + zipfile = util.zipdir(requested_dir_fullpath, requested_dir) + try: + return send_file(zipfile, as_attachment=True) + except Exception as e: + self.log.exception(e) + self.Error(400) + + return redirect("./", code=400) + if __name__ == '__main__': web.run(port=8181, host="127.0.0.1") diff --git a/templates/index.html b/templates/index.html index 149c3e0..75b9b0e 100644 --- a/templates/index.html +++ b/templates/index.html @@ -29,11 +29,11 @@ {% for file in files %}
  • - +
    - +  {{ file }}
    diff --git a/util.py b/util.py index 8ed6f37..e2868c6 100644 --- a/util.py +++ b/util.py @@ -1,8 +1,10 @@ #!/usr/bin/python3 import configparser +import hashlib import os import variables as var +import zipfile __CONFIG = configparser.ConfigParser(interpolation=None) __CONFIG.read("configuration.ini", encoding='latin-1') @@ -23,6 +25,36 @@ def get_recursive_filelist_sorted(path): filelist.sort() return filelist +# - zips all files of the given zippath (must be a directory) +# - returns the absolute path of the created zip file +# - zip file will be in the applications tmp folder (according to configuration) +# - format of the filename itself = prefix_hash.zip +# - prefix can be controlled by the caller +# - hash is a sha1 of the string representation of the directories' contents (which are +# zipped) +def zipdir(zippath, zipname_prefix=None): + zipname = __CONFIG.get('bot', 'tmp_folder') + if zipname_prefix and '../' not in zipname_prefix: + zipname += zipname_prefix.strip().replace('/', '_') + '_' + + files = get_recursive_filelist_sorted(zippath) + hash = hashlib.sha1((str(files).encode())).hexdigest() + zipname += hash + '.zip' + + if os.path.exists(zipname): + return zipname + + zipf = zipfile.ZipFile(zipname, 'w', zipfile.ZIP_DEFLATED) + + for file in files: + filepath = os.path.dirname(file) + file_to_add = os.path.join(zippath, file) + add_file_as = os.path.relpath(os.path.join(zippath, file), os.path.join(zippath, '..')) + zipf.write(file_to_add, add_file_as) + + zipf.close() + return zipname + class Dir(object): def __init__(self, name): self.name = name