This commit is contained in:
2026-01-19 21:25:44 -08:00
parent 37e2ff6651
commit fcab85455d
13 changed files with 820 additions and 393 deletions

View File

@@ -86,9 +86,22 @@ class Get_File(sh.Cmdlet):
debug(f"[get-file] Getting storage backend: {store_name}")
# Get storage backend
store = Store(config)
backend = store[store_name]
# Prefer instantiating only the named backend to avoid initializing all configured backends
try:
from Store.registry import get_backend_instance
backend = get_backend_instance(config, store_name, suppress_debug=True)
except Exception:
backend = None
if backend is None:
# Fallback to full registry when targeted instantiation fails
try:
store = Store(config)
backend = store[store_name]
except Exception:
log(f"Error: Storage backend '{store_name}' not found", file=sys.stderr)
return 1
debug(f"[get-file] Backend retrieved: {type(backend).__name__}")
# Get file metadata to determine name and extension

View File

@@ -192,10 +192,21 @@ class Get_Metadata(Cmdlet):
# Use storage backend to get metadata
try:
from Store import Store
# Instantiate only the required backend when possible to avoid initializing all configured backends
try:
from Store.registry import get_backend_instance
backend = get_backend_instance(config, storage_source, suppress_debug=True)
except Exception:
backend = None
storage = Store(config)
backend = storage[storage_source]
if backend is None:
try:
from Store import Store
storage = Store(config)
backend = storage[storage_source]
except Exception:
log(f"Storage backend '{storage_source}' not found", file=sys.stderr)
return 1
# Get metadata from backend
metadata = backend.get_metadata(file_hash)
@@ -290,6 +301,13 @@ class Get_Metadata(Cmdlet):
list(args))
self._add_table_body_row(table, row)
ctx.set_last_result_table_overlay(table, [row], row)
try:
from SYS.rich_display import render_item_details_panel
render_item_details_panel(row)
table._rendered_by_cmdlet = True
except Exception:
pass
ctx.emit(row)
return 0

View File

