mirror of
https://github.com/akuker/RASCSI.git
synced 2024-09-12 09:55:00 +00:00
Use dropzone and pydrop for file uploading
This commit is contained in:
parent
a9b7d43ef6
commit
4443f42d67
@ -11,3 +11,4 @@ waitress==1.4.4
|
|||||||
zope.event==4.5.0
|
zope.event==4.5.0
|
||||||
zope.interface==5.1.2
|
zope.interface==5.1.2
|
||||||
protobuf==3.17.3
|
protobuf==3.17.3
|
||||||
|
pydrop==0.0.6
|
||||||
|
@ -21,6 +21,11 @@
|
|||||||
<meta name="theme-color" content="#ffffff">
|
<meta name="theme-color" content="#ffffff">
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.2/min/dropzone.min.css"/>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.2/min/basic.min.css"/>
|
||||||
|
|
||||||
|
<script type="application/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.2/min/dropzone.min.js">
|
||||||
|
</script>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
|
@ -172,30 +172,30 @@
|
|||||||
<table style="border: none">
|
<table style="border: none">
|
||||||
<tr style="border: none">
|
<tr style="border: none">
|
||||||
<td style="border: none; vertical-align:top;">
|
<td style="border: none; vertical-align:top;">
|
||||||
<form id="uploadForm" action="/files/upload/" onchange="fileSelect(event)" method="post" enctype="multipart/form-data">
|
<form method="POST" action="/files/upload" class="dropzone dz-clickable" id="dropper" enctype="multipart/form-data">
|
||||||
<label for="file">File:</label>
|
|
||||||
<input type="file" name="file" accept="{{valid_file_suffix}}" />
|
|
||||||
<input type="submit" value="Upload" />
|
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<p><small>Supported file types: {{valid_file_suffix}}</small></p>
|
<script type="application/javascript">
|
||||||
<script>
|
Dropzone.options.dropper = {
|
||||||
function fileSelect(e) {
|
paramName: 'file',
|
||||||
document.getElementById("uploadForm").setAttribute('action', "/files/upload/" + e.target.files[0].name)
|
chunking: true,
|
||||||
console.log(e.target.files[0].name);
|
forceChunking: true,
|
||||||
|
url: '/files/upload',
|
||||||
|
maxFilesize: 2049, // megabytes
|
||||||
|
chunkSize: 1000000 // bytes
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<p><small>Recognized file types: {{valid_file_suffix}}</small></p>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
<h2>Download File from Web</h2>
|
<h2>Download File from Web</h2>
|
||||||
<p>Given a URL, download that file to the <tt>{{base_dir}}</tt></p>
|
<p>Given a URL, download that file to the <tt>{{base_dir}}</tt></p>
|
||||||
<table style="border: none">
|
<table style="border: none">
|
||||||
<tr style="border: none">
|
<tr style="border: none">
|
||||||
<td style="border: none; vertical-align:top;">
|
<td style="border: none; vertical-align:top;">
|
||||||
<form action="/files/download_image" method="post">
|
<form action="/files/download_image" method="post">
|
||||||
<label for="url">URL:</label>
|
<label for="url">URL:</label>
|
||||||
<input type="text" placeholder="URL" name="url" />
|
<input type="text" placeholder="URL" name="url" />
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
from flask import (
|
from flask import (
|
||||||
Flask,
|
Flask,
|
||||||
render_template,
|
render_template,
|
||||||
@ -7,6 +8,7 @@ from flask import (
|
|||||||
redirect,
|
redirect,
|
||||||
send_file,
|
send_file,
|
||||||
send_from_directory,
|
send_from_directory,
|
||||||
|
make_response,
|
||||||
)
|
)
|
||||||
|
|
||||||
from file_cmds import (
|
from file_cmds import (
|
||||||
@ -46,6 +48,7 @@ from ractl_cmds import (
|
|||||||
from settings import *
|
from settings import *
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
log = logging.getLogger('pydrop')
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
@ -161,7 +164,7 @@ def drive_create():
|
|||||||
size = request.form.get("size")
|
size = request.form.get("size")
|
||||||
file_type = request.form.get("file_type")
|
file_type = request.form.get("file_type")
|
||||||
file_name = request.form.get("file_name")
|
file_name = request.form.get("file_name")
|
||||||
|
|
||||||
# Creating the image file
|
# Creating the image file
|
||||||
process = create_new_image(file_name, file_type, size)
|
process = create_new_image(file_name, file_type, size)
|
||||||
if process["status"] == True:
|
if process["status"] == True:
|
||||||
@ -483,30 +486,50 @@ def download_img():
|
|||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/files/upload/<filename>", methods=["POST"])
|
@app.route("/files/upload", methods=["POST"])
|
||||||
def upload_file(filename):
|
def upload_file():
|
||||||
if not filename:
|
|
||||||
flash("No file provided.", "error")
|
|
||||||
return redirect(url_for("index"))
|
|
||||||
|
|
||||||
from os import path
|
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
file_path = path.join(app.config["UPLOAD_FOLDER"], secure_filename(filename))
|
from os import path
|
||||||
if path.isfile(file_path):
|
import pydrop
|
||||||
flash(f"{filename} already exists.", "error")
|
|
||||||
return redirect(url_for("index"))
|
|
||||||
|
|
||||||
from io import DEFAULT_BUFFER_SIZE
|
file = request.files['file']
|
||||||
binary_new_file = "bx"
|
|
||||||
with open(file_path, binary_new_file, buffering=DEFAULT_BUFFER_SIZE) as f:
|
save_path = path.join(app.config["UPLOAD_FOLDER"], secure_filename(file.filename))
|
||||||
chunk_size = DEFAULT_BUFFER_SIZE
|
current_chunk = int(request.form['dzchunkindex'])
|
||||||
while True:
|
|
||||||
chunk = request.stream.read(chunk_size)
|
# If the file already exists it's ok if we are appending to it,
|
||||||
if len(chunk) == 0:
|
# but not if it's new file that would overwrite the existing one
|
||||||
break
|
if path.exists(save_path) and current_chunk == 0:
|
||||||
f.write(chunk)
|
# 400 and 500s will tell dropzone that an error occurred and show an error
|
||||||
# TODO: display an informative success message
|
return make_response(('File already exists', 400))
|
||||||
return redirect(url_for("index", filename=filename))
|
|
||||||
|
try:
|
||||||
|
with open(save_path, 'ab') as f:
|
||||||
|
f.seek(int(request.form['dzchunkbyteoffset']))
|
||||||
|
f.write(file.stream.read())
|
||||||
|
except OSError:
|
||||||
|
# log.exception will include the traceback so we can see what's wrong
|
||||||
|
log.exception('Could not write to file')
|
||||||
|
return make_response(("Not sure why,"
|
||||||
|
" but we couldn't write the file to disk", 500))
|
||||||
|
|
||||||
|
total_chunks = int(request.form['dztotalchunkcount'])
|
||||||
|
|
||||||
|
if current_chunk + 1 == total_chunks:
|
||||||
|
# This was the last chunk, the file should be complete and the size we expect
|
||||||
|
if path.getsize(save_path) != int(request.form['dztotalfilesize']):
|
||||||
|
log.error(f"File {file.filename} was completed, "
|
||||||
|
f"but has a size mismatch."
|
||||||
|
f"Was {path.getsize(save_path)} but we"
|
||||||
|
f" expected {request.form['dztotalfilesize']} ")
|
||||||
|
return make_response(('Size mismatch', 500))
|
||||||
|
else:
|
||||||
|
log.info(f'File {file.filename} has been uploaded successfully')
|
||||||
|
else:
|
||||||
|
log.debug(f'Chunk {current_chunk + 1} of {total_chunks} '
|
||||||
|
f'for file {file.filename} complete')
|
||||||
|
|
||||||
|
return make_response(("Chunk upload successful", 200))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/files/create", methods=["POST"])
|
@app.route("/files/create", methods=["POST"])
|
||||||
|
Loading…
Reference in New Issue
Block a user