This commit is contained in:
2026-01-18 13:10:31 -08:00
parent 66e6c6eb72
commit 3ab122a55d
5 changed files with 175 additions and 88 deletions

View File

@@ -553,7 +553,7 @@ class Add_File(Cmdlet):
item, path_arg, pipe_obj, config, store_instance=storage_registry
)
debug(
f"[add-file] RESOLVED source: path={media_path}, hash={file_hash[:12] if file_hash else 'N/A'}..."
f"[add-file] RESOLVED source: path={media_path}, hash={file_hash if file_hash else 'N/A'}..."
)
if not media_path:
failures += 1
@@ -1112,8 +1112,8 @@ class Add_File(Cmdlet):
if dl_path and dl_path.exists():
pipe_obj.path = str(dl_path)
return dl_path, str(r_hash), tmp_dir
except Exception:
pass
except Exception as exc:
debug(f"[add-file] _resolve_source backend fetch failed for {r_store}/{r_hash}: {exc}")
# PRIORITY 2: Generic Coercion (Path arg > PipeObject > Result)
candidate: Optional[Path] = None
@@ -1148,13 +1148,13 @@ class Add_File(Cmdlet):
return None, None, None
@staticmethod
def _scan_directory_for_files(directory: Path) -> List[Dict[str, Any]]:
def _scan_directory_for_files(directory: Path, compute_hash: bool = True) -> List[Dict[str, Any]]:
"""Scan a directory for supported media files and return list of file info dicts.
Each dict contains:
- path: Path object
- name: filename
- hash: sha256 hash
- hash: sha256 hash (or None if compute_hash=False)
- size: file size in bytes
- ext: file extension
"""
@@ -1172,12 +1172,15 @@ class Add_File(Cmdlet):
if ext not in SUPPORTED_MEDIA_EXTENSIONS:
continue
# Compute hash
try:
file_hash = sha256_file(item)
except Exception as exc:
debug(f"Failed to hash {item}: {exc}")
continue
file_hash = None
# Compute hash if requested (computing can be expensive for large dirs)
if compute_hash:
try:
file_hash = sha256_file(item)
except Exception as exc:
debug(f"Failed to hash {item}: {exc}")
# If hashing is required, skip this file; otherwise include without hash
continue
# Get file size
try:
@@ -2046,10 +2049,15 @@ class Add_File(Cmdlet):
except Exception:
stored_path = None
# Compute canonical hash value for downstream use (defensive against non-string returns).
if isinstance(file_identifier, str) and len(file_identifier) == 64:
chosen_hash = file_identifier
else:
chosen_hash = f_hash or (str(file_identifier) if file_identifier is not None else "unknown")
Add_File._update_pipe_object_destination(
pipe_obj,
hash_value=file_identifier
if len(file_identifier) == 64 else f_hash or "unknown",
hash_value=chosen_hash,
store=backend_name,
path=stored_path,
tag=tags,
@@ -2061,10 +2069,7 @@ class Add_File(Cmdlet):
# Emit a search-file-like payload for consistent tables and natural piping.
# Keep hash/store for downstream commands (get-tag, get-file, etc.).
resolved_hash = (
file_identifier if len(file_identifier) == 64 else
(f_hash or file_identifier or "unknown")
)
resolved_hash = chosen_hash
if hydrus_like_backend and tags:
try:
@@ -2433,19 +2438,21 @@ class Add_File(Cmdlet):
@staticmethod
def _cleanup_after_success(media_path: Path, delete_source: bool):
if not delete_source:
return
# Check if it's a temp file that should always be deleted
# Determine whether this is a temporary merge/tracking file which should be
# deleted even when delete_source is False.
is_temp_merge = "(merged)" in media_path.name or ".dlhx_" in media_path.name
if delete_source or is_temp_merge:
##log(f"Deleting source file...", file=sys.stderr)
try:
media_path.unlink()
Add_File._cleanup_sidecar_files(media_path)
except Exception as exc:
log(f"⚠️ Could not delete file: {exc}", file=sys.stderr)
# If neither explicit delete was requested nor this looks like a temp-merge,
# avoid deleting the source file.
if not delete_source and not is_temp_merge:
return
# Attempt deletion (best-effort)
try:
media_path.unlink()
Add_File._cleanup_sidecar_files(media_path)
except Exception as exc:
log(f"⚠️ Could not delete file: {exc}", file=sys.stderr)
@staticmethod
def _cleanup_sidecar_files(media_path: Path):