cmdlet refactor
This commit is contained in:
@@ -549,6 +549,8 @@ class FTP(Provider):
|
||||
if not local_path.exists() or not local_path.is_file():
|
||||
raise FileNotFoundError(f"File not found: {local_path}")
|
||||
|
||||
pipe_obj = kwargs.get("pipe_obj")
|
||||
|
||||
settings = self._resolve_settings(
|
||||
instance_name=str(kwargs.get("instance") or kwargs.get("store") or "").strip() or None,
|
||||
require_explicit=bool(kwargs.get("instance") or kwargs.get("store")),
|
||||
@@ -569,6 +571,19 @@ class FTP(Provider):
|
||||
ftp = self._connect(settings=settings)
|
||||
try:
|
||||
self._ensure_directory(ftp, remote_dir, base_path=str(settings.get("base_path") or "/"))
|
||||
# FTP duplicate check is filename-based at the destination directory.
|
||||
# If the exact filename already exists remotely, skip re-upload.
|
||||
if self._remote_filename_exists(ftp, remote_dir, remote_name):
|
||||
try:
|
||||
if pipe_obj is not None:
|
||||
if not isinstance(getattr(pipe_obj, "extra", None), dict):
|
||||
pipe_obj.extra = {}
|
||||
pipe_obj.extra["upload_duplicate"] = True
|
||||
pipe_obj.extra["upload_duplicate_rule"] = "filename"
|
||||
pipe_obj.extra["upload_duplicate_target"] = remote_path
|
||||
except Exception:
|
||||
pass
|
||||
return self._build_url(remote_path, settings=settings)
|
||||
with local_path.open("rb") as handle:
|
||||
ftp.storbinary(f"STOR {remote_path}", handle)
|
||||
finally:
|
||||
@@ -930,6 +945,36 @@ class FTP(Provider):
|
||||
if not self._is_directory(ftp, partial):
|
||||
raise
|
||||
|
||||
def _remote_filename_exists(self, ftp: ftplib.FTP, remote_dir: str, filename: str) -> bool:
|
||||
target_name = str(filename or "").strip()
|
||||
if not target_name:
|
||||
return False
|
||||
|
||||
normalized_dir = self._normalize_remote_path(remote_dir, default=self._base_path)
|
||||
|
||||
try:
|
||||
for name, facts in ftp.mlsd(normalized_dir):
|
||||
_ = facts
|
||||
if str(name or "").strip() == target_name:
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
entries = ftp.nlst(normalized_dir)
|
||||
except Exception:
|
||||
entries = []
|
||||
|
||||
for entry in entries or []:
|
||||
entry_text = str(entry or "").strip().rstrip("/")
|
||||
if not entry_text:
|
||||
continue
|
||||
entry_name = posixpath.basename(entry_text)
|
||||
if entry_name == target_name:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _item_metadata(self, item: Any, *, pipe_obj: Any = None) -> Dict[str, Any]:
|
||||
metadata: Dict[str, Any] = {}
|
||||
for source in (item, pipe_obj):
|
||||
|
||||
Reference in New Issue
Block a user