From 3334fd1d1482838b8bbb3753af40f63f698809bf Mon Sep 17 00:00:00 2001 From: ABelliqueux Date: Wed, 14 Dec 2022 15:02:11 +0100 Subject: [PATCH] HTTP upload : chunks --- app.py | 64 ++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/app.py b/app.py index a6ec59a..5d1965e 100755 --- a/app.py +++ b/app.py @@ -161,7 +161,6 @@ def list_media_files(folder): for fd in files: if len(fd.split('.')) > 1: if fd.split('.')[1] in media_exts: - # TODO : Return a dict list [{"filename":"foo", "size":-1}, {...}] fd_size = os.stat(folder + fd).st_size file_dict = {"filename": fd, "size": fd_size} medias.append(file_dict) @@ -173,8 +172,14 @@ def list_media_files(folder): def generate_thumbnails(): media_files = list_media_files(upload_folder) for media in media_files: - subprocess.call(['ffmpeg', '-i', upload_folder + "/" + media, '-q:v', '30', '-s', '160x120', '-vf', 'boxblur=2', '-ss', '00:00:01.000', '-vframes', '1', thumbnails_folder + "/" + media + ".jpg", "-y"]) + subprocess.call(['ffmpeg', '-i', os.path.join(upload_folder, media), '-q:v', '30', '-s', '160x120', '-vf', 'boxblur=2', '-ss', '00:00:01.000', '-vframes', '1', os.path.join(thumbnails_folder, media) + ".jpg", "-y"]) + +def value_in_dict_list(value, dict_list, key): + for dictionary in dict_list: + if dictionary["filename"] == value: + return dictionary + return False @app.route("/") @auth.login_required @@ -214,9 +219,10 @@ def shutdown(): # File upload -@app.route('/upload', methods=['GET', 'POST']) +@app.route('/upload/', defaults={"filename": "null", "chunk_size" : 102400}, methods=['GET', 'POST']) +@app.route('/upload//', methods=['GET', 'POST']) @auth.login_required -def upload_file(over_write=1): +def upload_file(filename, chunk_size, over_write=1): global upload_candidates media_files = list_media_files(upload_folder) if debug: @@ -227,17 +233,14 @@ def upload_file(over_write=1): print("GET :" + str(upload_candidates)) return upload_candidates if request.method == "POST": + # JSON received, parse it if request.is_json: - print("HERE") - # JSON received, parse it upload_candidates = request.get_json() # ~ upload_candidates = [candidate for candidate in upload_candidates if candidate not in media_files] upload_laureates = [] for candidate in upload_candidates: if candidate not in media_files: upload_laureates.append(candidate) - # TODO : Compare existing file size to new file and upload if different - # received data of type list of dict [{"filename": "foo", "size": 0}, {...}] elif candidate in media_files: duplicate_index = media_files.index(candidate) if candidate["size"] != media_files[duplicate_index]["size"]: @@ -246,25 +249,46 @@ def upload_file(over_write=1): if debug: print("POST :" + str(upload_candidates)) return upload_candidates + # File received, get it else: + print("Sending " + filename) # Check if the post request has the file part - if "file" not in request.files: - return _("No file part: {}").format(str(request.files)) - file = request.files["file"] + # ~ if "file" not in request.files: + # ~ return _("No file part: {}").format(str(request.files)) + # ~ upload = request.files["file"] # If the user does not select a file, the browser submits an # empty file without a filename. - if file.filename == "": + if filename == "": return _("No selected file") - if file and allowed_ext(file.filename): + if filename and allowed_ext(filename): if debug: - print("Uploading file {} in {}.".format(str(file.filename.strip("/")), upload_folder)) - if (file.filename.strip("/") not in media_files) or over_write: - filename = secure_filename(file.filename) - file.save(os.path.join(upload_folder, filename)) - return _("File saved in {}").format(upload_folder) + print(media_files) + print(upload_candidates) + print("File {} is allowed.".format(str(filename.strip("/")))) + local_file_exists = value_in_dict_list(filename, media_files, "filename") + remote_file_infos = value_in_dict_list(filename, upload_candidates, "filename") + filename_l = secure_filename(filename) + file_path = os.path.join(upload_folder, filename_l) + # TODO : Find a way to remove incomplete uploads + # ~ if file_exists and over_write: + #if local_file_exists["size"] < remote_file_infos["size"]/10): + # ~ fd = open(file_path, "wb") + # ~ fd.write(b'') + # ~ over_write = 0 + # ~ if debug: + # ~ print("Overwriting file {} in {}.".format(filename_l, file_path)) + # ~ if filename not in media_files: + # ~ if (not local_file_exists) or (local_file_exists["size"] < remote_file_infos["size"]/10): if debug: - print("File exists, skipping...") - return "File exists, skipping..." + print("Uploading file {} in {}.".format(filename_l, file_path)) + with open(file_path, "ab") as dl_file: + part_size = int(chunk_size) + chunk = request.stream.read(part_size) + if debug: + print(len(chunk)) + dl_file.write(chunk) + # ~ file.save(os.path.join(upload_folder, filename)) + return _("File saved as {}").format(file_path) return "OK"