v
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled
This commit is contained in:
@@ -38,7 +38,7 @@ class Download_File(Cmdlet):
|
||||
super().__init__(
|
||||
name="download-file",
|
||||
summary="Download files via HTTP or provider handlers",
|
||||
usage="download-file <url> [-path DIR] [options] OR @N | download-file [-path DIR] [options]",
|
||||
usage="download-file <url> [-path DIR] [options] OR @N | download-file [-path DIR|DIR] [options]",
|
||||
alias=["dl-file", "download-http"],
|
||||
arg=[
|
||||
SharedArgs.URL,
|
||||
@@ -690,7 +690,12 @@ class Download_File(Cmdlet):
|
||||
downloaded_count += 1
|
||||
continue
|
||||
|
||||
result_obj = _download_direct_file(str(url), final_output_dir, quiet=quiet_mode)
|
||||
result_obj = _download_direct_file(
|
||||
str(url),
|
||||
final_output_dir,
|
||||
quiet=quiet_mode,
|
||||
pipeline_progress=progress,
|
||||
)
|
||||
downloaded_path = self._path_from_download_result(result_obj)
|
||||
|
||||
self._emit_local_file(
|
||||
@@ -829,25 +834,46 @@ class Download_File(Cmdlet):
|
||||
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))
|
||||
magnet_dir_name = _sf(str(magnet_name)) if magnet_name else ""
|
||||
|
||||
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 user already chose -path that ends with the magnet folder name,
|
||||
# don't create a duplicate nested folder.
|
||||
try:
|
||||
base_tail = str(Path(output_dir).name or "")
|
||||
except Exception:
|
||||
base_tail = ""
|
||||
base_tail_norm = _sf(base_tail).lower() if base_tail.strip() else ""
|
||||
magnet_dir_norm = magnet_dir_name.lower() if magnet_dir_name else ""
|
||||
|
||||
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)
|
||||
if magnet_dir_name and (not base_tail_norm or base_tail_norm != magnet_dir_norm):
|
||||
output_dir = Path(output_dir) / magnet_dir_name
|
||||
|
||||
try:
|
||||
Path(output_dir).mkdir(parents=True, exist_ok=True)
|
||||
except Exception:
|
||||
output_dir = final_output_dir
|
||||
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 {".", ".."}]
|
||||
|
||||
# If the provider relpath already includes the magnet folder name as a
|
||||
# root directory (common), strip it to prevent double nesting.
|
||||
if magnet_dir_name and parts:
|
||||
try:
|
||||
if _sf(parts[0]).lower() == magnet_dir_norm:
|
||||
parts = parts[1:]
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 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
|
||||
|
||||
@@ -927,6 +953,7 @@ class Download_File(Cmdlet):
|
||||
final_output_dir,
|
||||
quiet=quiet_mode,
|
||||
suggested_filename=suggested_name,
|
||||
pipeline_progress=progress,
|
||||
)
|
||||
downloaded_path = self._path_from_download_result(result_obj)
|
||||
|
||||
@@ -980,15 +1007,53 @@ class Download_File(Cmdlet):
|
||||
def _run_impl(self, result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
"""Main download implementation for direct HTTP files."""
|
||||
progress = PipelineProgress(pipeline_context)
|
||||
prev_progress = None
|
||||
had_progress_key = False
|
||||
try:
|
||||
debug("Starting download-file")
|
||||
|
||||
# Allow providers to tap into the active PipelineProgress (optional).
|
||||
try:
|
||||
if isinstance(config, dict):
|
||||
had_progress_key = "_pipeline_progress" in config
|
||||
prev_progress = config.get("_pipeline_progress")
|
||||
config["_pipeline_progress"] = progress
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Parse arguments
|
||||
parsed = parse_cmdlet_args(args, self)
|
||||
|
||||
raw_url = self._normalize_urls(parsed)
|
||||
piped_items = self._collect_piped_items_if_no_urls(result, raw_url)
|
||||
|
||||
had_piped_input = False
|
||||
try:
|
||||
if isinstance(result, list):
|
||||
had_piped_input = bool(result)
|
||||
else:
|
||||
had_piped_input = bool(result)
|
||||
except Exception:
|
||||
had_piped_input = False
|
||||
|
||||
# UX: In piped mode, allow a single positional arg to be the destination directory.
|
||||
# Example: @1-4 | download-file "C:\\Users\\Me\\Downloads\\yoyo"
|
||||
if had_piped_input and raw_url and len(raw_url) == 1 and (not parsed.get("path")) and (not parsed.get("output")):
|
||||
candidate = str(raw_url[0] or "").strip()
|
||||
low = candidate.lower()
|
||||
looks_like_url = low.startswith(("http://", "https://", "ftp://"))
|
||||
looks_like_provider = low.startswith(("magnet:", "alldebrid:", "hydrus:", "ia:", "internetarchive:"))
|
||||
looks_like_windows_path = (
|
||||
(len(candidate) >= 2 and candidate[1] == ":")
|
||||
or candidate.startswith("\\\\")
|
||||
or candidate.startswith("\\")
|
||||
or candidate.endswith(("\\", "/"))
|
||||
)
|
||||
if (not looks_like_url) and (not looks_like_provider) and looks_like_windows_path:
|
||||
parsed["path"] = candidate
|
||||
raw_url = []
|
||||
piped_items = self._collect_piped_items_if_no_urls(result, raw_url)
|
||||
|
||||
if not raw_url and not piped_items:
|
||||
log("No url or piped items to download", file=sys.stderr)
|
||||
return 1
|
||||
@@ -1055,6 +1120,14 @@ class Download_File(Cmdlet):
|
||||
return 1
|
||||
|
||||
finally:
|
||||
try:
|
||||
if isinstance(config, dict):
|
||||
if had_progress_key:
|
||||
config["_pipeline_progress"] = prev_progress
|
||||
else:
|
||||
config.pop("_pipeline_progress", None)
|
||||
except Exception:
|
||||
pass
|
||||
progress.close_local_ui(force_complete=True)
|
||||
|
||||
def _resolve_output_dir(self, parsed: Dict[str, Any], config: Dict[str, Any]) -> Optional[Path]:
|
||||
|
||||
Reference in New Issue
Block a user