This commit is contained in:
Raykov-MS 2026-07-10 14:50:21 +03:00
parent f9e01a72a0
commit 6f6ed4afc0
2 changed files with 37 additions and 1 deletions

View File

@ -146,6 +146,18 @@ class SMBClientConnection:
full_path = self._resolve_path(path) full_path = self._resolve_path(path)
smbclient.remove(full_path) smbclient.remove(full_path)
def rename(self, path_from: str, path_to: str, replace: bool = False) -> None:
smbclient = _import_smbclient()
full_source = self._resolve_path(path_from)
full_target = self._resolve_path(path_to)
self.mkdir(get_parent_dir(path_to), parent=True)
if self.path_exists(path_to) and not replace:
raise FileExistsError(full_target)
try:
smbclient.rename(full_source, full_target)
except TypeError:
smbclient.rename(full_source, full_target, replace=replace)
def open(self, path: str, mode: str = "rb"): def open(self, path: str, mode: str = "rb"):
smbclient = _import_smbclient() smbclient = _import_smbclient()
full_path = self._resolve_path(path) full_path = self._resolve_path(path)
@ -401,6 +413,15 @@ def _next_available_samba_target(dir_path: str, file_name: str, samba_conn) -> s
def _samba_move_file(path_from: str, path_to: str, samba_conn) -> None: def _samba_move_file(path_from: str, path_to: str, samba_conn) -> None:
rename_error: Exception | None = None
if hasattr(samba_conn, "rename"):
try:
with samba_conn:
samba_conn.rename(path_from=path_from, path_to=path_to, replace=False)
return
except Exception as exc: # noqa: BLE001
rename_error = exc
try: try:
with samba_conn: with samba_conn:
samba_conn.copy(path_from=path_from, path_to=path_to, replace=False) samba_conn.copy(path_from=path_from, path_to=path_to, replace=False)
@ -408,7 +429,7 @@ def _samba_move_file(path_from: str, path_to: str, samba_conn) -> None:
raise RuntimeError( raise RuntimeError(
"SMB move failed at copy stage: " "SMB move failed at copy stage: "
f"source='{path_from}', target='{path_to}', " f"source='{path_from}', target='{path_to}', "
f"{_format_smb_exception(exc)}" f"{_format_smb_exception(exc)}{_format_rename_attempt(rename_error)}"
) from exc ) from exc
try: try:
@ -420,6 +441,7 @@ def _samba_move_file(path_from: str, path_to: str, samba_conn) -> None:
"SMB move failed at delete stage after successful copy: " "SMB move failed at delete stage after successful copy: "
f"source='{path_from}', target='{path_to}', " f"source='{path_from}', target='{path_to}', "
f"target_exists={target_exists}, {_format_smb_exception(exc)}" f"target_exists={target_exists}, {_format_smb_exception(exc)}"
f"{_format_rename_attempt(rename_error)}"
) from exc ) from exc
@ -440,6 +462,12 @@ def _format_smb_exception(exc: Exception) -> str:
return ", ".join(details) return ", ".join(details)
def _format_rename_attempt(rename_error: Exception | None) -> str:
if rename_error is None:
return ""
return f"; native_rename_attempt=failed({_format_smb_exception(rename_error)})"
def _write_probe_file(remote_path: str, samba_conn) -> None: def _write_probe_file(remote_path: str, samba_conn) -> None:
if hasattr(samba_conn, "open"): if hasattr(samba_conn, "open"):
with samba_conn.open(remote_path, mode="wb") as remote_file: with samba_conn.open(remote_path, mode="wb") as remote_file:

View File

@ -58,6 +58,14 @@ class FakeSamba:
if target.exists(): if target.exists():
target.unlink() target.unlink()
def rename(self, path_from: str, path_to: str, replace: bool = False) -> None:
source = self._to_local(path_from)
target = self._to_local(path_to)
target.parent.mkdir(parents=True, exist_ok=True)
if target.exists() and not replace:
raise FileExistsError(path_to)
source.rename(target)
def open(self, path: str, mode: str = "rb"): def open(self, path: str, mode: str = "rb"):
target = self._to_local(path) target = self._to_local(path)
target.parent.mkdir(parents=True, exist_ok=True) target.parent.mkdir(parents=True, exist_ok=True)