diff options
author | willmcgugan@gmail.com <willmcgugan@gmail.com@67cdc799-7952-0410-af00-57a81ceafa0f> | 2015-02-03 10:51:53 +0000 |
---|---|---|
committer | willmcgugan@gmail.com <willmcgugan@gmail.com@67cdc799-7952-0410-af00-57a81ceafa0f> | 2015-02-03 10:51:53 +0000 |
commit | 01b1818dc9587652d792089610976d367453fd77 (patch) | |
tree | f2ebfdca476196e53de68a8c16e10918984dce24 /fs/utils.py | |
parent | a16d951821fe9fccf53472b4541eb070448ed378 (diff) | |
download | pyfilesystem-git-01b1818dc9587652d792089610976d367453fd77.tar.gz |
adde utils.copydir_progress method
Diffstat (limited to 'fs/utils.py')
-rw-r--r-- | fs/utils.py | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/fs/utils.py b/fs/utils.py index e0ab693..8fd6254 100644 --- a/fs/utils.py +++ b/fs/utils.py @@ -258,6 +258,56 @@ def copydir(fs1, fs2, create_destination=True, ignore_errors=False, chunk_size=6 chunk_size=chunk_size) +def copydir_progress(progress_callback, fs1, fs2, create_destination=True, ignore_errors=False, chunk_size=64*1024): + """ + Copies the contents of a directory from one fs to another, with a callback function to display progress. + + `progress_callback` should be a function with two parameters; `step` and `num_steps`. + + `num_steps` is the number of steps in the copy process, and `step` is the current step. `num_steps` may be None if the number + of steps is still being calculated. + + """ + if isinstance(fs1, tuple): + fs1, dir1 = fs1 + fs1 = fs1.opendir(dir1) + if isinstance(fs2, tuple): + fs2, dir2 = fs2 + if create_destination: + fs2.makedir(dir2, allow_recreate=True, recursive=True) + fs2 = fs2.opendir(dir2) + + def do_callback(step, num_steps): + try: + progress_callback(step, num_steps) + except: + pass + + do_callback(0, None) + + file_count = 0 + copy_paths = [] + for dir_path, file_paths in fs1.walk(): + copy_paths.append((dir_path, file_paths)) + file_count += len(file_paths) + do_callback(0, file_count) + + step = 0 + for i, (dir_path, file_paths) in enumerate(copy_paths): + try: + fs2.makedir(dir_path, allow_recreate=True) + for path in file_paths: + copy_path = pathjoin(dir_path, path) + with fs1.open(copy_path, 'rb') as src_file: + fs2.setcontents(copy_path, src_file, chunk_size=chunk_size) + step += 1 + except: + if ignore_errors: + continue + raise + do_callback(step, file_count) + + def remove_all(fs, path): """Remove everything in a directory. Returns True if successful. |