dfslkjelf
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
import sys
|
||||
from typing import Any, Dict, Iterable, List, Optional
|
||||
|
||||
from ProviderCore.base import SearchProvider, SearchResult
|
||||
from ProviderCore.download import sanitize_filename
|
||||
from SYS.logger import log
|
||||
|
||||
|
||||
@@ -66,6 +68,89 @@ class AllDebrid(SearchProvider):
|
||||
# Consider "available" when configured; actual API connectivity can vary.
|
||||
return bool(_get_debrid_api_key(self.config or {}))
|
||||
|
||||
def download(self, result: SearchResult, output_dir: Path) -> Optional[Path]:
|
||||
"""Download an AllDebrid SearchResult into output_dir.
|
||||
|
||||
AllDebrid magnet file listings often provide links that require an API
|
||||
"unlock" step to produce a true direct-download URL. Without unlocking,
|
||||
callers may download a small HTML/redirect page instead of file bytes.
|
||||
|
||||
This is used by the download-file cmdlet when a provider item is piped.
|
||||
"""
|
||||
try:
|
||||
api_key = _get_debrid_api_key(self.config or {})
|
||||
if not api_key:
|
||||
return None
|
||||
|
||||
target = str(getattr(result, "path", "") or "").strip()
|
||||
if not target.startswith(("http://", "https://")):
|
||||
return None
|
||||
|
||||
try:
|
||||
from API.alldebrid import AllDebridClient
|
||||
|
||||
client = AllDebridClient(api_key)
|
||||
except Exception as exc:
|
||||
log(f"[alldebrid] Failed to init client: {exc}", file=sys.stderr)
|
||||
return None
|
||||
|
||||
# Quiet mode when download-file is mid-pipeline.
|
||||
quiet = bool(self.config.get("_quiet_background_output")) if isinstance(self.config, dict) else False
|
||||
|
||||
unlocked_url = target
|
||||
try:
|
||||
unlocked = client.unlock_link(target)
|
||||
if isinstance(unlocked, str) and unlocked.strip().startswith(("http://", "https://")):
|
||||
unlocked_url = unlocked.strip()
|
||||
except Exception as exc:
|
||||
# Fall back to the raw link, but warn.
|
||||
log(f"[alldebrid] Failed to unlock link: {exc}", file=sys.stderr)
|
||||
|
||||
# Prefer provider title as the output filename.
|
||||
suggested = sanitize_filename(str(getattr(result, "title", "") or "").strip())
|
||||
suggested_name = suggested if suggested else None
|
||||
|
||||
try:
|
||||
from SYS.download import _download_direct_file
|
||||
|
||||
dl_res = _download_direct_file(
|
||||
unlocked_url,
|
||||
Path(output_dir),
|
||||
quiet=quiet,
|
||||
suggested_filename=suggested_name,
|
||||
)
|
||||
downloaded_path = getattr(dl_res, "path", None)
|
||||
if downloaded_path is None:
|
||||
return None
|
||||
downloaded_path = Path(str(downloaded_path))
|
||||
|
||||
# Guard: if we got an HTML error/redirect page, treat as failure.
|
||||
try:
|
||||
if downloaded_path.exists():
|
||||
size = downloaded_path.stat().st_size
|
||||
if size > 0 and size <= 250_000 and downloaded_path.suffix.lower() not in (".html", ".htm"):
|
||||
head = downloaded_path.read_bytes()[:512]
|
||||
try:
|
||||
text = head.decode("utf-8", errors="ignore").lower()
|
||||
except Exception:
|
||||
text = ""
|
||||
if "<html" in text or "<!doctype html" in text:
|
||||
try:
|
||||
downloaded_path.unlink()
|
||||
except Exception:
|
||||
pass
|
||||
log("[alldebrid] Download returned HTML page (not file bytes). Try again or check AllDebrid link status.", file=sys.stderr)
|
||||
return None
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return downloaded_path if downloaded_path.exists() else None
|
||||
except Exception as exc:
|
||||
log(f"[alldebrid] Download failed: {exc}", file=sys.stderr)
|
||||
return None
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _flatten_files(items: Any) -> Iterable[Dict[str, Any]]:
|
||||
"""Flatten AllDebrid magnet file tree into file dicts.
|
||||
|
||||
Reference in New Issue
Block a user