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 | 1f3ed9f956c9f9eca3a4f19e5e6ad8bbd2368c32 (patch) | |
tree | f2ebfdca476196e53de68a8c16e10918984dce24 | |
parent | a61d85e3e97f4c8ef2c733416ec1e59de71ed2ff (diff) | |
download | pyfilesystem-1f3ed9f956c9f9eca3a4f19e5e6ad8bbd2368c32.tar.gz |
adde utils.copydir_progress method
git-svn-id: http://pyfilesystem.googlecode.com/svn/trunk@911 67cdc799-7952-0410-af00-57a81ceafa0f
-rw-r--r-- | CHANGES.txt | 3 | ||||
-rw-r--r-- | fs/memoryfs.py | 2 | ||||
-rw-r--r-- | fs/utils.py | 50 |
3 files changed, 53 insertions, 2 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index df34fd7..dab45a1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -89,7 +89,8 @@ * Added archivefs to fs.contrib, contributed by btimby * Added some polish to fstree command and unicode box lines rather than ascii art -0.5: +0.5.1: * Fixed a hang bug in readline + * Added copydir_progress to fs.utils diff --git a/fs/memoryfs.py b/fs/memoryfs.py index 9a87db3..cde0096 100644 --- a/fs/memoryfs.py +++ b/fs/memoryfs.py @@ -542,7 +542,7 @@ class MemoryFS(FS): @synchronize
def _on_close_memory_file(self, open_file, path):
dir_entry = self._get_dir_entry(path)
- if dir_entry is not None:
+ if dir_entry is not None and open_file in dir_entry.open_files:
dir_entry.open_files.remove(open_file)
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. |