0

While studying Ajax/jQuery, I am trying to setup this test environment:

  1. the server recursively copy a full folder form one location to another;
  2. the client should display the list of copied files, one by one, in real time until the copy ends;
  3. in the client thereshould be a button to abort the copy operation.

Can you pls point me to a simple skeleton of this problem, or give me any clue? Thanks, I appreciate.

Fabio Marzocca
  • 1,573
  • 16
  • 36
  • See [How to read and echo file size of uploaded file being written at server in real time without blocking at both server and client?](https://stackoverflow.com/questions/42475492/how-to-read-and-echo-file-size-of-uploaded-file-being-written-at-server-in-real) – guest271314 Jun 04 '17 at 17:14

1 Answers1

1

Some general ideas for the client:

  • It needs to establish a session. This is both so that it can see the file copy progress of the files it is copying and no other (possibly malicious) third party can see it. This can be done with some sort of a token. This can be stored as a cookie and the server can read this to see what session the request is from.
  • You need the client to keep requesting the state at a steady interval. This is called polling.

So, all your client has to do is request to establish a session, request which folder needs to be copied (Possibly needing to request a directory tree), and then make a request for which folder needs to be copied where, and keep making requests for the progress every few seconds or minutes until it is done. In the mean time, if the user wishes to cancel it, send a cancel request to some endpoint.

On the server side, there are many technologies to do this. django is the most popular, but this seems like a smaller project, so might I recommended flask.

As for the actual task, shutil.copytree() is what you are looking for. It takes a custom copy function, which you can specify to update a sessions "currently copying" file when a new file needs to be copied:

import shutil

def copy_dir(session_id, source, destination):
    def copy_fn(src, dest):
        if sessions[session_id]['data'].aborted:
            return  # Stop copying once requested.
        # Or however your session data is structured
        sessions[session_id]['data'].current_copy = [src, dest]
        shutil.copy2(src, dest)  # Actual copy work
    shutil.copytree(source, destination, copy_function=copy_fn)

To get the percentage of how much of the file has been copied, compare the size of the file that is being copied to to the file it is being copied from.

Another way to get the percentage of copying, os.walk on a directory to generate all the file names, then open the files and copy it in chunks. Update the progress every few chunks. Note that this is very error prone.

Artyer
  • 31,034
  • 3
  • 47
  • 75
  • Great post, Artyer! I am using Flask, indeed! And my copy_dir function is already working on cli app, fully tested. I already have the copy_fn(src, dest) and at the moment it prints out in the terminal each file been copied. The problem is that now I need to move from cli to web application (that's why Flask) an I need to display in user's screen those file names while they get listed. So, the proble is: "how to implement AJAX/jQuery on the client side? – Fabio Marzocca Jun 04 '17 at 19:22
  • At the end, I managed to build this behaviour using WebSockets (Flask.SocketIO) – Fabio Marzocca Jun 05 '17 at 11:51