HTTP upload : chunks

This commit is contained in:
ABelliqueux 2022-12-14 15:02:11 +01:00
parent 670b183d04
commit 3334fd1d14
1 changed files with 44 additions and 20 deletions

64
app.py
View File

@ -161,7 +161,6 @@ def list_media_files(folder):
for fd in files: for fd in files:
if len(fd.split('.')) > 1: if len(fd.split('.')) > 1:
if fd.split('.')[1] in media_exts: if fd.split('.')[1] in media_exts:
# TODO : Return a dict list [{"filename":"foo", "size":-1}, {...}]
fd_size = os.stat(folder + fd).st_size fd_size = os.stat(folder + fd).st_size
file_dict = {"filename": fd, "size": fd_size} file_dict = {"filename": fd, "size": fd_size}
medias.append(file_dict) medias.append(file_dict)
@ -173,9 +172,15 @@ def list_media_files(folder):
def generate_thumbnails(): def generate_thumbnails():
media_files = list_media_files(upload_folder) media_files = list_media_files(upload_folder)
for media in media_files: 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("/") @app.route("/")
@auth.login_required @auth.login_required
def main(): def main():
@ -214,9 +219,10 @@ def shutdown():
# File upload # File upload
@app.route('/upload', methods=['GET', 'POST']) @app.route('/upload/', defaults={"filename": "null", "chunk_size" : 102400}, methods=['GET', 'POST'])
@app.route('/upload/<filename>/<chunk_size>', methods=['GET', 'POST'])
@auth.login_required @auth.login_required
def upload_file(over_write=1): def upload_file(filename, chunk_size, over_write=1):
global upload_candidates global upload_candidates
media_files = list_media_files(upload_folder) media_files = list_media_files(upload_folder)
if debug: if debug:
@ -227,17 +233,14 @@ def upload_file(over_write=1):
print("GET :" + str(upload_candidates)) print("GET :" + str(upload_candidates))
return upload_candidates return upload_candidates
if request.method == "POST": if request.method == "POST":
# JSON received, parse it
if request.is_json: if request.is_json:
print("HERE")
# JSON received, parse it
upload_candidates = request.get_json() upload_candidates = request.get_json()
# ~ upload_candidates = [candidate for candidate in upload_candidates if candidate not in media_files] # ~ upload_candidates = [candidate for candidate in upload_candidates if candidate not in media_files]
upload_laureates = [] upload_laureates = []
for candidate in upload_candidates: for candidate in upload_candidates:
if candidate not in media_files: if candidate not in media_files:
upload_laureates.append(candidate) 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: elif candidate in media_files:
duplicate_index = media_files.index(candidate) duplicate_index = media_files.index(candidate)
if candidate["size"] != media_files[duplicate_index]["size"]: if candidate["size"] != media_files[duplicate_index]["size"]:
@ -246,25 +249,46 @@ def upload_file(over_write=1):
if debug: if debug:
print("POST :" + str(upload_candidates)) print("POST :" + str(upload_candidates))
return upload_candidates return upload_candidates
# File received, get it
else: else:
print("Sending " + filename)
# Check if the post request has the file part # Check if the post request has the file part
if "file" not in request.files: # ~ if "file" not in request.files:
return _("No file part: {}").format(str(request.files)) # ~ return _("No file part: {}").format(str(request.files))
file = request.files["file"] # ~ upload = request.files["file"]
# If the user does not select a file, the browser submits an # If the user does not select a file, the browser submits an
# empty file without a filename. # empty file without a filename.
if file.filename == "": if filename == "":
return _("No selected file") return _("No selected file")
if file and allowed_ext(file.filename): if filename and allowed_ext(filename):
if debug: if debug:
print("Uploading file {} in {}.".format(str(file.filename.strip("/")), upload_folder)) print(media_files)
if (file.filename.strip("/") not in media_files) or over_write: print(upload_candidates)
filename = secure_filename(file.filename) print("File {} is allowed.".format(str(filename.strip("/"))))
file.save(os.path.join(upload_folder, filename)) local_file_exists = value_in_dict_list(filename, media_files, "filename")
return _("File saved in {}").format(upload_folder) 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: if debug:
print("File exists, skipping...") print("Uploading file {} in {}.".format(filename_l, file_path))
return "File exists, skipping..." 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" return "OK"