summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Feldmann <mail@tfeldmann.de>2022-04-29 14:26:06 +0200
committerThomas Feldmann <mail@tfeldmann.de>2022-04-29 14:26:06 +0200
commit1626788c585d2957bf4c1e70c7a42ce06de1bd99 (patch)
treea1c2717685c5096324f8174f76b3fdb2a6afba14
parent843ff7c37daf75306c43031dfeeb70b6feab0f00 (diff)
bugfix for move error
-rw-r--r--organize/actions/copymove_utils.py5
-rw-r--r--organize/actions/move.py88
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):