updating and refining plugin system refactor
This commit is contained in:
@@ -506,32 +506,28 @@ class CmdletIntrospection:
|
||||
if normalized_arg == "plugin":
|
||||
canonical_cmd = (cmd_name or "").replace("_", "-").lower()
|
||||
try:
|
||||
from ProviderCore.registry import (
|
||||
list_search_plugin_names,
|
||||
list_upload_plugin_names,
|
||||
)
|
||||
from ProviderCore.registry import list_plugin_names_with_capability
|
||||
except Exception:
|
||||
list_search_plugin_names = None # type: ignore
|
||||
list_upload_plugin_names = None # type: ignore
|
||||
list_plugin_names_with_capability = None # type: ignore
|
||||
|
||||
provider_choices: List[str] = []
|
||||
plugin_choices: List[str] = []
|
||||
|
||||
if canonical_cmd in {"add-file"} and list_upload_plugin_names is not None:
|
||||
return list_upload_plugin_names() or []
|
||||
if canonical_cmd in {"add-file"} and list_plugin_names_with_capability is not None:
|
||||
return list_plugin_names_with_capability("upload") or []
|
||||
|
||||
if list_search_plugin_names is not None:
|
||||
provider_choices = list_search_plugin_names() or []
|
||||
if list_plugin_names_with_capability is not None:
|
||||
plugin_choices = list_plugin_names_with_capability("search") or []
|
||||
|
||||
if provider_choices:
|
||||
return provider_choices
|
||||
if plugin_choices:
|
||||
return plugin_choices
|
||||
|
||||
if normalized_arg == "scrape":
|
||||
try:
|
||||
from plugins.metadata_provider import list_metadata_providers
|
||||
from plugins.metadata_provider import list_metadata_plugins
|
||||
|
||||
meta_providers = list_metadata_providers(config) or {}
|
||||
if meta_providers:
|
||||
return sorted(meta_providers.keys())
|
||||
metadata_plugins = list_metadata_plugins(config) or {}
|
||||
if metadata_plugins:
|
||||
return sorted(metadata_plugins.keys())
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@@ -704,6 +700,77 @@ class CmdletCompleter(Completer):
|
||||
return tokens[idx + 1]
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _selected_plugin_name(cmd_name: str, stage_tokens: Sequence[str]) -> Optional[str]:
|
||||
canonical_cmd = str(cmd_name or "").replace("_", "-").strip().lower()
|
||||
if canonical_cmd not in {"search-file", "add-file", "download-file"}:
|
||||
return None
|
||||
return CmdletCompleter._flag_value(stage_tokens, "-plugin", "--plugin")
|
||||
|
||||
@staticmethod
|
||||
def _plugin_instance_choices(plugin_name: Optional[str], config: Dict[str, Any]) -> List[str]:
|
||||
plugin_key = str(plugin_name or "").strip().lower()
|
||||
if not plugin_key:
|
||||
return []
|
||||
|
||||
try:
|
||||
from ProviderCore.registry import get_plugin_class
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
plugin_class = get_plugin_class(plugin_key)
|
||||
if plugin_class is None:
|
||||
return []
|
||||
|
||||
try:
|
||||
plugin = plugin_class(config)
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
try:
|
||||
instances = plugin.configured_instances()
|
||||
except Exception:
|
||||
return []
|
||||
|
||||
out: List[str] = []
|
||||
seen: Set[str] = set()
|
||||
for value in instances or []:
|
||||
text = str(value or "").strip()
|
||||
lowered = text.lower()
|
||||
if not text or lowered in seen:
|
||||
continue
|
||||
seen.add(lowered)
|
||||
out.append(text)
|
||||
return out
|
||||
|
||||
def _filter_stage_arg_names(
|
||||
self,
|
||||
*,
|
||||
cmd_name: str,
|
||||
stage_tokens: Sequence[str],
|
||||
config: Dict[str, Any],
|
||||
arg_names: List[str],
|
||||
) -> List[str]:
|
||||
if not arg_names:
|
||||
return []
|
||||
|
||||
canonical_cmd = str(cmd_name or "").replace("_", "-").strip().lower()
|
||||
plugin_name = self._selected_plugin_name(canonical_cmd, stage_tokens)
|
||||
instance_choices = self._plugin_instance_choices(plugin_name, config)
|
||||
has_named_instances = bool(instance_choices)
|
||||
|
||||
filtered: List[str] = []
|
||||
for arg in arg_names:
|
||||
logical = str(arg or "").lstrip("-").strip().lower()
|
||||
if logical == "instance":
|
||||
if not plugin_name or not has_named_instances:
|
||||
continue
|
||||
if canonical_cmd == "search-file" and logical == "open":
|
||||
if str(plugin_name or "").strip().lower() != "alldebrid":
|
||||
continue
|
||||
filtered.append(arg)
|
||||
return filtered
|
||||
|
||||
def get_completions(
|
||||
self,
|
||||
document: Document,
|
||||
@@ -742,7 +809,12 @@ class CmdletCompleter(Completer):
|
||||
if cmd_name not in self.cmdlet_names:
|
||||
return
|
||||
|
||||
arg_names = self._cmdlet_args(cmd_name, config)
|
||||
arg_names = self._filter_stage_arg_names(
|
||||
cmd_name=cmd_name,
|
||||
stage_tokens=stage_tokens,
|
||||
config=config,
|
||||
arg_names=self._cmdlet_args(cmd_name, config),
|
||||
)
|
||||
seen_logicals: Set[str] = set()
|
||||
for arg in arg_names:
|
||||
arg_low = arg.lower()
|
||||
@@ -779,6 +851,8 @@ class CmdletCompleter(Completer):
|
||||
if cmd_name == "search-file":
|
||||
provider_name = self._flag_value(stage_tokens, "-plugin", "--plugin")
|
||||
|
||||
selected_plugin = self._selected_plugin_name(cmd_name, stage_tokens)
|
||||
|
||||
query_specs = self._query_args(cmd_name, config)
|
||||
query_flag_index = -1
|
||||
for idx, tok in enumerate(stage_tokens):
|
||||
@@ -886,28 +960,43 @@ class CmdletCompleter(Completer):
|
||||
yield Completion(suggestion, start_position=start_pos)
|
||||
return
|
||||
|
||||
choices = self._arg_choices(
|
||||
cmd_name=cmd_name,
|
||||
arg_name=prev_token,
|
||||
config=config,
|
||||
force=False,
|
||||
)
|
||||
normalized_prev = prev_token.lstrip("-").strip().lower()
|
||||
choices: List[str] = []
|
||||
if normalized_prev == "instance" and selected_plugin:
|
||||
choices = self._plugin_instance_choices(selected_plugin, config)
|
||||
if not choices:
|
||||
choices = self._arg_choices(
|
||||
cmd_name=cmd_name,
|
||||
arg_name=prev_token,
|
||||
config=config,
|
||||
force=False,
|
||||
)
|
||||
if choices:
|
||||
choice_list = choices
|
||||
normalized_prev = prev_token.lstrip("-").strip().lower()
|
||||
if normalized_prev in {"plugin", "provider"} and current_token:
|
||||
current_lower = current_token.lower()
|
||||
filtered = [c for c in choices if current_lower in c.lower()]
|
||||
if filtered:
|
||||
choice_list = filtered
|
||||
|
||||
if normalized_prev == "instance" and current_token:
|
||||
current_lower = current_token.lower()
|
||||
filtered = [c for c in choice_list if current_lower in c.lower()]
|
||||
if filtered:
|
||||
choice_list = filtered
|
||||
|
||||
for choice in choice_list:
|
||||
yield Completion(choice, start_position=-len(current_token))
|
||||
# Example: if the user has typed `download-file -url ...`, then `url`
|
||||
# is considered used and should not be suggested again (even as `--url`).
|
||||
return
|
||||
|
||||
arg_names = self._cmdlet_args(cmd_name, config)
|
||||
arg_names = self._filter_stage_arg_names(
|
||||
cmd_name=cmd_name,
|
||||
stage_tokens=stage_tokens,
|
||||
config=config,
|
||||
arg_names=self._cmdlet_args(cmd_name, config),
|
||||
)
|
||||
used_logicals = self._used_arg_logicals(cmd_name, stage_tokens, config)
|
||||
logical_seen: Set[str] = set()
|
||||
for arg in arg_names:
|
||||
|
||||
Reference in New Issue
Block a user