updated plugin refactor and added FTP and SCP plugins , also hydrusnetwork plugin migration

This commit is contained in:
2026-04-27 21:17:53 -07:00
parent bfd5c20dc3
commit 8685fbb723
24 changed files with 3650 additions and 405 deletions
+57 -10
View File
@@ -23,24 +23,56 @@ from SYS.models import DownloadError, PipeObject
_HOSTS_CACHE_TTL_SECONDS = 24 * 60 * 60
def _repo_root() -> Path:
def _plugin_dir() -> Path:
try:
return Path(__file__).resolve().parents[1]
return Path(__file__).resolve().parent
except Exception:
return Path(".")
def _legacy_hosts_cache_paths() -> Tuple[Path, ...]:
try:
repo_root = Path(__file__).resolve().parents[2]
plugins_root = Path(__file__).resolve().parents[1]
except Exception:
return tuple()
return (
plugins_root / "API" / "data" / "alldebrid.json",
repo_root / "API" / "data" / "alldebrid.json",
)
def _hosts_cache_path() -> Path:
# Keep this local to the repo so it works in portable installs.
# The registry's URL routing can read this file without instantiating providers.
# Keep this local to the plugin so plugin-specific cache/state stays bundled
# with the plugin itself in portable installs.
#
# This file is expected to be the JSON payload shape from AllDebrid:
# {"status":"success","data":{"hosts":[...],"streams":[...],"redirectors":[...]}}
return _repo_root() / "API" / "data" / "alldebrid.json"
return _plugin_dir() / "alldebrid.json"
def _resolve_hosts_cache_path() -> Path:
path = _hosts_cache_path()
try:
if path.exists() and path.is_file():
return path
except Exception:
return path
for legacy in _legacy_hosts_cache_paths():
try:
if not legacy.exists() or not legacy.is_file():
continue
path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(legacy, path)
return path
except Exception:
continue
return path
def _load_cached_domains(category: str) -> List[str]:
"""Load cached domain list from API/data/alldebrid.json.
"""Load cached domain list from the plugin-local alldebrid.json cache.
category: "hosts" | "streams" | "redirectors"
"""
@@ -49,7 +81,7 @@ def _load_cached_domains(category: str) -> List[str]:
if wanted not in {"hosts", "streams", "redirectors"}:
return []
path = _hosts_cache_path()
path = _resolve_hosts_cache_path()
try:
if not path.exists() or not path.is_file():
return []
@@ -68,12 +100,27 @@ def _load_cached_domains(category: str) -> List[str]:
return []
raw_list = data.get(wanted)
if not isinstance(raw_list, list):
if not isinstance(raw_list, (list, dict)):
return []
out: List[str] = []
seen: set[str] = set()
for d in raw_list:
domain_candidates: List[Any] = []
if isinstance(raw_list, list):
domain_candidates.extend(raw_list)
else:
for entry in raw_list.values():
if isinstance(entry, dict):
nested_domains = entry.get("domains")
if isinstance(nested_domains, list):
domain_candidates.extend(nested_domains)
elif isinstance(nested_domains, str):
domain_candidates.append(nested_domains)
elif isinstance(entry, str):
domain_candidates.append(entry)
for d in domain_candidates:
try:
dom = str(d or "").strip().lower()
except Exception:
@@ -115,7 +162,7 @@ def _save_cached_hosts_payload(payload: Dict[str, Any]) -> None:
def _cache_is_fresh() -> bool:
path = _hosts_cache_path()
path = _resolve_hosts_cache_path()
try:
if not path.exists() or not path.is_file():
return False
File diff suppressed because one or more lines are too long