updated
This commit is contained in:
+31
-3
@@ -98,7 +98,7 @@ DEBUG_PIPE_NOTE_PREVIEW_LENGTH = 256
|
||||
# Used by multiple methods in this file to guard against URL strings being
|
||||
# treated as local file paths.
|
||||
_REMOTE_URL_PREFIXES: tuple[str, ...] = (
|
||||
"http://", "https://", "magnet:", "torrent:", "tidal:", "hydrus:",
|
||||
"http://", "https://", "ftp://", "ftps://", "magnet:", "torrent:", "tidal:", "hydrus:",
|
||||
)
|
||||
|
||||
|
||||
@@ -1241,6 +1241,11 @@ class Add_File(Cmdlet):
|
||||
return None, None
|
||||
if not url_text.lower().startswith(_REMOTE_URL_PREFIXES):
|
||||
return None, None
|
||||
# This helper performs generic HTTP downloads only.
|
||||
# Non-HTTP schemes (e.g. hydrus://, tidal:) should be handled by
|
||||
# plugin-specific resolvers via _maybe_download_plugin_result.
|
||||
if not url_text.lower().startswith(("http://", "https://")):
|
||||
return None, None
|
||||
|
||||
tmp_dir: Optional[Path] = None
|
||||
try:
|
||||
@@ -1480,8 +1485,31 @@ class Add_File(Cmdlet):
|
||||
if candidate:
|
||||
s = str(candidate).lower()
|
||||
if s.startswith(_REMOTE_URL_PREFIXES):
|
||||
log("add-file ingests local files only. Use download-file first.", file=sys.stderr)
|
||||
return None, None, None
|
||||
# For remote sources, prefer plugin-specific resolvers first
|
||||
# (e.g. hydrus://), then generic HTTP fallback.
|
||||
downloaded_path, hash_hint, tmp_dir = Add_File._maybe_download_plugin_result(
|
||||
result,
|
||||
pipe_obj,
|
||||
config,
|
||||
deps=deps,
|
||||
)
|
||||
if downloaded_path:
|
||||
pipe_obj.path = str(downloaded_path)
|
||||
return downloaded_path, hash_hint, tmp_dir
|
||||
|
||||
dl_path, tmp_dir = Add_File._download_remote_backend_url(
|
||||
str(candidate),
|
||||
pipe_obj,
|
||||
file_hash=get_field(result, "hash") or get_field(result, "file_hash"),
|
||||
output_dir=export_destination,
|
||||
)
|
||||
if dl_path:
|
||||
pipe_obj.path = str(dl_path)
|
||||
hash_hint = get_field(result, "hash") or get_field(result, "file_hash")
|
||||
return dl_path, hash_hint, tmp_dir
|
||||
|
||||
log("add-file could not auto-fetch remote source. Use download-file first.", file=sys.stderr)
|
||||
return None, None, None
|
||||
|
||||
pipe_obj.path = str(candidate)
|
||||
# Retain hash from input if available to avoid re-hashing
|
||||
|
||||
+63
-4
@@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List, Sequence
|
||||
import posixpath
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
@@ -128,6 +129,27 @@ class Delete_File(sh.Cmdlet):
|
||||
else:
|
||||
store = sh.get_field(item, "store")
|
||||
|
||||
# Extract plugin/provider identity and full metadata for plugin-level dispatch
|
||||
provider_name = None
|
||||
full_metadata: Dict[str, Any] = {}
|
||||
if isinstance(item, dict):
|
||||
provider_name = item.get("provider") or item.get("table")
|
||||
raw_meta = item.get("full_metadata") or item.get("metadata")
|
||||
if isinstance(raw_meta, dict):
|
||||
full_metadata = raw_meta
|
||||
else:
|
||||
try:
|
||||
provider_name = sh.get_field(item, "provider") or sh.get_field(item, "table")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
raw_meta = sh.get_field(item, "full_metadata") or sh.get_field(item, "metadata")
|
||||
if isinstance(raw_meta, dict):
|
||||
full_metadata = raw_meta
|
||||
except Exception:
|
||||
pass
|
||||
provider_name = str(provider_name or "").strip().lower() or None
|
||||
|
||||
store_lower = str(store).lower() if store else ""
|
||||
hydrus_provider = get_plugin("hydrusnetwork", config)
|
||||
|
||||
@@ -169,14 +191,51 @@ class Delete_File(sh.Cmdlet):
|
||||
)
|
||||
|
||||
local_deleted = False
|
||||
_target_str = str(target).strip().lower() if isinstance(target, str) else ""
|
||||
local_target = (
|
||||
isinstance(target,
|
||||
str) and target.strip()
|
||||
and not str(target).lower().startswith(("http://",
|
||||
"https://"))
|
||||
isinstance(target, str) and target.strip()
|
||||
and not _target_str.startswith(("http://", "https://", "ftp://", "ftps://"))
|
||||
)
|
||||
deleted_rows: List[Dict[str, Any]] = []
|
||||
|
||||
# --- Plugin-level delete dispatch ---
|
||||
# When the item originates from a plugin (e.g. FTP), and that plugin exposes
|
||||
# a delete_file() method, delegate to it instead of attempting a local unlink.
|
||||
if conserve != "local" and provider_name and not is_hydrus_store:
|
||||
try:
|
||||
candidate_plugin = get_plugin(provider_name, config)
|
||||
plugin_deleter = getattr(candidate_plugin, "delete_file", None) if candidate_plugin else None
|
||||
if callable(plugin_deleter):
|
||||
# Prefer ftp_path from full_metadata; fall back to the path/url field
|
||||
remote = (
|
||||
full_metadata.get("ftp_path")
|
||||
or full_metadata.get("selection_url")
|
||||
or full_metadata.get("ftp_url")
|
||||
or (str(target).strip() if isinstance(target, str) else "")
|
||||
)
|
||||
instance_hint = full_metadata.get("instance") or None
|
||||
if remote:
|
||||
plugin_ok = bool(plugin_deleter(remote, instance=instance_hint))
|
||||
if plugin_ok:
|
||||
local_deleted = True
|
||||
size_hint = (
|
||||
full_metadata.get("size")
|
||||
or (item.get("size_bytes") if isinstance(item, dict) else None)
|
||||
or sh.get_field(item, "size_bytes")
|
||||
)
|
||||
deleted_rows.append(
|
||||
{
|
||||
"title": str(title_val).strip() if title_val else posixpath.basename(str(remote).rstrip("/")),
|
||||
"store": instance_hint or provider_name,
|
||||
"hash": hash_hex or "",
|
||||
"size_bytes": size_hint,
|
||||
"ext": _get_ext_from_item(),
|
||||
}
|
||||
)
|
||||
return deleted_rows
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# If this item references a configured non-Hydrus store backend, prefer deleting
|
||||
# via the backend API. This supports store items where `path`/`target` is the hash.
|
||||
if conserve != "local" and store and (not is_hydrus_store):
|
||||
|
||||
Reference in New Issue
Block a user