d
This commit is contained in:
174
CLI.py
174
CLI.py
@@ -407,24 +407,27 @@ def _get_cmdlet_names() -> List[str]:
|
||||
return []
|
||||
|
||||
|
||||
def _import_cmd_module(mod_name: str):
|
||||
"""Import a cmdlet/native module from cmdlets or cmdnats packages."""
|
||||
for package in ("cmdlets", "cmdnats", None):
|
||||
try:
|
||||
qualified = f"{package}.{mod_name}" if package else mod_name
|
||||
return import_module(qualified)
|
||||
except ModuleNotFoundError:
|
||||
continue
|
||||
except Exception:
|
||||
continue
|
||||
return None
|
||||
|
||||
|
||||
def _get_cmdlet_args(cmd_name: str) -> List[str]:
|
||||
"""Get list of argument flags for a cmdlet (with - and -- prefixes)."""
|
||||
try:
|
||||
# Try to load CMDLET object from the module
|
||||
mod_name = cmd_name.replace("-", "_")
|
||||
|
||||
# Try importing as cmdlet first, then as root-level module
|
||||
data = None
|
||||
try:
|
||||
mod = import_module(f"cmdlets.{mod_name}")
|
||||
mod = _import_cmd_module(mod_name)
|
||||
if mod:
|
||||
data = getattr(mod, "CMDLET", None)
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
try:
|
||||
# Try root-level modules like search_soulseek
|
||||
mod = import_module(mod_name)
|
||||
data = getattr(mod, "CMDLET", None)
|
||||
except (ModuleNotFoundError, ImportError):
|
||||
pass
|
||||
|
||||
if data:
|
||||
# If CMDLET is an object (not dict), use build_flag_registry if available
|
||||
@@ -458,25 +461,56 @@ def _get_arg_choices(cmd_name: str, arg_name: str) -> List[str]:
|
||||
"""Get list of valid choices for a specific cmdlet argument."""
|
||||
try:
|
||||
mod_name = cmd_name.replace("-", "_")
|
||||
try:
|
||||
mod = import_module(f"cmdlets.{mod_name}")
|
||||
data = getattr(mod, "CMDLET", None)
|
||||
if data:
|
||||
args_list = data.get("args", []) if isinstance(data, dict) else getattr(data, "args", [])
|
||||
for arg in args_list:
|
||||
normalized_arg = arg_name.lstrip("-")
|
||||
|
||||
# Dynamic storage backends: use current config to enumerate available storages
|
||||
if normalized_arg == "storage":
|
||||
try:
|
||||
from helper.file_storage import FileStorage
|
||||
storage = FileStorage(_load_cli_config())
|
||||
backends = storage.list_backends()
|
||||
if backends:
|
||||
return backends
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Dynamic search providers
|
||||
if normalized_arg == "provider":
|
||||
try:
|
||||
from helper.search_provider import list_providers
|
||||
providers = list_providers(_load_cli_config())
|
||||
available = [name for name, is_ready in providers.items() if is_ready]
|
||||
provider_choices = sorted(available) if available else sorted(providers.keys())
|
||||
except Exception:
|
||||
provider_choices = []
|
||||
|
||||
try:
|
||||
from helper.metadata_search import list_metadata_providers
|
||||
meta_providers = list_metadata_providers(_load_cli_config())
|
||||
meta_available = [n for n, ready in meta_providers.items() if ready]
|
||||
meta_choices = sorted(meta_available) if meta_available else sorted(meta_providers.keys())
|
||||
except Exception:
|
||||
meta_choices = []
|
||||
|
||||
merged = sorted(set(provider_choices + meta_choices))
|
||||
if merged:
|
||||
return merged
|
||||
mod = _import_cmd_module(mod_name)
|
||||
data = getattr(mod, "CMDLET", None) if mod else None
|
||||
if data:
|
||||
args_list = data.get("args", []) if isinstance(data, dict) else getattr(data, "args", [])
|
||||
for arg in args_list:
|
||||
if isinstance(arg, dict):
|
||||
arg_obj_name = arg.get("name", "")
|
||||
else:
|
||||
arg_obj_name = getattr(arg, "name", "")
|
||||
|
||||
if arg_obj_name == arg_name:
|
||||
# Found matching arg, get choices
|
||||
if isinstance(arg, dict):
|
||||
arg_obj_name = arg.get("name", "")
|
||||
return arg.get("choices", [])
|
||||
else:
|
||||
arg_obj_name = getattr(arg, "name", "")
|
||||
|
||||
if arg_obj_name == arg_name:
|
||||
# Found matching arg, get choices
|
||||
if isinstance(arg, dict):
|
||||
return arg.get("choices", [])
|
||||
else:
|
||||
return getattr(arg, "choices", [])
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
return getattr(arg, "choices", [])
|
||||
return []
|
||||
except Exception:
|
||||
return []
|
||||
@@ -1575,43 +1609,40 @@ def _show_cmdlet_list():
|
||||
from cmdlets import REGISTRY
|
||||
import os
|
||||
|
||||
# Collect unique commands by scanning cmdlet modules
|
||||
cmdlet_info = {}
|
||||
cmdlets_dir = os.path.join(os.path.dirname(__file__), "cmdlets")
|
||||
|
||||
# Iterate through cmdlet files
|
||||
for filename in os.listdir(cmdlets_dir):
|
||||
if filename.endswith(".py") and not filename.startswith("_"):
|
||||
mod_name = filename[:-3]
|
||||
try:
|
||||
mod = import_module(f"cmdlets.{mod_name}")
|
||||
if hasattr(mod, "CMDLET"):
|
||||
cmdlet = getattr(mod, "CMDLET")
|
||||
# Extract name, aliases, and args
|
||||
if hasattr(cmdlet, "name"):
|
||||
cmd_name = cmdlet.name
|
||||
aliases = []
|
||||
if hasattr(cmdlet, "aliases"):
|
||||
aliases = cmdlet.aliases
|
||||
|
||||
# Extract argument names
|
||||
arg_names = []
|
||||
if hasattr(cmdlet, "args"):
|
||||
for arg in cmdlet.args:
|
||||
if hasattr(arg, "name"):
|
||||
arg_names.append(arg.name)
|
||||
elif isinstance(arg, dict):
|
||||
arg_names.append(arg.get("name", ""))
|
||||
|
||||
# Store info (skip if already seen)
|
||||
if cmd_name not in cmdlet_info:
|
||||
cmdlet_info[cmd_name] = {
|
||||
"aliases": aliases,
|
||||
"args": arg_names,
|
||||
}
|
||||
except Exception:
|
||||
# If we can't import the module, try to get info from REGISTRY
|
||||
pass
|
||||
base_dir = os.path.dirname(__file__)
|
||||
|
||||
def _collect_cmdlets_from_dir(folder: str, package: str) -> None:
|
||||
if not os.path.isdir(folder):
|
||||
return
|
||||
for filename in os.listdir(folder):
|
||||
if filename.endswith(".py") and not filename.startswith("_") and filename != "__init__.py":
|
||||
mod_name = filename[:-3]
|
||||
try:
|
||||
mod = import_module(f"{package}.{mod_name}")
|
||||
if hasattr(mod, "CMDLET"):
|
||||
cmdlet = getattr(mod, "CMDLET")
|
||||
if hasattr(cmdlet, "name"):
|
||||
cmd_name = cmdlet.name
|
||||
aliases = getattr(cmdlet, "aliases", []) if hasattr(cmdlet, "aliases") else []
|
||||
|
||||
arg_names = []
|
||||
if hasattr(cmdlet, "args"):
|
||||
for arg in cmdlet.args:
|
||||
if hasattr(arg, "name"):
|
||||
arg_names.append(arg.name)
|
||||
elif isinstance(arg, dict):
|
||||
arg_names.append(arg.get("name", ""))
|
||||
if cmd_name not in cmdlet_info:
|
||||
cmdlet_info[cmd_name] = {
|
||||
"aliases": aliases,
|
||||
"args": arg_names,
|
||||
}
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
_collect_cmdlets_from_dir(os.path.join(base_dir, "cmdlets"), "cmdlets")
|
||||
_collect_cmdlets_from_dir(os.path.join(base_dir, "cmdnats"), "cmdnats")
|
||||
|
||||
# Also check root-level cmdlets (search_*, etc)
|
||||
# Note: search_libgen, search_soulseek, and search_debrid are consolidated into search-file with providers
|
||||
@@ -1700,14 +1731,11 @@ def _show_cmdlet_help(cmd_name: str):
|
||||
"""Display help for a cmdlet."""
|
||||
try:
|
||||
mod_name = cmd_name.replace("-", "_")
|
||||
try:
|
||||
mod = import_module(f"cmdlets.{mod_name}")
|
||||
data = getattr(mod, "CMDLET", None)
|
||||
if data:
|
||||
_print_metadata(cmd_name, data)
|
||||
return
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
mod = _import_cmd_module(mod_name)
|
||||
data = getattr(mod, "CMDLET", None) if mod else None
|
||||
if data:
|
||||
_print_metadata(cmd_name, data)
|
||||
return
|
||||
|
||||
from cmdlets import REGISTRY
|
||||
cmd_fn = REGISTRY.get(cmd_name)
|
||||
|
||||
Reference in New Issue
Block a user