@@ -211,18 +211,27 @@ class search_file(Cmdlet):
worker_id = str(uuid.uuid4())
library_root = get_local_storage_path(config or {}) if get_local_storage_path else None
if not library_root:
try:
from Store import Store
storage_registry = Store(config=config or {})
# Try the first folder backend
for name in storage_registry.list_backends():
backend = storage_registry[name]
if type(backend).__name__ == "Folder":
library_root = expand_path(getattr(backend, "_location", None))
if library_root:
break
from Store.registry import get_backend_instance
# Try the first configured folder backend without instantiating all backends
store_cfg = (config or {}).get("store") or {}
folder_cfg = None
for raw_store_type, instances in store_cfg.items():
if _normalize_store_type(str(raw_store_type)) == "folder":
folder_cfg = instances
break
if isinstance(folder_cfg, dict):
for instance_name, instance_config in folder_cfg.items():
try:
backend = get_backend_instance(config, instance_name, suppress_debug=True)
if backend and type(backend).__name__ == "Folder":
library_root = expand_path(getattr(backend, "_location", None))
if library_root:
break
except Exception:
pass
except Exception:
pass
@@ -655,10 +664,9 @@ class search_file(Cmdlet):
except Exception:
pass
from Store import Store
from Store.registry import list_configured_backend_names, get_backend_instance
from Store._base import Store as BaseStore
storage = storage_registry
backend_to_search = storage_backend or None
if hash_query:
# Explicit hash list search: build rows from backend metadata.
@@ -666,7 +674,7 @@ class search_file(Cmdlet):
if backend_to_search:
backends_to_try = [backend_to_search]
else:
backends_to_try = list(storage.list_backends())
backends_to_try = list_configured_backend_names(config or {})
found_any = False
for h in hash_query:
@@ -674,9 +682,17 @@ class search_file(Cmdlet):
resolved_backend = None
for backend_name in backends_to_try:
backend = None
try:
backend = storage[backend_name]
backend = get_backend_instance(config, backend_name, suppress_debug=True)
if backend is None:
# Last-resort: instantiate full registry for this backend only
from Store import Store as _Store
_store = _Store(config=config)
backend = _store[backend_name]
except Exception:
backend = None
if backend is None:
continue
try:
# If get_metadata works, consider it a hit; get_file can be optional (e.g. remote URL).
@@ -828,7 +844,17 @@ class search_file(Cmdlet):
if backend_to_search:
searched_backends.append(backend_to_search)
target_backend = storage[backend_to_search]
try:
target_backend = get_backend_instance(config, backend_to_search, suppress_debug=True)
if target_backend is None:
from Store import Store as _Store
_store = _Store(config=config)
target_backend = _store[backend_to_search]
except Exception as exc:
log(f"Backend '{backend_to_search}' not found: {exc}", file=sys.stderr)
db.update_worker_status(worker_id, "error")
return 1
if type(target_backend).search is BaseStore.search:
log(
f"Backend '{backend_to_search}' does not support searching",
@@ -843,11 +869,19 @@ class search_file(Cmdlet):
)
else:
all_results = []
for backend_name in storage.list_searchable_backends():
for backend_name in list_configured_backend_names(config or {}):
try:
backend = storage[backend_name]
backend = get_backend_instance(config, backend_name, suppress_debug=True)
if backend is None:
from Store import Store as _Store
_store = _Store(config=config)
backend = _store[backend_name]
searched_backends.append(backend_name)
if type(backend).search is BaseStore.search:
continue
debug(f"[search-file] Searching '{backend_name}'")
backend_results = backend.search(
query,
@@ -909,6 +943,62 @@ class search_file(Cmdlet):
if store_val and not normalized.get("store"):
normalized["store"] = store_val
# Populate default selection args for interactive @N selection/hash/url handling
try:
sel_args: Optional[List[str]] = None
sel_action: Optional[List[str]] = None
# Prefer explicit path when available
p_val = normalized.get("path") or normalized.get("target") or normalized.get("url")
if p_val:
p_str = str(p_val or "").strip()
if p_str:
if p_str.startswith(("http://", "https://", "magnet:", "torrent:")):
sel_args = ["-url", p_str]
sel_action = ["download-file", "-url", p_str]
else:
try:
from SYS.utils import expand_path
full_path = expand_path(p_str)
# Prefer showing metadata details when we have a hash+store context
h = normalized.get("hash") or normalized.get("file_hash") or normalized.get("hash_hex")
s_val = normalized.get("store")
if h and s_val:
try:
h_norm = normalize_hash(h)
except Exception:
h_norm = str(h)
sel_args = ["-query", f"hash:{h_norm}", "-store", str(s_val)]
sel_action = ["get-metadata", "-query", f"hash:{h_norm}", "-store", str(s_val)]
else:
sel_args = ["-path", str(full_path)]
# Default action for local paths: get-file to fetch or operate on the path
sel_action = ["get-file", "-path", str(full_path)]
except Exception:
sel_args = ["-path", p_str]
sel_action = ["get-file", "-path", p_str]
# Fallback: use hash+store when available
if sel_args is None:
h = normalized.get("hash") or normalized.get("file_hash") or normalized.get("hash_hex")
s_val = normalized.get("store")
if h and s_val:
try:
h_norm = normalize_hash(h)
except Exception:
h_norm = str(h)
sel_args = ["-query", f"hash:{h_norm}", "-store", str(s_val)]
# Show metadata details by default for store/hash selections
sel_action = ["get-metadata", "-query", f"hash:{h_norm}", "-store", str(s_val)]
if sel_args:
normalized["_selection_args"] = [str(x) for x in sel_args]
if sel_action:
normalized["_selection_action"] = [str(x) for x in sel_action]
except Exception:
pass
table.add_result(normalized)
results_list.append(normalized)