updating and refining plugin system refactor

This commit is contained in:
2026-04-28 22:20:54 -07:00
parent 8685fbb723
commit 323c24f4f4
33 changed files with 4287 additions and 3312 deletions
+37 -17
View File
@@ -1,4 +1,4 @@
"""search-file cmdlet: Search for files in storage backends (Hydrus)."""
"""search-file cmdlet: Search store backends and search-capable plugins."""
from __future__ import annotations
@@ -15,11 +15,11 @@ from urllib.parse import urlparse, parse_qs, unquote, urljoin
from SYS.logger import log, debug, debug_panel
from SYS.payload_builders import build_file_result_payload, normalize_file_extension
from ProviderCore.registry import get_search_plugin, list_search_plugins
from ProviderCore.registry import get_plugin_with_capability, list_plugins_with_capability
from SYS.rich_display import (
show_provider_config_panel,
show_plugin_config_panel,
show_store_config_panel,
show_available_providers_panel,
show_available_plugins_panel,
)
from SYS.database import insert_worker, update_worker, append_worker_stdout
from SYS.item_accessors import get_extension_field, get_int_field, get_result_title
@@ -164,13 +164,13 @@ def _summarize_worker_results(results: Sequence[Dict[str, Any]], preview_limit:
class search_file(Cmdlet):
"""Class-based search-file cmdlet for searching storage backends."""
"""Class-based search-file cmdlet for searching backends and providers."""
def __init__(self) -> None:
super().__init__(
name="search-file",
summary="Search storage backends (Hydrus) or external plugins (via -plugin).",
usage="search-file [-query <query>] [-store BACKEND] [-limit N] [-plugin NAME]",
summary="Search configured store backends or search-capable plugins.",
usage="search-file [-query <query>] [-store BACKEND] [-instance NAME] [-limit N] [-plugin NAME]",
arg=[
CmdletArg(
"limit",
@@ -178,6 +178,7 @@ class search_file(Cmdlet):
description="Limit results (default: 100)"
),
SharedArgs.STORE,
SharedArgs.INSTANCE,
SharedArgs.QUERY,
SharedArgs.PLUGIN,
CmdletArg(
@@ -187,8 +188,10 @@ class search_file(Cmdlet):
),
],
detail=[
"Search across storage backends: Hydrus instances",
"Use -store to search a specific backend by name",
"Search across configured store backends or plugin providers.",
"Use -store to target a specific store backend by name.",
"Use -plugin with -instance to target a named provider config.",
"In plugin mode, -store <name> is kept as a compatibility alias for -instance <name>.",
"URL search: url:* (any URL) or url:<value> (URL substring)",
"Extension search: ext:<value> (e.g., ext:png)",
"Hydrus-style extension: system:filetype = png",
@@ -207,6 +210,7 @@ class search_file(Cmdlet):
"",
"Plugin search (-plugin):",
"search-file -plugin youtube 'tutorial' # Search YouTube plugin",
"search-file -plugin ftp -instance work '*' # Search a named FTP/SCP plugin instance",
"search-file -plugin alldebrid '*' # List AllDebrid magnets",
"search-file -plugin alldebrid -open 123 '*' # Show files for a magnet",
],
@@ -1451,6 +1455,7 @@ class search_file(Cmdlet):
self,
*,
plugin_name: str,
instance_name: Optional[str],
query: str,
limit: int,
limit_set: bool,
@@ -1475,15 +1480,15 @@ class search_file(Cmdlet):
log("Error: search-file -plugin requires both plugin and query", file=sys.stderr)
log(f"Usage: {self.usage}", file=sys.stderr)
providers_map = list_search_plugins(config)
providers_map = list_plugins_with_capability("search", config)
available = [n for n, a in providers_map.items() if a]
unconfigured = [n for n, a in providers_map.items() if not a]
if unconfigured:
show_provider_config_panel(unconfigured)
show_plugin_config_panel(unconfigured)
if available:
show_available_providers_panel(available)
show_available_plugins_panel(available)
return 1
@@ -1496,7 +1501,7 @@ class search_file(Cmdlet):
if hasattr(ctx_mod, "get_pipeline_state"):
progress = ctx_mod.get_pipeline_state().live_progress
provider = get_search_plugin(plugin_name, config)
provider = get_plugin_with_capability(plugin_name, "search", config)
if not provider:
if progress:
try:
@@ -1504,12 +1509,12 @@ class search_file(Cmdlet):
except Exception:
pass
show_provider_config_panel([plugin_name])
show_plugin_config_panel([plugin_name])
providers_map = list_search_plugins(config)
providers_map = list_plugins_with_capability("search", config)
available = [n for n, a in providers_map.items() if a]
if available:
show_available_providers_panel(available)
show_available_plugins_panel(available)
return 1
worker_id = str(uuid.uuid4())
@@ -1542,6 +1547,8 @@ class search_file(Cmdlet):
normalized_query = (normalized_query or "").strip()
query = normalized_query or "*"
search_filters = dict(provider_filters or {})
if instance_name and not search_filters.get("instance"):
search_filters["instance"] = str(instance_name).strip()
# Dynamic table generation via provider
table_title = provider.get_table_title(query, search_filters).strip().rstrip(":")
@@ -1564,6 +1571,7 @@ class search_file(Cmdlet):
"search-file provider request",
[
("provider", plugin_name),
("instance", search_filters.get("instance") or "<default>"),
("query", query),
("limit", limit),
("filters", search_filters or "<none>"),
@@ -1581,7 +1589,7 @@ class search_file(Cmdlet):
border_style="cyan",
)
# Allow providers to apply provider-specific UX transforms (e.g. auto-expansion)
# Allow plugins to apply plugin-specific UX transforms (e.g. auto-expansion)
try:
post = getattr(provider, "postprocess_search_results", None)
if callable(post) and isinstance(results, list):
@@ -1737,6 +1745,10 @@ class search_file(Cmdlet):
f.lower()
for f in (flag_registry.get("store") or {"-store", "--store"})
}
instance_flags = {
f.lower()
for f in (flag_registry.get("instance") or {"-instance", "--instance"})
}
limit_flags = {
f.lower()
for f in (flag_registry.get("limit") or {"-limit", "--limit"})
@@ -1753,6 +1765,7 @@ class search_file(Cmdlet):
# Parse arguments
query = ""
storage_backend: Optional[str] = None
instance_name: Optional[str] = None
plugin_name: Optional[str] = None
open_id: Optional[int] = None
limit = 100
@@ -1773,6 +1786,10 @@ class search_file(Cmdlet):
plugin_name = args_list[i + 1]
i += 2
continue
if low in instance_flags and i + 1 < len(args_list):
instance_name = args_list[i + 1]
i += 2
continue
if low in open_flags and i + 1 < len(args_list):
try:
open_id = int(args_list[i + 1])
@@ -1804,8 +1821,11 @@ class search_file(Cmdlet):
query = query.strip()
if plugin_name:
if storage_backend and not instance_name:
instance_name = storage_backend
return self._run_plugin_search(
plugin_name=plugin_name,
instance_name=instance_name,
query=query,
limit=limit,
limit_set=limit_set,