diff options
author | Thomas Feldmann <mail@tfeldmann.de> | 2022-04-29 14:26:06 +0200 |
---|---|---|
committer | Thomas Feldmann <mail@tfeldmann.de> | 2022-04-29 14:26:06 +0200 |
commit | 1626788c585d2957bf4c1e70c7a42ce06de1bd99 (patch) | |
tree | a1c2717685c5096324f8174f76b3fdb2a6afba14 | |
parent | 843ff7c37daf75306c43031dfeeb70b6feab0f00 (diff) |
bugfix for move error
-rw-r--r-- | organize/actions/copymove_utils.py | 5 | ||||
-rw-r--r-- | organize/actions/move.py | 88 |
2 files changed, 77 insertions, 16 deletions
diff --git a/organize/actions/copymove_utils.py b/organize/actions/copymove_utils.py index e30aa98..3afb365 100644 --- a/organize/actions/copymove_utils.py +++ b/organize/actions/copymove_utils.py @@ -84,6 +84,11 @@ def resolve_overwrite_conflict( elif conflict_mode == "overwrite": print("Overwrite %s." % safe_description(dst_fs, dst_path)) + if not simulate: + if dst_fs.isdir(dst_path): + dst_fs.removedir(dst_path) + elif dst_fs.isfile(dst_path): + dst_fs.remove(dst_path) return dst_path elif conflict_mode == "rename_new": diff --git a/organize/actions/move.py b/organize/actions/move.py index 9fe89b4..1b01c93 100644 --- a/organize/actions/move.py +++ b/organize/actions/move.py @@ -3,8 +3,10 @@ from typing import Callable, Union from fs import errors, open_fs from fs.base import FS -from fs.errors import NoSysPath -from fs.move import move_dir, move_file +from fs.copy import copy_file +from fs.errors import FSError +from fs.move import move_dir +from fs.opener import manage_fs from fs.opener.errors import OpenerError from fs.osfs import OSFS from fs.path import dirname, frombase @@ -16,20 +18,74 @@ from .action import Action from .copymove_utils import CONFLICT_OPTIONS, check_conflict, dst_from_options -def move_file_optimized(src_fs, src_path, dst_fs, dst_path): - try: - if isinstance(src_fs, OSFS) and isinstance(dst_fs, OSFS): - src_syspath = src_fs.getsyspath(src_path) - dst_syspath = dst_fs.getsyspath(dst_path) - common = commonpath([src_syspath, dst_syspath]) - rel_src = frombase(common, src_syspath) - rel_dst = frombase(common, dst_syspath) - with open_fs(common, writeable=True) as base: - base.move(rel_src, rel_dst) - return - except (ValueError, NoSysPath): - pass - move_file(src_fs, src_path, dst_fs, dst_path) +# this is taken from my PR +def move_file_optimized( + src_fs, + src_path, + dst_fs, + dst_path, + preserve_time=False, + cleanup_dst_on_error=True, +): + # type: (...) -> None + """Move a file from one filesystem to another. + + Arguments: + src_fs (FS or str): Source filesystem (instance or URL). + src_path (str): Path to a file on ``src_fs``. + dst_fs (FS or str): Destination filesystem (instance or URL). + dst_path (str): Path to a file on ``dst_fs``. + preserve_time (bool): If `True`, try to preserve mtime of the + resources (defaults to `False`). + cleanup_dst_on_error (bool): If `True`, tries to delete the file copied to + ``dst_fs`` if deleting the file from ``src_fs`` fails (defaults to `True`). + + """ + with manage_fs(src_fs, writeable=True) as _src_fs: + with manage_fs(dst_fs, writeable=True, create=True) as _dst_fs: + if _src_fs is _dst_fs: + # Same filesystem, may be optimized + _src_fs.move( + src_path, dst_path, overwrite=True, preserve_time=preserve_time + ) + return + + if _src_fs.hassyspath(src_path) and _dst_fs.hassyspath(dst_path): + # if both filesystems have a syspath we create a new OSFS from a + # common parent folder and use it to move the file. + try: + src_syspath = _src_fs.getsyspath(src_path) + dst_syspath = _dst_fs.getsyspath(dst_path) + common = commonpath([src_syspath, dst_syspath]) + if common: + rel_src = frombase(common, src_syspath) + rel_dst = frombase(common, dst_syspath) + with _src_fs.lock(), _dst_fs.lock(): + with OSFS(common) as base: + base.move(rel_src, rel_dst, preserve_time=preserve_time) + return # optimization worked, exit early + except ValueError: + # This is raised if we cannot find a common base folder. + # In this case just fall through to the standard method. + pass + + # Standard copy and delete + with _src_fs.lock(), _dst_fs.lock(): + copy_file( + _src_fs, + src_path, + _dst_fs, + dst_path, + preserve_time=preserve_time, + ) + try: + _src_fs.remove(src_path) + except FSError as e: + # if the source cannot be removed we delete the copy on the + # destination + if cleanup_dst_on_error: + _dst_fs.remove(dst_path) + raise e class Move(Action): |