jj
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled

This commit is contained in:
2025-12-28 03:51:48 -08:00
parent 8288ea8c66
commit 6acb52dfa0
3 changed files with 63 additions and 9 deletions

View File

@@ -152,15 +152,20 @@ class AllDebrid(Provider):
return None return None
@staticmethod @staticmethod
def _flatten_files(items: Any) -> Iterable[Dict[str, Any]]: def _flatten_files(items: Any, *, _prefix: Optional[List[str]] = None) -> Iterable[Dict[str, Any]]:
"""Flatten AllDebrid magnet file tree into file dicts. """Flatten AllDebrid magnet file tree into file dicts, preserving relative paths.
API commonly returns: API commonly returns:
- file: {n: name, s: size, l: link} - file: {n: name, s: size, l: link}
- folder: {n: name, e: [sub_items]} - folder: {n: name, e: [sub_items]}
This flattener attaches a best-effort relative path to each yielded file node
as `_relpath` using POSIX separators (e.g., "Season 1/E01.mkv").
Some call sites in this repo also expect {name, size, link}, so we accept both. Some call sites in this repo also expect {name, size, link}, so we accept both.
""" """
prefix = list(_prefix or [])
if not items: if not items:
return return
if isinstance(items, dict): if isinstance(items, dict):
@@ -174,13 +179,21 @@ class AllDebrid(Provider):
children = node.get('e') or node.get('children') children = node.get('e') or node.get('children')
if isinstance(children, list): if isinstance(children, list):
yield from AllDebrid._flatten_files(children) folder_name = node.get('n') or node.get('name')
next_prefix = prefix
if isinstance(folder_name, str) and folder_name.strip():
next_prefix = prefix + [folder_name.strip()]
yield from AllDebrid._flatten_files(children, _prefix=next_prefix)
continue continue
name = node.get('n') or node.get('name') name = node.get('n') or node.get('name')
link = node.get('l') or node.get('link') link = node.get('l') or node.get('link')
if isinstance(name, str) and name.strip() and isinstance(link, str) and link.strip(): if isinstance(name, str) and name.strip() and isinstance(link, str) and link.strip():
yield node rel_parts = prefix + [name.strip()]
relpath = "/".join([p for p in rel_parts if p])
enriched = dict(node)
enriched["_relpath"] = relpath
yield enriched
def search( def search(
self, self,
@@ -269,6 +282,7 @@ class AllDebrid(Provider):
for file_node in self._flatten_files(file_tree): for file_node in self._flatten_files(file_tree):
file_name = str(file_node.get('n') or file_node.get('name') or '').strip() file_name = str(file_node.get('n') or file_node.get('name') or '').strip()
file_url = str(file_node.get('l') or file_node.get('link') or '').strip() file_url = str(file_node.get('l') or file_node.get('link') or '').strip()
relpath = str(file_node.get('_relpath') or file_name or '').strip()
file_size = file_node.get('s') or file_node.get('size') file_size = file_node.get('s') or file_node.get('size')
if not file_name or not file_url: if not file_name or not file_url:
continue continue
@@ -300,7 +314,13 @@ class AllDebrid(Provider):
("Folder", magnet_name), ("Folder", magnet_name),
("ID", str(magnet_id)), ("ID", str(magnet_id)),
], ],
full_metadata={"magnet": magnet_status, "magnet_id": magnet_id, "file": file_node}, full_metadata={
"magnet": magnet_status,
"magnet_id": magnet_id,
"magnet_name": magnet_name,
"relpath": relpath,
"file": file_node,
},
) )
) )
if len(results) >= max(1, limit): if len(results) >= max(1, limit):

View File

@@ -815,7 +815,43 @@ class Download_File(Cmdlet):
full_metadata=full_metadata if isinstance(full_metadata, dict) else {}, full_metadata=full_metadata if isinstance(full_metadata, dict) else {},
) )
debug(f"[download-file] Downloading provider item via {table}: {sr.title}") debug(f"[download-file] Downloading provider item via {table}: {sr.title}")
downloaded_path = provider.download(sr, final_output_dir)
# Preserve provider structure when possible (AllDebrid folders -> subfolders).
output_dir = final_output_dir
try:
if str(table).strip().lower() == "alldebrid":
from ProviderCore.download import sanitize_filename as _sf
md = full_metadata if isinstance(full_metadata, dict) else {}
magnet_name = None
if isinstance(md, dict):
magnet_name = md.get("magnet_name") or md.get("folder")
if not magnet_name:
magnet_name = str(get_field(item, "detail") or "").strip() or None
if magnet_name:
output_dir = Path(output_dir) / _sf(str(magnet_name))
relpath = None
if isinstance(md, dict):
relpath = md.get("relpath")
if not relpath and isinstance(md.get("file"), dict):
relpath = md["file"].get("_relpath")
if relpath:
parts = [p for p in str(relpath).replace("\\", "/").split("/") if p and p not in {".", ".."}]
# relpath includes the filename; only join parent directories.
for part in parts[:-1]:
output_dir = Path(output_dir) / _sf(part)
try:
Path(output_dir).mkdir(parents=True, exist_ok=True)
except Exception:
output_dir = final_output_dir
except Exception:
output_dir = final_output_dir
downloaded_path = provider.download(sr, output_dir)
provider_sr = sr provider_sr = sr
# OpenLibrary: if provider download failed, do NOT try to download the OpenLibrary page HTML. # OpenLibrary: if provider download failed, do NOT try to download the OpenLibrary page HTML.

View File

@@ -16,8 +16,6 @@ scripts/setup.py
""" """
Unified project setup helper (Python-only).
#!/usr/bin/env python3
""" scripts/setup.py """ scripts/setup.py
Unified project setup helper (Python-only). Unified project setup helper (Python-only).