This commit is contained in:
2026-01-03 03:37:48 -08:00
parent 6e9a0c28ff
commit 73f3005393
23 changed files with 1791 additions and 442 deletions

View File

@@ -55,10 +55,40 @@ class Provider(ABC):
URL: Sequence[str] = ()
# Optional provider-driven defaults for what to do when a user selects @N from a
# provider table. The CLI uses this to auto-insert stages (e.g. download-file)
# without hardcoding table names.
#
# Example:
# TABLE_AUTO_STAGES = {"youtube": ["download-file"]}
# TABLE_AUTO_PREFIXES = {"hifi": ["download-file"]} # matches hifi.*
TABLE_AUTO_STAGES: Dict[str, Sequence[str]] = {}
TABLE_AUTO_PREFIXES: Dict[str, Sequence[str]] = {}
AUTO_STAGE_USE_SELECTION_ARGS: bool = False
# Optional provider-declared configuration keys.
# Used for dynamically generating config panels (e.g., missing credentials).
REQUIRED_CONFIG_KEYS: Sequence[str] = ()
def __init__(self, config: Optional[Dict[str, Any]] = None):
self.config = config or {}
self.name = self.__class__.__name__.lower()
@classmethod
def required_config_keys(cls) -> List[str]:
keys = getattr(cls, "REQUIRED_CONFIG_KEYS", None)
if not keys:
return []
out: List[str] = []
try:
for k in list(keys):
s = str(k or "").strip()
if s:
out.append(s)
except Exception:
return []
return out
# Standard lifecycle/auth hook.
def login(self, **_kwargs: Any) -> bool:
return True
@@ -109,6 +139,56 @@ class Provider(ABC):
_ = stage_is_last
return False
@classmethod
def selection_auto_stage(
cls,
table_type: str,
stage_args: Optional[Sequence[str]] = None,
) -> Optional[List[str]]:
"""Return a stage to auto-run after selecting from `table_type`.
This is used by the CLI to auto-insert default stages for provider tables
(e.g. select a YouTube row -> auto-run download-file).
Providers can implement this via class attributes (TABLE_AUTO_STAGES /
TABLE_AUTO_PREFIXES) or by overriding this method.
"""
t = str(table_type or "").strip().lower()
if not t:
return None
stage: Optional[Sequence[str]] = None
try:
stage = cls.TABLE_AUTO_STAGES.get(t)
except Exception:
stage = None
if stage is None:
try:
for prefix, cmd in (cls.TABLE_AUTO_PREFIXES or {}).items():
p = str(prefix or "").strip().lower()
if not p:
continue
if t == p or t.startswith(p + ".") or t.startswith(p):
stage = cmd
break
except Exception:
stage = None
if not stage:
return None
out = [str(x) for x in stage if str(x or "").strip()]
if not out:
return None
if cls.AUTO_STAGE_USE_SELECTION_ARGS and stage_args:
try:
out.extend([str(x) for x in stage_args if str(x or "").strip()])
except Exception:
pass
return out
@classmethod
def url_patterns(cls) -> Tuple[str, ...]:
"""Return normalized URL patterns that this provider handles."""