removed TUI and others

This commit is contained in:
2026-05-14 20:47:20 -07:00
parent 036977832b
commit 717cb13dda
31 changed files with 378 additions and 7790 deletions
+120 -37
View File
@@ -16,7 +16,7 @@ def add_startup_check(
name: str,
*,
provider: str = "",
store: str = "",
instance: str = "",
files: int | str | None = None,
detail: str = "",
) -> None:
@@ -24,11 +24,82 @@ def add_startup_check(
row.add_column("STATUS", upper_text(status))
row.add_column("NAME", upper_text(name))
row.add_column("PLUGIN", upper_text(provider or ""))
row.add_column("STORE", upper_text(store or ""))
row.add_column("INSTANCE", upper_text(instance or ""))
row.add_column("FILES", "" if files is None else str(files))
row.add_column("DETAIL", upper_text(detail or ""))
def _provider_config_map(config: dict) -> dict[str, Any]:
if not isinstance(config, dict):
return {}
provider_cfg = config.get("plugin")
if not isinstance(provider_cfg, dict):
provider_cfg = config.get("provider")
return provider_cfg if isinstance(provider_cfg, dict) else {}
def _iter_registered_plugin_infos() -> tuple[Any, ...]:
try:
from ProviderCore.registry import REGISTRY
return tuple(
sorted(
REGISTRY.iter_plugins(),
key=lambda info: str(
getattr(info, "canonical_name", "") or ""
).lower(),
)
)
except Exception:
return ()
def _extract_configured_instance_names(raw_entry: Any) -> list[str]:
if not isinstance(raw_entry, dict) or not raw_entry:
return []
if not all(isinstance(value, dict) for value in raw_entry.values()):
return []
names: list[str] = []
for key in raw_entry.keys():
name = str(key or "").strip()
if not name or name.lower() == "default":
continue
names.append(name)
return names
def _resolve_startup_instance_text(
plugin: Any,
summary: dict[str, Any],
configured_entry: Any,
) -> str:
instance_text = str(summary.get("instance") or "").strip()
if instance_text:
return instance_text
raw_instances = summary.get("instances")
if isinstance(raw_instances, (list, tuple, set)):
values = [str(value).strip() for value in raw_instances if str(value).strip()]
if values:
return ", ".join(values)
elif raw_instances is not None:
instance_text = str(raw_instances).strip()
if instance_text:
return instance_text
try:
configured_instances = plugin.configured_instances() if plugin is not None else []
except Exception:
configured_instances = []
if configured_instances:
return ", ".join(str(value).strip() for value in configured_instances if str(value).strip())
return ", ".join(_extract_configured_instance_names(configured_entry))
def has_store_subtype(cfg: dict, subtype: str) -> bool:
store_cfg = cfg.get("store")
if not isinstance(store_cfg, dict):
@@ -113,61 +184,73 @@ def ping_first(urls: list[str]) -> tuple[bool, str]:
def collect_plugin_startup_checks(config: dict) -> list[dict[str, Any]]:
provider_cfg = None
if isinstance(config, dict):
provider_cfg = config.get("plugin")
if not isinstance(provider_cfg, dict):
provider_cfg = config.get("provider")
if not isinstance(provider_cfg, dict) or not provider_cfg:
return []
try:
from ProviderCore.registry import get_plugin_class
except Exception:
return []
provider_cfg = _provider_config_map(config)
checks: list[dict[str, Any]] = []
for plugin_name in provider_cfg.keys():
plugin_key = str(plugin_name or "").strip().lower()
seen_plugin_keys: set[str] = set()
for info in _iter_registered_plugin_infos():
plugin_key = str(getattr(info, "canonical_name", "") or "").strip().lower()
if not plugin_key:
continue
seen_plugin_keys.add(plugin_key)
plugin_class = None
try:
plugin_class = get_plugin_class(plugin_key)
except Exception:
plugin_class = None
if plugin_class is None:
checks.append(
{
"status": "UNKNOWN",
"name": provider_display_name(plugin_key),
"plugin": plugin_key,
"detail": "Not registered",
}
)
continue
plugin = None
summary: dict[str, Any]
display_name = provider_display_name(plugin_key)
configured_entry: Any = None
try:
plugin = plugin_class(config)
plugin = info.plugin_class(config)
configured_entry = plugin.plugin_config_root()
summary = plugin.status_summary()
except Exception as exc:
summary = {
"status": "DISABLED",
"name": provider_display_name(plugin_key),
"name": display_name,
"plugin": plugin_key,
"detail": str(exc),
}
status = str(summary.get("status") or "UNKNOWN").strip().upper() or "UNKNOWN"
name = str(summary.get("name") or display_name)
detail = str(summary.get("detail") or "").strip()
if detail.lower() == "configured" and not configured_entry:
detail = "Available"
if not detail:
if status == "ENABLED":
detail = "Configured" if configured_entry else "Available"
else:
detail = "Not configured" if not configured_entry else "Unavailable"
checks.append(
{
"status": str(summary.get("status") or "UNKNOWN"),
"name": str(summary.get("name") or provider_display_name(plugin_key)),
"status": status,
"name": name,
"plugin": str(summary.get("plugin") or plugin_key),
"detail": str(summary.get("detail") or ""),
"instance": _resolve_startup_instance_text(
plugin,
summary,
configured_entry if configured_entry else provider_cfg.get(plugin_key),
),
"detail": detail,
"files": summary.get("files"),
}
)
for plugin_name, raw_entry in sorted(provider_cfg.items()):
plugin_key = str(plugin_name or "").strip().lower()
if not plugin_key or plugin_key in seen_plugin_keys:
continue
checks.append(
{
"status": "UNKNOWN",
"name": provider_display_name(plugin_key),
"plugin": plugin_key,
"instance": ", ".join(_extract_configured_instance_names(raw_entry)),
"detail": "Not registered",
"files": None,
}
)
return checks
+4 -40
View File
@@ -291,47 +291,11 @@ def _run(piped_result: Any, args: List[str], config: Dict[str, Any]) -> int:
return 1
if not args:
# Check if we're in an interactive terminal and can launch a Textual modal
if sys.stdin.isatty() and not piped_result:
try:
from textual.app import App
from TUI.modalscreen.config_modal import ConfigModal
class ConfigApp(App):
def on_mount(self) -> None:
self.title = "Config Editor"
# We push the modal screen. It will sit on top of the main (blank) screen.
# Using a callback to exit the app when the modal is dismissed.
self.push_screen(ConfigModal(), callback=self.exit_on_close)
def exit_on_close(self, result: Any = None) -> None:
self.exit()
with ctx.suspend_live_progress():
app = ConfigApp()
app.run()
# After modal exits, show the new status table if possible
try:
from cmdlet._shared import SharedArgs
from cmdnat.status import CMDLET as STATUS_CMDLET
# We reload the config one more time because it might have changed on disk
fresh_config = load_config()
# Force refresh of shared caches (especially stores)
SharedArgs._refresh_store_choices_cache(fresh_config)
# Update the global SharedArgs choices so cmdlets pick up new stores
SharedArgs.STORE.choices = SharedArgs.get_store_choices(fresh_config, force=True)
return STATUS_CMDLET.exec(None, [], fresh_config)
except Exception:
pass
return 0
except Exception as exc:
# Fall back to table display if Textual modal fails
print(f"Note: Could not launch interactive editor ({exc}). Showing configuration table:")
return _show_config_table(current_config)
print(
"Interactive TUI config editor has been discontinued. "
"Showing configuration table instead."
)
return _show_config_table(current_config)
key = args[0]
+3 -57
View File
@@ -4,14 +4,12 @@ import shutil
from typing import Any, Dict, List
from SYS.cmdlet_spec import Cmdlet
from SYS.config import resolve_cookies_path
from SYS import pipeline as ctx
from SYS.result_table import Table
from SYS.logger import set_debug, debug
from SYS.logger import set_debug
from cmdnat._status_shared import (
add_startup_check as _add_startup_check,
collect_plugin_startup_checks as _collect_plugin_startup_checks,
has_store_subtype as _has_store_subtype,
)
CMDLET = Cmdlet(
@@ -35,7 +33,6 @@ def _run(result: Any, args: List[str], config: Dict[str, Any]) -> int:
set_debug(debug_enabled)
except Exception:
pass
debug(f"Status check: debug_enabled={debug_enabled}")
_add_startup_check(startup_table, "ENABLED" if debug_enabled else "DISABLED", "DEBUGGING")
try:
@@ -45,51 +42,8 @@ def _run(result: Any, args: List[str], config: Dict[str, Any]) -> int:
MPV()
mpv_path = shutil.which("mpv")
_add_startup_check(startup_table, "ENABLED", "MPV", detail=mpv_path or "Available")
debug(f"MPV check OK: path={mpv_path or 'Available'}")
except Exception as exc:
_add_startup_check(startup_table, "DISABLED", "MPV", detail=str(exc))
debug(f"MPV check failed: {exc}")
# Store Registry
store_registry = None
try:
from Store import Store as StoreRegistry
store_registry = StoreRegistry(config=config, suppress_debug=True)
try:
backends = store_registry.list_backends()
except Exception:
backends = []
debug(f"StoreRegistry initialized. backends={backends}")
except Exception as exc:
debug(f"StoreRegistry initialization failed: {exc}")
store_registry = None
# Hydrus
if _has_store_subtype(config, "hydrusnetwork"):
hcfg = config.get("store", {}).get("hydrusnetwork", {})
for iname, icfg in hcfg.items():
if not isinstance(icfg, dict): continue
nkey = str(icfg.get("NAME") or iname)
uval = str(icfg.get("URL") or "").strip()
debug(f"Hydrus network check: name={nkey}, url={uval}")
ok = bool(store_registry and store_registry.is_available(nkey))
status = "ENABLED" if ok else "DISABLED"
files = None
detail = uval
if ok and store_registry:
try:
backend = store_registry[nkey]
files = getattr(backend, "total_count", None)
if files is None and hasattr(backend, "get_total_count"):
files = backend.get_total_count()
debug(f"Hydrus backend '{nkey}' available: files={files}")
except Exception as exc:
debug(f"Hydrus backend '{nkey}' check failed: {exc}")
else:
err = store_registry.get_backend_error(iname) if store_registry else None
debug(f"Hydrus backend '{nkey}' not available: {err}")
detail = f"{uval} - {err or 'Unavailable'}"
_add_startup_check(startup_table, status, nkey, store="hydrusnetwork", files=files, detail=detail)
for check in _collect_plugin_startup_checks(config):
_add_startup_check(
@@ -97,27 +51,19 @@ def _run(result: Any, args: List[str], config: Dict[str, Any]) -> int:
str(check.get("status") or "UNKNOWN"),
str(check.get("name") or "Plugin"),
provider=str(check.get("plugin") or ""),
instance=str(check.get("instance") or ""),
files=check.get("files"),
detail=str(check.get("detail") or ""),
)
# Cookies
try:
cf = resolve_cookies_path(config)
_add_startup_check(startup_table, "FOUND" if cf else "MISSING", "Cookies", detail=str(cf) if cf else "Not found")
debug(f"Cookies: resolved cookiefile={cf}")
except Exception as exc:
debug(f"Cookies check failed: {exc}")
except Exception as exc:
debug(f"Status check failed: {exc}")
_add_startup_check(startup_table, "ERROR", "STATUS", detail=str(exc))
if startup_table.rows:
# Mark as rendered to prevent CLI.py from auto-printing it to stdout
# (avoiding duplication in TUI logs, while keeping it in TUI Results)
setattr(startup_table, "_rendered_by_cmdlet", True)
ctx.set_current_stage_table(startup_table)
debug(f"Status check completed: {len(startup_table.rows)} checks recorded")
return 0