continuing refactor

This commit is contained in:
2026-05-03 21:20:05 -07:00
parent 77cab1bd27
commit 5534812426
50 changed files with 1004 additions and 428 deletions
+3 -3
View File
@@ -52,9 +52,9 @@ class MyPlugin(Provider):
Bundled walkthrough:
- Providers can now expose named config instances under `provider.<plugin>.<instance>` and cmdlets can target them with `-instance <name>`; plugin-mode `-store <name>` remains a compatibility alias while store-backed flows still use real backend stores.
- Providers can now expose named config instances under `provider.<plugin>.<instance>` and cmdlets can target them with `-instance <name>`.
- The repo now includes a real FTP example plugin in [plugins/ftp/__init__.py](plugins/ftp/__init__.py).
- The walkthrough is in [docs/ftp_plugin_tutorial.md](docs/ftp_plugin_tutorial.md) and shows `search-file -plugin ftp -instance <name>`, folder drill-in via `@N`, file download routing, `@N | add-file -store ...`, and `add-file -plugin ftp -instance <name>` uploads.
- The walkthrough is in [docs/ftp_plugin_tutorial.md](docs/ftp_plugin_tutorial.md) and shows `search-file -plugin ftp -instance <name>`, folder drill-in via `@N`, file download routing, `@N | add-file -instance ...`, and `add-file -plugin ftp -instance <name>` uploads.
- The repo also includes an SCP example plugin in [plugins/scp/__init__.py](plugins/scp/__init__.py).
- The walkthrough is in [docs/scp_plugin_tutorial.md](docs/scp_plugin_tutorial.md) and shows `search-file -plugin scp -instance <name>`, SSH-backed directory drill-in, file download routing, `@N | add-file -store ...`, and `add-file -plugin scp -instance <name>` uploads.
- The walkthrough is in [docs/scp_plugin_tutorial.md](docs/scp_plugin_tutorial.md) and shows `search-file -plugin scp -instance <name>`, SSH-backed directory drill-in, file download routing, `@N | add-file -instance ...`, and `add-file -plugin scp -instance <name>` uploads.
- The repo now also includes a built-in HydrusNetwork provider in [plugins/hydrusnetwork/__init__.py](plugins/hydrusnetwork/__init__.py). Its Hydrus client API now lives in the plugin-owned package [plugins/hydrusnetwork/api/__init__.py](plugins/hydrusnetwork/api/__init__.py), its registry-facing store adapter lives in [plugins/hydrusnetwork/store_proxy.py](plugins/hydrusnetwork/store_proxy.py), and its heavy internal operations live in [plugins/hydrusnetwork/store_backend.py](plugins/hydrusnetwork/store_backend.py). This `plugins/<name>/api/` package shape is the intended pattern for plugin-owned API helpers going forward. The provider now resolves configured Hydrus instances directly from plugin config instead of routing back through `Store.registry`; the proxy exists only so generic store callers can still target configured Hydrus stores. [API/HydrusNetwork.py](API/HydrusNetwork.py) and [Store/HydrusNetwork.py](Store/HydrusNetwork.py) are legacy compatibility shims only, and store discovery prefers the plugin-owned Hydrus hook over those shims.
+3 -3
View File
@@ -210,8 +210,8 @@ def _get_debrid_api_key(config: Dict[str, Any]) -> Optional[str]:
api_key=...
-> config["provider"]["alldebrid"]["api_key"]
- store-style debrid block:
config["store"]["debrid"]["all-debrid"]["api_key"]
- plugin-style debrid block:
config["plugin"]["debrid"]["all-debrid"]["api_key"]
Falls back to some legacy keys if present.
"""
@@ -227,7 +227,7 @@ def _get_debrid_api_key(config: Dict[str, Any]) -> Optional[str]:
if isinstance(entry, str) and entry.strip():
return entry.strip()
# 2) store.debrid block (canonical for debrid store configuration)
# 2) plugin debrid block
try:
from SYS.config import get_debrid_api_key
+1 -1
View File
@@ -8,7 +8,7 @@ Run this to see sample output:
python -m Provider.example_provider
Example usage (piped selector):
plugin-table -plugin example -sample | select -select 1 | add-file -store default
plugin-table -plugin example -sample | select -select 1 | add-file -instance default
"""
from __future__ import annotations
+2
View File
@@ -72,6 +72,8 @@ def _unique_path(path: Path) -> Path:
class FTP(Provider):
PLUGIN_NAME = "ftp"
URL = ("ftp://", "ftps://")
MULTI_INSTANCE = True
SUPPORTED_CMDLETS = frozenset({"add-file", "get-file", "search-file"})
@property
def label(self) -> str:
+2
View File
@@ -301,6 +301,8 @@ class Matrix(TableProviderMixin, Provider):
"""
EXPOSE_AS_FILE_PROVIDER = False
MULTI_INSTANCE = True
SUPPORTED_CMDLETS = frozenset({"add-file"})
@classmethod
def config_schema(cls) -> List[Dict[str, Any]]:
+1 -1
View File
@@ -472,7 +472,7 @@ class MPV:
pipeline = f"download-file -url {_q(url)} -query {_q(f'format:{fmt}')}"
if store:
pipeline += f" | add-file -store {_q(store)}"
pipeline += f" | add-file -instance {_q(store)}"
else:
pipeline += f" | add-file -path {_q(path or '')}"
+1 -1
View File
@@ -30,7 +30,7 @@ class Vimm(TableProviderMixin, Provider):
- This provider exposes file rows on a detail page. Each file row includes
a `path` which is an absolute download URL (or a form action + mediaId).
- To make `@N` expansion robust (so users can do `@1 | add-file -store <x>`)
- To make `@N` expansion robust (so users can do `@1 | add-file -instance <x>`)
we ensure three things:
1) The ResultTable produced by the `selector()` sets `source_command` to
"download-file" (the canonical cmdlet for downloading files).