2021-11-28 03:28:48 +00:00
|
|
|
# https://github.com/FineUploader/server-examples/blob/master/python/django-fine-uploader
|
|
|
|
|
|
|
|
from django.conf import settings
|
|
|
|
from django import forms
|
|
|
|
from django.forms import ClearableFileInput
|
|
|
|
|
|
|
|
import os, os.path
|
|
|
|
import tempfile
|
|
|
|
import shutil
|
|
|
|
|
2022-05-14 17:57:27 +00:00
|
|
|
__all__ = ("handle_upload", "save_upload", "FineUploadForm", "FineUploadFileInput")
|
2021-11-28 03:28:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
def combine_chunks(total_parts, total_size, source_folder, dest):
|
|
|
|
if not os.path.exists(os.path.dirname(dest)):
|
|
|
|
os.makedirs(os.path.dirname(dest))
|
|
|
|
|
2022-05-14 17:57:27 +00:00
|
|
|
with open(dest, "wb+") as destination:
|
2021-11-28 03:28:48 +00:00
|
|
|
for i in range(total_parts):
|
|
|
|
part = os.path.join(source_folder, str(i))
|
2022-05-14 17:57:27 +00:00
|
|
|
with open(part, "rb") as source:
|
2021-11-28 03:28:48 +00:00
|
|
|
destination.write(source.read())
|
|
|
|
|
|
|
|
|
|
|
|
def save_upload(f, path):
|
|
|
|
if not os.path.exists(os.path.dirname(path)):
|
|
|
|
os.makedirs(os.path.dirname(path))
|
2022-05-14 17:57:27 +00:00
|
|
|
with open(path, "wb+") as destination:
|
|
|
|
if hasattr(f, "multiple_chunks") and f.multiple_chunks():
|
2021-11-28 03:28:48 +00:00
|
|
|
for chunk in f.chunks():
|
|
|
|
destination.write(chunk)
|
|
|
|
else:
|
|
|
|
destination.write(f.read())
|
|
|
|
|
|
|
|
|
|
|
|
# pass callback function to post_upload
|
|
|
|
def handle_upload(f, fileattrs, upload_dir, post_upload=None):
|
2022-05-14 17:57:27 +00:00
|
|
|
chunks_dir = os.path.join(tempfile.gettempdir(), "chunk_upload_tmp")
|
2021-11-28 03:28:48 +00:00
|
|
|
if not os.path.exists(os.path.dirname(chunks_dir)):
|
|
|
|
os.makedirs(os.path.dirname(chunks_dir))
|
|
|
|
chunked = False
|
|
|
|
dest_folder = upload_dir
|
2022-05-14 17:57:27 +00:00
|
|
|
dest = os.path.join(dest_folder, fileattrs["qqfilename"])
|
2021-11-28 03:28:48 +00:00
|
|
|
|
|
|
|
# Chunked
|
2022-05-14 17:57:27 +00:00
|
|
|
if fileattrs.get("qqtotalparts") and int(fileattrs["qqtotalparts"]) > 1:
|
2021-11-28 03:28:48 +00:00
|
|
|
chunked = True
|
2022-05-14 17:57:27 +00:00
|
|
|
dest_folder = os.path.join(chunks_dir, fileattrs["qquuid"])
|
|
|
|
dest = os.path.join(
|
|
|
|
dest_folder, fileattrs["qqfilename"], str(fileattrs["qqpartindex"])
|
|
|
|
)
|
2021-11-28 03:28:48 +00:00
|
|
|
save_upload(f, dest)
|
|
|
|
|
|
|
|
# If the last chunk has been sent, combine the parts.
|
2022-05-14 17:57:27 +00:00
|
|
|
if chunked and (fileattrs["qqtotalparts"] - 1 == fileattrs["qqpartindex"]):
|
|
|
|
combine_chunks(
|
|
|
|
fileattrs["qqtotalparts"],
|
|
|
|
fileattrs["qqtotalfilesize"],
|
2021-11-28 03:28:48 +00:00
|
|
|
source_folder=os.path.dirname(dest),
|
2022-05-14 17:57:27 +00:00
|
|
|
dest=os.path.join(upload_dir, fileattrs["qqfilename"]),
|
|
|
|
)
|
2021-11-28 03:28:48 +00:00
|
|
|
shutil.rmtree(os.path.dirname(os.path.dirname(dest)))
|
2022-05-14 17:57:27 +00:00
|
|
|
|
|
|
|
if post_upload and (
|
|
|
|
not chunked or fileattrs["qqtotalparts"] - 1 == fileattrs["qqpartindex"]
|
|
|
|
):
|
2021-11-28 03:28:48 +00:00
|
|
|
post_upload()
|
|
|
|
|
|
|
|
|
|
|
|
class FineUploadForm(forms.Form):
|
|
|
|
qqfile = forms.FileField()
|
|
|
|
qquuid = forms.CharField()
|
|
|
|
qqfilename = forms.CharField()
|
|
|
|
qqpartindex = forms.IntegerField(required=False)
|
|
|
|
qqchunksize = forms.IntegerField(required=False)
|
|
|
|
qqpartbyteoffset = forms.IntegerField(required=False)
|
|
|
|
qqtotalfilesize = forms.IntegerField(required=False)
|
|
|
|
qqtotalparts = forms.IntegerField(required=False)
|
|
|
|
|
|
|
|
|
|
|
|
class FineUploadFileInput(ClearableFileInput):
|
2022-05-14 17:57:27 +00:00
|
|
|
template_name = "widgets/fine_uploader.html"
|
|
|
|
|
2021-11-28 03:28:48 +00:00
|
|
|
def fine_uploader_id(self, name):
|
2022-05-14 17:57:27 +00:00
|
|
|
return name + "_" + "fine_uploader"
|
2021-11-28 03:28:48 +00:00
|
|
|
|
|
|
|
def get_context(self, name, value, attrs):
|
|
|
|
context = super().get_context(name, value, attrs)
|
2022-05-14 17:57:27 +00:00
|
|
|
context["widget"].update(
|
|
|
|
{
|
|
|
|
"fine_uploader_id": self.fine_uploader_id(name),
|
|
|
|
}
|
|
|
|
)
|
|
|
|
return context
|