update download plugin

This commit is contained in:
2026-07-14 17:56:54 -07:00
parent 5e71a3cf54
commit a156700e6e
6 changed files with 125 additions and 81 deletions
+59 -16
View File
@@ -429,9 +429,11 @@ def prepare_magnet(
def _flatten_files_with_relpath(items: Any) -> Iterable[Dict[str, Any]]:
for node in AllDebrid._flatten_files(items):
enriched = dict(node)
enriched.setdefault("name", node.get("n") or node.get("name"))
enriched.setdefault("link", node.get("l") or node.get("link"))
rel = node.get("_relpath") or node.get("relpath")
if not rel:
name = node.get("n") or node.get("name")
name = enriched.get("name")
rel = str(name or "").strip()
enriched["relpath"] = rel
yield enriched
@@ -447,7 +449,7 @@ def download_magnet(
path_from_result: Callable[[Any], Path],
on_emit: Callable[[Path, str, str, Dict[str, Any]], None],
) -> tuple[int, Optional[int]]:
client, magnet_id, _magnet_info = prepare_magnet(magnet_spec, config)
client, magnet_id, magnet_info = prepare_magnet(magnet_spec, config)
if client is None or magnet_id is None:
return 0, None
@@ -486,6 +488,11 @@ def download_magnet(
log(f"AllDebrid magnet {magnet_id} produced no files", file=sys.stderr)
return 0, magnet_id
magnet_folder_name = _resolve_alldebrid_folder_name(
magnet_info,
fallback_metadata=magnet_files,
magnet_id=magnet_id,
)
downloaded = 0
for node in _flatten_files_with_relpath(file_nodes):
file_url = str(node.get("link") or "").strip()
@@ -494,15 +501,12 @@ def download_magnet(
if not file_url or not relpath:
continue
target_path = final_output_dir
rel_path_obj = Path(relpath)
output_dir = target_path
if rel_path_obj.parent:
output_dir = target_path / rel_path_obj.parent
try:
output_dir.mkdir(parents=True, exist_ok=True)
except Exception:
output_dir = target_path
output_dir = adjust_output_dir_for_alldebrid(
final_output_dir,
{"folder": magnet_folder_name, "relpath": relpath},
magnet_files,
)
try:
result_obj = download_direct_file(
@@ -519,6 +523,7 @@ def download_magnet(
downloaded_path = path_from_result(result_obj)
metadata = {
"magnet_id": magnet_id,
"folder": magnet_folder_name,
"relpath": relpath,
"name": file_name,
}
@@ -627,6 +632,29 @@ def adjust_output_dir_for_alldebrid(
return output_dir
def _resolve_alldebrid_folder_name(
metadata: Any,
*,
fallback_metadata: Any = None,
magnet_id: Optional[int] = None,
) -> str:
sources = [
source
for source in (metadata, fallback_metadata)
if isinstance(source, dict)
]
for key in ("folder", "magnet_name", "filename", "name"):
for source in sources:
value = str(source.get(key) or "").strip()
if value:
return value
for source in sources:
value = str(source.get("hash") or "").strip()
if value:
return value
return f"magnet-{magnet_id}" if magnet_id is not None else "download"
class AllDebrid(TablePluginMixin, Provider):
"""AllDebrid account provider with magnet folder/file browsing and downloads.
@@ -1278,13 +1306,27 @@ class AllDebrid(TablePluginMixin, Provider):
log(f"AllDebrid magnet {magnet_id} has no downloadable files", file=sys.stderr)
return 0
magnet_metadata: Dict[str, Any] = {}
try:
for magnet in client.magnet_list() or []:
if not isinstance(magnet, dict):
continue
try:
listed_id = int(magnet.get("id") or 0)
except (TypeError, ValueError):
continue
if listed_id == magnet_id:
magnet_metadata = magnet
break
except Exception:
magnet_metadata = {}
magnet_path_metadata: Dict[str, Any] = {}
magnet_folder_name = str(
magnet_files.get("filename")
or magnet_files.get("name")
or magnet_files.get("hash")
or f"magnet-{magnet_id}"
).strip()
magnet_folder_name = _resolve_alldebrid_folder_name(
magnet_metadata,
fallback_metadata=magnet_files,
magnet_id=magnet_id,
)
if magnet_folder_name:
magnet_path_metadata["folder"] = magnet_folder_name
@@ -1340,6 +1382,7 @@ class AllDebrid(TablePluginMixin, Provider):
downloaded_path = path_from_result(result_obj)
metadata = {
"magnet_id": magnet_id,
"folder": magnet_folder_name,
"relpath": relpath,
"name": file_name,
}
+53 -2
View File
@@ -165,6 +165,43 @@ class Local(Provider):
def validate(self) -> bool:
return True
@staticmethod
def _folder_name_from_pipe(pipe_obj: Any) -> str:
metadata = getattr(pipe_obj, "metadata", None)
extra = getattr(pipe_obj, "extra", None)
if not isinstance(metadata, dict):
metadata = {}
if not isinstance(extra, dict):
extra = {}
plugin_name = str(
getattr(pipe_obj, "plugin", None)
or metadata.get("plugin")
or extra.get("plugin")
or ""
).strip().lower()
has_alldebrid_metadata = any(
isinstance(source, dict)
and (source.get("magnet_id") is not None or source.get("plugin") == "alldebrid")
for source in (metadata, extra)
)
if plugin_name != "alldebrid" and not has_alldebrid_metadata:
return ""
for source in (metadata, extra):
for key in ("folder_name", "folder", "magnet_name"):
value = str(source.get(key) or "").strip()
if value:
return value
magnet = source.get("magnet")
if isinstance(magnet, dict):
for key in ("filename", "name", "hash"):
value = str(magnet.get(key) or "").strip()
if value:
return value
return ""
def upload(self, file_path: str, **kwargs: Any) -> Dict[str, Any]:
source_path = Path(str(file_path or "")).expanduser()
if not source_path.exists() or not source_path.is_file():
@@ -210,6 +247,19 @@ class Local(Provider):
elif not destination_root.is_dir():
raise NotADirectoryError(f"Destination is not a directory: {destination_root}")
direct_export_download = bool(kwargs.get("direct_export_download", False))
folder_name = str(kwargs.get("folder_name") or "").strip()
if not folder_name and not direct_export_download:
folder_name = self._folder_name_from_pipe(kwargs.get("pipe_obj"))
export_root = destination_root
if folder_name and not direct_export_download:
export_root = destination_root / sanitize_filename(folder_name)
if create_dirs:
export_root.mkdir(parents=True, exist_ok=True)
elif not export_root.is_dir():
raise FileNotFoundError(f"Destination directory does not exist: {export_root}")
title = str(kwargs.get("title") or "").strip()
if not title:
title = source_path.stem.replace("_", " ").strip()
@@ -221,8 +271,7 @@ class Local(Provider):
else:
target_name = base_name + file_ext
direct_export_download = bool(kwargs.get("direct_export_download", False))
target_path = source_path if direct_export_download else destination_root / target_name
target_path = source_path if direct_export_download else export_root / target_name
if not direct_export_download:
if target_path.exists():
@@ -271,6 +320,8 @@ class Local(Provider):
"url": urls,
"export_path": str(destination_root),
}
if export_root != destination_root:
extra_updates["export_folder"] = str(export_root)
if resolved_name:
extra_updates["instance"] = resolved_name
if relationships: