juliomalegria / django-chunked-upload

Upload large files to Django in multiple chunks, with the ability to resume if the upload is interrupted.
MIT No Attribution
218 stars 73 forks source link

Opening file issue #56

Open danielgarner64 opened 4 years ago

danielgarner64 commented 4 years ago

In the ChunkedUploadCompleteView class in the post method there is the following call on line 286: self.on_completion(chunked_upload.get_uploaded_file(), request) This opens the uploaded file and returns it to the on_completion user method.

This prevented me from moving the uploaded file to a separate database model as the file was open. I also couldn't do this work in the post_save method as it causes an error as the file is no longer present when the get_uploade_file attempts to open the file.

In the end I shifted the model shifting to the get_response_data method which allowed me to do what I want without modifying this project.

jerinpetergeorge commented 4 years ago

@danielgarner64

You can close the opened file in on_completion method by overriding ChunkedUploadCompleteView as,

from chunked_upload.views import ChunkedUploadCompleteView

class MyUploadCompleteView(ChunkedUploadCompleteView):
    def on_completion(self, uploaded_file, request):
        uploaded_file.file.close()

Apart from that, the method on_completion(...) is a hook which can be used to post process the file. In your case, I persume you can use the on_completion(...) method itself to move the file

danielgarner64 commented 4 years ago

That was exactly what I attempted to do originally.

But while in the on_completion method I still get the error that the file is open.

Here is the error I get: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\Users\bob\Desktop\DjangoUploadDownloadFirstDraft\media\chunked_uploads\2020\04\21\ddbf659a09364bfe924995b2894f3a01.part' [21/Apr/2020 15:07:11] "POST /chunkedUploadComplete/ HTTP/1.1" 500 24675

Code that gets the above error

    def on_completion(self, uploaded_file, request):
        uploaded_file.file.close()

        chunked_upload = get_object_or_404(ChunkedFile, upload_id=request.POST.get("upload_id"))
        chunked_upload.delete(delete_file=False)
        #time.sleep(2)
        uploaded_file = create_file_in_db_with_existing_file(
            src_path=chunked_upload.file.path,
            file_name=chunked_upload.filename,
            description=request.POST.get("description", ""),
            user=request.user,
            file_size=chunked_upload.file.size,
            file_md5=chunked_upload.md5
        )

Code that works and gets no error but is in the inappropriate location of get_response_data:

    def get_response_data(self, chunked_upload, request):
        chunked_upload.file.close()
        chunked_upload.delete(delete_file=False)

        uploaded_file = create_file_in_db_with_existing_file(
            src_path=chunked_upload.file.path,
            file_name=chunked_upload.filename,
            description=request.POST.get("description", ""),
            user=request.user,
            file_size=chunked_upload.file.size,
            file_md5=chunked_upload.md5
        )
        redirect_to = "uploadDownloadApp:" + request.POST.get("source_page", "home")
        messages.add_message(request, messages.SUCCESS, f"Successfully uploaded file {uploaded_file.file.name}")
        return {"status": "success", "redirect_url": reverse(redirect_to)}
jerinpetergeorge commented 4 years ago

@danielgarner64 Is there any way I can reproduce this error ?

danielgarner64 commented 4 years ago

@jerinpetergeorge Here is a copy of a mini-project that reproduces the error, sorry for the lack of comments. https://github.com/danielgarner64/BasicChunkedUpload

jerinpetergeorge commented 4 years ago

@danielgarner64

I tried to reproduce the issue, unfortunately, I couldn't. I have executed the given code as-is and both works just charm (Ubuntu OS)

danielgarner64 commented 4 years ago

Just confirmed, you are correct this is not a problem for Ubuntu with Python 3.6. I only get the bug in Windows 10 with Python 3.7. I'd say its not a big problem because its isolated to Windows. And its probably a Python/Windows issue rather than this projects issue.