df
This commit is contained in:
@@ -5,6 +5,7 @@ from pathlib import Path
|
||||
from copy import deepcopy
|
||||
import sys
|
||||
import shutil
|
||||
import tempfile
|
||||
import re
|
||||
|
||||
from SYS import models
|
||||
@@ -501,7 +502,7 @@ class Add_File(Cmdlet):
|
||||
temp_dir_to_cleanup: Optional[Path] = None
|
||||
delete_after_item = delete_after
|
||||
try:
|
||||
media_path, file_hash = self._resolve_source(
|
||||
media_path, file_hash, temp_dir_to_cleanup = self._resolve_source(
|
||||
item, path_arg, pipe_obj, config
|
||||
)
|
||||
debug(
|
||||
@@ -901,6 +902,38 @@ class Add_File(Cmdlet):
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
@staticmethod
|
||||
def _maybe_download_backend_file(
|
||||
backend: Any,
|
||||
file_hash: str,
|
||||
pipe_obj: models.PipeObject,
|
||||
) -> Tuple[Optional[Path], Optional[Path]]:
|
||||
"""Best-effort fetch of a backend file when get_file returns a URL.
|
||||
|
||||
Returns (downloaded_path, temp_dir_to_cleanup).
|
||||
"""
|
||||
|
||||
downloader = getattr(backend, "download_to_temp", None)
|
||||
if not callable(downloader):
|
||||
return None, None
|
||||
|
||||
tmp_dir: Optional[Path] = None
|
||||
try:
|
||||
tmp_dir = Path(tempfile.mkdtemp(prefix="add-file-src-"))
|
||||
downloaded = downloader(str(file_hash), temp_root=tmp_dir)
|
||||
if isinstance(downloaded, Path) and downloaded.exists():
|
||||
pipe_obj.is_temp = True
|
||||
return downloaded, tmp_dir
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if tmp_dir is not None:
|
||||
try:
|
||||
shutil.rmtree(tmp_dir, ignore_errors=True)
|
||||
except Exception:
|
||||
pass
|
||||
return None, None
|
||||
|
||||
@staticmethod
|
||||
def _resolve_source(
|
||||
result: Any,
|
||||
@@ -909,10 +942,11 @@ class Add_File(Cmdlet):
|
||||
config: Dict[str,
|
||||
Any],
|
||||
) -> Tuple[Optional[Path],
|
||||
Optional[str]]:
|
||||
Optional[str],
|
||||
Optional[Path]]:
|
||||
"""Resolve the source file path from args or pipeline result.
|
||||
|
||||
Returns (media_path, file_hash).
|
||||
Returns (media_path, file_hash, temp_dir_to_cleanup).
|
||||
"""
|
||||
# PRIORITY 1a: Try hash+path from directory scan result (has 'path' and 'hash' keys)
|
||||
if isinstance(result, dict):
|
||||
@@ -931,7 +965,7 @@ class Add_File(Cmdlet):
|
||||
f"[add-file] Using path+hash from directory scan: {media_path}"
|
||||
)
|
||||
pipe_obj.path = str(media_path)
|
||||
return media_path, str(result_hash)
|
||||
return media_path, str(result_hash), None
|
||||
except Exception as exc:
|
||||
debug(f"[add-file] Failed to use directory scan result: {exc}")
|
||||
|
||||
@@ -950,7 +984,17 @@ class Add_File(Cmdlet):
|
||||
media_path = backend.get_file(result_hash)
|
||||
if isinstance(media_path, Path) and media_path.exists():
|
||||
pipe_obj.path = str(media_path)
|
||||
return media_path, str(result_hash)
|
||||
return media_path, str(result_hash), None
|
||||
|
||||
if isinstance(media_path, str) and media_path.strip():
|
||||
downloaded, tmp_dir = Add_File._maybe_download_backend_file(
|
||||
backend,
|
||||
str(result_hash),
|
||||
pipe_obj,
|
||||
)
|
||||
if isinstance(downloaded, Path) and downloaded.exists():
|
||||
pipe_obj.path = str(downloaded)
|
||||
return downloaded, str(result_hash), tmp_dir
|
||||
except Exception as exc:
|
||||
debug(f"[add-file] Failed to retrieve via hash+store: {exc}")
|
||||
|
||||
@@ -959,7 +1003,7 @@ class Add_File(Cmdlet):
|
||||
media_path = Path(path_arg)
|
||||
pipe_obj.path = str(media_path)
|
||||
debug(f"[add-file] Using explicit path argument: {media_path}")
|
||||
return media_path, None
|
||||
return media_path, None, None
|
||||
|
||||
# PRIORITY 3: Try from pipe_obj.path (check file first before URL)
|
||||
pipe_path = getattr(pipe_obj, "path", None)
|
||||
@@ -976,8 +1020,8 @@ class Add_File(Cmdlet):
|
||||
"add-file ingests local files only. Use download-file first.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return None, None
|
||||
return Path(pipe_path_str), None
|
||||
return None, None, None
|
||||
return Path(pipe_path_str), None, None
|
||||
|
||||
# Try from result (if it's a string path or URL)
|
||||
if isinstance(result, str):
|
||||
@@ -993,10 +1037,10 @@ class Add_File(Cmdlet):
|
||||
"add-file ingests local files only. Use download-file first.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return None, None
|
||||
return None, None, None
|
||||
media_path = Path(result)
|
||||
pipe_obj.path = str(media_path)
|
||||
return media_path, None
|
||||
return media_path, None, None
|
||||
|
||||
# Try from result if it's a list (pipeline emits multiple results)
|
||||
if isinstance(result, list) and result:
|
||||
@@ -1014,10 +1058,10 @@ class Add_File(Cmdlet):
|
||||
"add-file ingests local files only. Use download-file first.",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return None, None
|
||||
return None, None, None
|
||||
media_path = Path(first_item)
|
||||
pipe_obj.path = str(media_path)
|
||||
return media_path, None
|
||||
return media_path, None, None
|
||||
|
||||
# If the first item is a dict, interpret it as a PipeObject-style result
|
||||
if isinstance(first_item, dict):
|
||||
@@ -1037,9 +1081,9 @@ class Add_File(Cmdlet):
|
||||
try:
|
||||
media_path = Path(path_candidate)
|
||||
pipe_obj.path = str(media_path)
|
||||
return media_path, first_item.get("hash")
|
||||
return media_path, first_item.get("hash"), None
|
||||
except Exception:
|
||||
return None, first_item.get("hash")
|
||||
return None, first_item.get("hash"), None
|
||||
|
||||
# If first item is a PipeObject object
|
||||
try:
|
||||
@@ -1052,7 +1096,7 @@ class Add_File(Cmdlet):
|
||||
debug(f"Resolved path from PipeObject: {path_candidate}")
|
||||
media_path = Path(path_candidate)
|
||||
pipe_obj.path = str(media_path)
|
||||
return media_path, getattr(first_item, "hash", None)
|
||||
return media_path, getattr(first_item, "hash", None), None
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -1060,7 +1104,7 @@ class Add_File(Cmdlet):
|
||||
f"No resolution path matched. pipe_obj.path={pipe_path}, result type={type(result).__name__}"
|
||||
)
|
||||
log("File path could not be resolved")
|
||||
return None, None
|
||||
return None, None, None
|
||||
|
||||
@staticmethod
|
||||
def _scan_directory_for_files(directory: Path) -> List[Dict[str, Any]]:
|
||||
@@ -1778,6 +1822,12 @@ class Add_File(Cmdlet):
|
||||
store = Store(config)
|
||||
backend = store[backend_name]
|
||||
|
||||
hydrus_like_backend = False
|
||||
try:
|
||||
hydrus_like_backend = str(type(backend).__name__ or "").lower().startswith("hydrus")
|
||||
except Exception:
|
||||
hydrus_like_backend = False
|
||||
|
||||
# Prepare metadata from pipe_obj and sidecars
|
||||
tags, url, title, f_hash = Add_File._prepare_metadata(
|
||||
result, media_path, pipe_obj, config
|
||||
@@ -1870,6 +1920,11 @@ class Add_File(Cmdlet):
|
||||
log(f"[add-file] FlorenceVision tagging error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
upload_tags = tags
|
||||
if hydrus_like_backend and upload_tags:
|
||||
upload_tags = []
|
||||
debug("[add-file] Deferring tag application until after Hydrus upload")
|
||||
|
||||
debug(
|
||||
f"[add-file] Storing into backend '{backend_name}' path='{media_path}' title='{title}'"
|
||||
)
|
||||
@@ -1879,7 +1934,7 @@ class Add_File(Cmdlet):
|
||||
file_identifier = backend.add_file(
|
||||
media_path,
|
||||
title=title,
|
||||
tag=tags,
|
||||
tag=upload_tags,
|
||||
url=[] if (defer_url_association and url) else url,
|
||||
)
|
||||
debug(
|
||||
@@ -1921,6 +1976,17 @@ class Add_File(Cmdlet):
|
||||
(f_hash or file_identifier or "unknown")
|
||||
)
|
||||
|
||||
if hydrus_like_backend and tags:
|
||||
try:
|
||||
adder = getattr(backend, "add_tag", None)
|
||||
if callable(adder):
|
||||
debug(
|
||||
f"[add-file] Applying {len(tags)} tag(s) post-upload to Hydrus"
|
||||
)
|
||||
adder(resolved_hash, list(tags))
|
||||
except Exception as exc:
|
||||
log(f"[add-file] Hydrus post-upload tagging failed: {exc}", file=sys.stderr)
|
||||
|
||||
# If we have url(s), ensure they get associated with the destination file.
|
||||
# This mirrors `add-url` behavior but avoids emitting extra pipeline noise.
|
||||
if url:
|
||||
|
||||
Reference in New Issue
Block a user