Add YAPF style + ignore, and format tracked Python files
This commit is contained in:
@@ -38,8 +38,10 @@ 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|DIR] [options]",
|
||||
alias=["dl-file", "download-http"],
|
||||
usage=
|
||||
"download-file <url> [-path DIR] [options] OR @N | download-file [-path DIR|DIR] [options]",
|
||||
alias=["dl-file",
|
||||
"download-http"],
|
||||
arg=[
|
||||
SharedArgs.URL,
|
||||
SharedArgs.PATH,
|
||||
@@ -86,7 +88,8 @@ class Download_File(Cmdlet):
|
||||
return expanded_urls
|
||||
|
||||
@staticmethod
|
||||
def _collect_piped_items_if_no_urls(result: Any, raw_urls: Sequence[str]) -> List[Any]:
|
||||
def _collect_piped_items_if_no_urls(result: Any,
|
||||
raw_urls: Sequence[str]) -> List[Any]:
|
||||
if raw_urls:
|
||||
return []
|
||||
if isinstance(result, list):
|
||||
@@ -104,13 +107,18 @@ class Download_File(Cmdlet):
|
||||
|
||||
@staticmethod
|
||||
def _build_preview(
|
||||
raw_urls: Sequence[str], piped_items: Sequence[Any], total_items: int
|
||||
raw_urls: Sequence[str],
|
||||
piped_items: Sequence[Any],
|
||||
total_items: int
|
||||
) -> List[Any]:
|
||||
try:
|
||||
preview: List[Any] = []
|
||||
preview.extend(list(raw_urls or [])[: max(0, total_items)])
|
||||
preview.extend(list(raw_urls or [])[:max(0, total_items)])
|
||||
if len(preview) < total_items:
|
||||
preview.extend(list(piped_items or [])[: max(0, total_items - len(preview))])
|
||||
preview.extend(
|
||||
list(piped_items or [])[:max(0,
|
||||
total_items - len(preview))]
|
||||
)
|
||||
return preview
|
||||
except Exception:
|
||||
return []
|
||||
@@ -145,8 +153,10 @@ class Download_File(Cmdlet):
|
||||
*,
|
||||
raw_urls: Sequence[str],
|
||||
piped_items: Sequence[Any],
|
||||
parsed: Dict[str, Any],
|
||||
config: Dict[str, Any],
|
||||
parsed: Dict[str,
|
||||
Any],
|
||||
config: Dict[str,
|
||||
Any],
|
||||
quiet_mode: bool,
|
||||
) -> Optional[int]:
|
||||
"""If the input is an IA item page, show a selectable formats table.
|
||||
@@ -168,7 +178,9 @@ class Download_File(Cmdlet):
|
||||
target = ""
|
||||
if item is not None:
|
||||
try:
|
||||
target = str(get_field(item, "path") or get_field(item, "url") or "").strip()
|
||||
target = str(get_field(item,
|
||||
"path") or get_field(item,
|
||||
"url") or "").strip()
|
||||
except Exception:
|
||||
target = ""
|
||||
if not target and raw_urls:
|
||||
@@ -206,22 +218,28 @@ class Download_File(Cmdlet):
|
||||
try:
|
||||
files = ia.list_download_files(identifier)
|
||||
except Exception as exc:
|
||||
log(f"download-file: Internet Archive lookup failed: {exc}", file=sys.stderr)
|
||||
log(
|
||||
f"download-file: Internet Archive lookup failed: {exc}",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 1
|
||||
|
||||
if not files:
|
||||
log("download-file: Internet Archive item has no downloadable files", file=sys.stderr)
|
||||
log(
|
||||
"download-file: Internet Archive item has no downloadable files",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 1
|
||||
|
||||
title = ""
|
||||
try:
|
||||
title = str(get_field(item, "title") or "").strip() if item is not None else ""
|
||||
title = str(get_field(item,
|
||||
"title") or "").strip() if item is not None else ""
|
||||
except Exception:
|
||||
title = ""
|
||||
table_title = (
|
||||
f"Internet Archive: {title}".strip().rstrip(":")
|
||||
if title
|
||||
else f"Internet Archive: {identifier}"
|
||||
if title else f"Internet Archive: {identifier}"
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -256,31 +274,43 @@ class Download_File(Cmdlet):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
row_item: Dict[str, Any] = {
|
||||
"table": "internetarchive",
|
||||
"title": fmt or name,
|
||||
"path": direct_url,
|
||||
"url": direct_url,
|
||||
"columns": [
|
||||
("Format", fmt),
|
||||
("Name", name),
|
||||
("Size", size_val),
|
||||
("Source", src),
|
||||
],
|
||||
"_selection_args": [direct_url],
|
||||
"full_metadata": {
|
||||
"identifier": identifier,
|
||||
"name": name,
|
||||
"format": fmt,
|
||||
"source": src,
|
||||
"size": f.get("size"),
|
||||
},
|
||||
}
|
||||
row_item: Dict[str,
|
||||
Any] = {
|
||||
"table":
|
||||
"internetarchive",
|
||||
"title":
|
||||
fmt or name,
|
||||
"path":
|
||||
direct_url,
|
||||
"url":
|
||||
direct_url,
|
||||
"columns": [
|
||||
("Format",
|
||||
fmt),
|
||||
("Name",
|
||||
name),
|
||||
("Size",
|
||||
size_val),
|
||||
("Source",
|
||||
src),
|
||||
],
|
||||
"_selection_args": [direct_url],
|
||||
"full_metadata": {
|
||||
"identifier": identifier,
|
||||
"name": name,
|
||||
"format": fmt,
|
||||
"source": src,
|
||||
"size": f.get("size"),
|
||||
},
|
||||
}
|
||||
rows.append(row_item)
|
||||
table.add_result(row_item)
|
||||
|
||||
if not rows:
|
||||
log("download-file: no downloadable files found for this item", file=sys.stderr)
|
||||
log(
|
||||
"download-file: no downloadable files found for this item",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 1
|
||||
|
||||
try:
|
||||
@@ -289,7 +319,10 @@ class Download_File(Cmdlet):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
log("Internet Archive item detected: select a file with @N to download", file=sys.stderr)
|
||||
log(
|
||||
"Internet Archive item detected: select a file with @N to download",
|
||||
file=sys.stderr
|
||||
)
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
@@ -334,14 +367,15 @@ class Download_File(Cmdlet):
|
||||
title_hint: Optional[str],
|
||||
tags_hint: Optional[List[str]],
|
||||
media_kind_hint: Optional[str],
|
||||
full_metadata: Optional[Dict[str, Any]],
|
||||
full_metadata: Optional[Dict[str,
|
||||
Any]],
|
||||
progress: PipelineProgress,
|
||||
config: Dict[str, Any],
|
||||
config: Dict[str,
|
||||
Any],
|
||||
provider_hint: Optional[str] = None,
|
||||
) -> None:
|
||||
title_val = (
|
||||
title_hint or downloaded_path.stem or "Unknown"
|
||||
).strip() or downloaded_path.stem
|
||||
title_val = (title_hint or downloaded_path.stem
|
||||
or "Unknown").strip() or downloaded_path.stem
|
||||
hash_value = self._compute_file_hash(downloaded_path)
|
||||
tag: List[str] = []
|
||||
if tags_hint:
|
||||
@@ -349,16 +383,17 @@ class Download_File(Cmdlet):
|
||||
if not any(str(t).lower().startswith("title:") for t in tag):
|
||||
tag.insert(0, f"title:{title_val}")
|
||||
|
||||
payload: Dict[str, Any] = {
|
||||
"path": str(downloaded_path),
|
||||
"hash": hash_value,
|
||||
"title": title_val,
|
||||
"action": "cmdlet:download-file",
|
||||
"download_mode": "file",
|
||||
"store": "local",
|
||||
"media_kind": media_kind_hint or "file",
|
||||
"tag": tag,
|
||||
}
|
||||
payload: Dict[str,
|
||||
Any] = {
|
||||
"path": str(downloaded_path),
|
||||
"hash": hash_value,
|
||||
"title": title_val,
|
||||
"action": "cmdlet:download-file",
|
||||
"download_mode": "file",
|
||||
"store": "local",
|
||||
"media_kind": media_kind_hint or "file",
|
||||
"tag": tag,
|
||||
}
|
||||
if provider_hint:
|
||||
payload["provider"] = str(provider_hint)
|
||||
if full_metadata:
|
||||
@@ -384,11 +419,14 @@ class Download_File(Cmdlet):
|
||||
*,
|
||||
raw_urls: Sequence[str],
|
||||
final_output_dir: Path,
|
||||
config: Dict[str, Any],
|
||||
config: Dict[str,
|
||||
Any],
|
||||
quiet_mode: bool,
|
||||
registry: Dict[str, Any],
|
||||
registry: Dict[str,
|
||||
Any],
|
||||
progress: PipelineProgress,
|
||||
) -> tuple[int, Optional[int]]:
|
||||
) -> tuple[int,
|
||||
Optional[int]]:
|
||||
downloaded_count = 0
|
||||
|
||||
SearchResult = registry.get("SearchResult")
|
||||
@@ -406,7 +444,8 @@ class Download_File(Cmdlet):
|
||||
except Exception:
|
||||
host = ""
|
||||
|
||||
is_telegram = host in {"t.me", "telegram.me"} or host.endswith(".t.me")
|
||||
is_telegram = host in {"t.me",
|
||||
"telegram.me"} or host.endswith(".t.me")
|
||||
if is_telegram and SearchResult:
|
||||
try:
|
||||
from ProviderCore.registry import get_provider as _get_provider
|
||||
@@ -423,7 +462,10 @@ class Download_File(Cmdlet):
|
||||
)
|
||||
|
||||
sr = SearchResult(
|
||||
table="telegram", title=str(url), path=str(url), full_metadata={}
|
||||
table="telegram",
|
||||
title=str(url),
|
||||
path=str(url),
|
||||
full_metadata={}
|
||||
)
|
||||
downloaded_path = None
|
||||
telegram_info: Optional[Dict[str, Any]] = None
|
||||
@@ -444,14 +486,21 @@ class Download_File(Cmdlet):
|
||||
try:
|
||||
chat_info_raw = telegram_info.get("chat")
|
||||
msg_info_raw = telegram_info.get("message")
|
||||
chat_info: Dict[str, Any] = (
|
||||
chat_info_raw if isinstance(chat_info_raw, dict) else {}
|
||||
)
|
||||
msg_info: Dict[str, Any] = (
|
||||
msg_info_raw if isinstance(msg_info_raw, dict) else {}
|
||||
)
|
||||
chat_info: Dict[str,
|
||||
Any] = (
|
||||
chat_info_raw
|
||||
if isinstance(chat_info_raw,
|
||||
dict) else {}
|
||||
)
|
||||
msg_info: Dict[str,
|
||||
Any] = (
|
||||
msg_info_raw
|
||||
if isinstance(msg_info_raw,
|
||||
dict) else {}
|
||||
)
|
||||
channel = str(
|
||||
chat_info.get("title") or chat_info.get("username") or ""
|
||||
chat_info.get("title") or chat_info.get("username")
|
||||
or ""
|
||||
).strip()
|
||||
post = msg_info.get("id")
|
||||
except Exception:
|
||||
@@ -501,16 +550,12 @@ class Download_File(Cmdlet):
|
||||
p = urlparse(str(url))
|
||||
h = (p.hostname or "").strip().lower()
|
||||
path = (p.path or "").strip().lower()
|
||||
if "libgen" in h and any(
|
||||
x in path
|
||||
for x in (
|
||||
if "libgen" in h and any(x in path for x in (
|
||||
"/edition.php",
|
||||
"/file.php",
|
||||
"/ads.php",
|
||||
"/get.php",
|
||||
"/series.php",
|
||||
)
|
||||
):
|
||||
"/series.php", )):
|
||||
provider_name = "libgen"
|
||||
except Exception:
|
||||
pass
|
||||
@@ -546,7 +591,10 @@ class Download_File(Cmdlet):
|
||||
progress.begin_steps(5)
|
||||
|
||||
def _progress(
|
||||
kind: str, done: int, total: Optional[int], label: str
|
||||
kind: str,
|
||||
done: int,
|
||||
total: Optional[int],
|
||||
label: str
|
||||
) -> None:
|
||||
# kind:
|
||||
# - "step": advance step text
|
||||
@@ -561,12 +609,21 @@ class Download_File(Cmdlet):
|
||||
d = int(done) if isinstance(done, int) else 0
|
||||
if t > 0:
|
||||
pct = int(
|
||||
round((max(0, min(d, t)) / max(1, t)) * 100.0)
|
||||
round(
|
||||
(max(0,
|
||||
min(d,
|
||||
t)) / max(1,
|
||||
t)) * 100.0
|
||||
)
|
||||
)
|
||||
progress.set_percent(pct)
|
||||
progress.set_status(f"downloading pages {d}/{t}")
|
||||
progress.set_status(
|
||||
f"downloading pages {d}/{t}"
|
||||
)
|
||||
else:
|
||||
progress.set_status(f"downloading pages {d}")
|
||||
progress.set_status(
|
||||
f"downloading pages {d}"
|
||||
)
|
||||
return
|
||||
|
||||
if kind == "bytes":
|
||||
@@ -576,14 +633,14 @@ class Download_File(Cmdlet):
|
||||
lbl = "download"
|
||||
progress.begin_transfer(label=lbl, total=total)
|
||||
progress.update_transfer(
|
||||
label=lbl, completed=done, total=total
|
||||
label=lbl,
|
||||
completed=done,
|
||||
total=total
|
||||
)
|
||||
try:
|
||||
if (
|
||||
isinstance(total, int)
|
||||
and total > 0
|
||||
and int(done) >= int(total)
|
||||
):
|
||||
if (isinstance(total,
|
||||
int) and total > 0
|
||||
and int(done) >= int(total)):
|
||||
progress.finish_transfer(label=lbl)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -591,7 +648,11 @@ class Download_File(Cmdlet):
|
||||
|
||||
progress_cb = _progress
|
||||
|
||||
downloaded_path = provider.download(sr, final_output_dir, progress_callback=progress_cb) # type: ignore[call-arg]
|
||||
downloaded_path = provider.download(
|
||||
sr,
|
||||
final_output_dir,
|
||||
progress_callback=progress_cb
|
||||
) # type: ignore[call-arg]
|
||||
except Exception as exc:
|
||||
raise DownloadError(str(exc))
|
||||
|
||||
@@ -635,7 +696,12 @@ class Download_File(Cmdlet):
|
||||
if callable(exec_fn):
|
||||
ret = exec_fn(
|
||||
None,
|
||||
["-provider", "libgen", "-query", fallback_query],
|
||||
[
|
||||
"-provider",
|
||||
"libgen",
|
||||
"-query",
|
||||
fallback_query
|
||||
],
|
||||
config,
|
||||
)
|
||||
try:
|
||||
@@ -643,7 +709,8 @@ class Download_File(Cmdlet):
|
||||
items = pipeline_context.get_last_result_items()
|
||||
if table is not None:
|
||||
pipeline_context.set_last_result_table_overlay(
|
||||
table, items
|
||||
table,
|
||||
items
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -665,7 +732,10 @@ class Download_File(Cmdlet):
|
||||
provider = get_provider(provider_name, config)
|
||||
if provider is not None and hasattr(provider, "download_url"):
|
||||
try:
|
||||
downloaded_path = provider.download_url(str(url), final_output_dir) # type: ignore[attr-defined]
|
||||
downloaded_path = provider.download_url(
|
||||
str(url),
|
||||
final_output_dir
|
||||
) # type: ignore[attr-defined]
|
||||
except Exception as exc:
|
||||
raise DownloadError(str(exc))
|
||||
|
||||
@@ -694,14 +764,20 @@ class Download_File(Cmdlet):
|
||||
path=str(url),
|
||||
full_metadata={},
|
||||
)
|
||||
downloaded_path = provider.download(sr_obj, final_output_dir) # type: ignore[call-arg]
|
||||
downloaded_path = provider.download(
|
||||
sr_obj,
|
||||
final_output_dir
|
||||
) # type: ignore[call-arg]
|
||||
except Exception:
|
||||
downloaded_path = None
|
||||
|
||||
# Refuse to fall back to direct-download for LibGen landing pages.
|
||||
# This prevents saving HTML (e.g. edition.php) as a bogus file.
|
||||
if (not downloaded_path) and str(provider_name).lower() == "libgen":
|
||||
raise DownloadError("LibGen URL did not resolve to a downloadable file")
|
||||
if (not downloaded_path
|
||||
) and str(provider_name).lower() == "libgen":
|
||||
raise DownloadError(
|
||||
"LibGen URL did not resolve to a downloadable file"
|
||||
)
|
||||
|
||||
if downloaded_path:
|
||||
emit_tags: Optional[List[str]] = None
|
||||
@@ -709,12 +785,15 @@ class Download_File(Cmdlet):
|
||||
title_hint = Path(str(downloaded_path)).stem
|
||||
media_kind_hint = "file"
|
||||
|
||||
if str(provider_name).lower() == "libgen" and sr_obj is not None:
|
||||
if str(provider_name
|
||||
).lower() == "libgen" and sr_obj is not None:
|
||||
media_kind_hint = "book"
|
||||
try:
|
||||
sr_tags = getattr(sr_obj, "tag", None)
|
||||
if isinstance(sr_tags, set) and sr_tags:
|
||||
emit_tags = sorted([str(t) for t in sr_tags if t])
|
||||
emit_tags = sorted(
|
||||
[str(t) for t in sr_tags if t]
|
||||
)
|
||||
except Exception:
|
||||
emit_tags = None
|
||||
|
||||
@@ -774,8 +853,10 @@ class Download_File(Cmdlet):
|
||||
self,
|
||||
*,
|
||||
piped_items: Sequence[Any],
|
||||
registry: Dict[str, Any],
|
||||
config: Dict[str, Any],
|
||||
registry: Dict[str,
|
||||
Any],
|
||||
config: Dict[str,
|
||||
Any],
|
||||
) -> List[Any]:
|
||||
get_search_provider = registry.get("get_search_provider")
|
||||
expanded_items: List[Any] = []
|
||||
@@ -786,18 +867,14 @@ class Download_File(Cmdlet):
|
||||
full_metadata = get_field(item, "full_metadata")
|
||||
target = get_field(item, "path") or get_field(item, "url")
|
||||
|
||||
if (
|
||||
str(table or "").lower() == "alldebrid"
|
||||
and str(media_kind or "").lower() == "folder"
|
||||
):
|
||||
if (str(table or "").lower() == "alldebrid"
|
||||
and str(media_kind or "").lower() == "folder"):
|
||||
magnet_id = None
|
||||
if isinstance(full_metadata, dict):
|
||||
magnet_id = full_metadata.get("magnet_id")
|
||||
if (
|
||||
magnet_id is None
|
||||
and isinstance(target, str)
|
||||
and target.lower().startswith("alldebrid:magnet:")
|
||||
):
|
||||
if (magnet_id is None and isinstance(target,
|
||||
str)
|
||||
and target.lower().startswith("alldebrid:magnet:")):
|
||||
try:
|
||||
magnet_id = int(target.split(":")[-1])
|
||||
except Exception:
|
||||
@@ -810,17 +887,18 @@ class Download_File(Cmdlet):
|
||||
files = provider.search(
|
||||
"*",
|
||||
limit=10_000,
|
||||
filters={"view": "files", "magnet_id": int(magnet_id)},
|
||||
filters={
|
||||
"view": "files",
|
||||
"magnet_id": int(magnet_id)
|
||||
},
|
||||
)
|
||||
except Exception:
|
||||
files = []
|
||||
|
||||
# If the magnet isn't ready, provider.search returns a single not-ready folder row.
|
||||
if (
|
||||
files
|
||||
and len(files) == 1
|
||||
and getattr(files[0], "media_kind", "") == "folder"
|
||||
):
|
||||
if (files and len(files) == 1 and getattr(files[0],
|
||||
"media_kind",
|
||||
"") == "folder"):
|
||||
detail = getattr(files[0], "detail", "")
|
||||
log(
|
||||
f"[download-file] AllDebrid magnet {magnet_id} not ready ({detail or 'unknown'})",
|
||||
@@ -829,7 +907,8 @@ class Download_File(Cmdlet):
|
||||
else:
|
||||
for sr in files:
|
||||
expanded_items.append(
|
||||
sr.to_dict() if hasattr(sr, "to_dict") else sr
|
||||
sr.to_dict() if hasattr(sr,
|
||||
"to_dict") else sr
|
||||
)
|
||||
continue
|
||||
|
||||
@@ -844,9 +923,11 @@ class Download_File(Cmdlet):
|
||||
*,
|
||||
piped_items: Sequence[Any],
|
||||
final_output_dir: Path,
|
||||
config: Dict[str, Any],
|
||||
config: Dict[str,
|
||||
Any],
|
||||
quiet_mode: bool,
|
||||
registry: Dict[str, Any],
|
||||
registry: Dict[str,
|
||||
Any],
|
||||
progress: PipelineProgress,
|
||||
) -> int:
|
||||
downloaded_count = 0
|
||||
@@ -854,7 +935,9 @@ class Download_File(Cmdlet):
|
||||
SearchResult = registry.get("SearchResult")
|
||||
|
||||
expanded_items = self._expand_provider_items(
|
||||
piped_items=piped_items, registry=registry, config=config
|
||||
piped_items=piped_items,
|
||||
registry=registry,
|
||||
config=config
|
||||
)
|
||||
|
||||
for item in expanded_items:
|
||||
@@ -871,11 +954,10 @@ class Download_File(Cmdlet):
|
||||
tags_list = None
|
||||
|
||||
full_metadata = get_field(item, "full_metadata")
|
||||
if (
|
||||
(not full_metadata)
|
||||
and isinstance(item, dict)
|
||||
and isinstance(item.get("extra"), dict)
|
||||
):
|
||||
if ((not full_metadata) and isinstance(item,
|
||||
dict)
|
||||
and isinstance(item.get("extra"),
|
||||
dict)):
|
||||
extra_md = item["extra"].get("full_metadata")
|
||||
if isinstance(extra_md, dict):
|
||||
full_metadata = extra_md
|
||||
@@ -892,9 +974,13 @@ class Download_File(Cmdlet):
|
||||
table=str(table),
|
||||
title=str(title or "Unknown"),
|
||||
path=str(target or ""),
|
||||
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}")
|
||||
|
||||
# Preserve provider structure when possible (AllDebrid folders -> subfolders).
|
||||
output_dir = final_output_dir
|
||||
@@ -902,16 +988,21 @@ class Download_File(Cmdlet):
|
||||
if str(table).strip().lower() == "alldebrid":
|
||||
from ProviderCore.download import sanitize_filename as _sf
|
||||
|
||||
md = full_metadata if isinstance(full_metadata, dict) else {}
|
||||
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")
|
||||
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
|
||||
str(get_field(item,
|
||||
"detail") or "").strip() or None
|
||||
)
|
||||
|
||||
magnet_dir_name = _sf(str(magnet_name)) if magnet_name else ""
|
||||
magnet_dir_name = _sf(
|
||||
str(magnet_name)
|
||||
) if magnet_name else ""
|
||||
|
||||
# If user already chose -path that ends with the magnet folder name,
|
||||
# don't create a duplicate nested folder.
|
||||
@@ -919,12 +1010,14 @@ class Download_File(Cmdlet):
|
||||
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 ""
|
||||
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 magnet_dir_name and (
|
||||
not base_tail_norm or base_tail_norm != magnet_dir_norm
|
||||
):
|
||||
if magnet_dir_name and (not base_tail_norm
|
||||
or base_tail_norm
|
||||
!= magnet_dir_norm):
|
||||
output_dir = Path(output_dir) / magnet_dir_name
|
||||
|
||||
relpath = None
|
||||
@@ -935,8 +1028,8 @@ class Download_File(Cmdlet):
|
||||
|
||||
if relpath:
|
||||
parts = [
|
||||
p
|
||||
for p in str(relpath).replace("\\", "/").split("/")
|
||||
p for p in str(relpath).replace("\\", "/"
|
||||
).split("/")
|
||||
if p and p not in {".", ".."}
|
||||
]
|
||||
|
||||
@@ -964,11 +1057,8 @@ class Download_File(Cmdlet):
|
||||
provider_sr = sr
|
||||
|
||||
# OpenLibrary: if provider download failed, do NOT try to download the OpenLibrary page HTML.
|
||||
if (
|
||||
downloaded_path is None
|
||||
and attempted_provider_download
|
||||
and str(table or "").lower() == "openlibrary"
|
||||
):
|
||||
if (downloaded_path is None and attempted_provider_download
|
||||
and str(table or "").lower() == "openlibrary"):
|
||||
availability = None
|
||||
reason = None
|
||||
if isinstance(full_metadata, dict):
|
||||
@@ -1002,7 +1092,10 @@ class Download_File(Cmdlet):
|
||||
|
||||
ret = exec_fn(
|
||||
None,
|
||||
["-provider", "libgen", "-query", fallback_query],
|
||||
["-provider",
|
||||
"libgen",
|
||||
"-query",
|
||||
fallback_query],
|
||||
config,
|
||||
)
|
||||
|
||||
@@ -1012,7 +1105,8 @@ class Download_File(Cmdlet):
|
||||
items_obj = pipeline_context.get_last_result_items()
|
||||
if table_obj is not None:
|
||||
pipeline_context.set_last_result_table_overlay(
|
||||
table_obj, items_obj
|
||||
table_obj,
|
||||
items_obj
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -1027,16 +1121,15 @@ class Download_File(Cmdlet):
|
||||
continue
|
||||
|
||||
# Fallback: if we have a direct HTTP URL, download it directly
|
||||
if (
|
||||
downloaded_path is None
|
||||
and isinstance(target, str)
|
||||
and target.startswith("http")
|
||||
):
|
||||
if (downloaded_path is None and isinstance(target,
|
||||
str)
|
||||
and target.startswith("http")):
|
||||
# Guard: provider landing pages (e.g. LibGen ads.php) are HTML, not files.
|
||||
# Never download these as "files".
|
||||
if str(table or "").lower() == "libgen":
|
||||
low = target.lower()
|
||||
if ("/ads.php" in low) or ("/file.php" in low) or ("/index.php" in low):
|
||||
if ("/ads.php" in low) or ("/file.php" in low) or ("/index.php"
|
||||
in low):
|
||||
log(
|
||||
"[download-file] Refusing to download LibGen landing page (expected provider to resolve file link)",
|
||||
file=sys.stderr,
|
||||
@@ -1092,7 +1185,8 @@ class Download_File(Cmdlet):
|
||||
title_hint=str(title) if title else downloaded_path.stem,
|
||||
tags_hint=tags_list,
|
||||
media_kind_hint=str(media_kind) if media_kind else None,
|
||||
full_metadata=full_metadata if isinstance(full_metadata, dict) else None,
|
||||
full_metadata=full_metadata if isinstance(full_metadata,
|
||||
dict) else None,
|
||||
progress=progress,
|
||||
config=config,
|
||||
)
|
||||
@@ -1105,7 +1199,13 @@ class Download_File(Cmdlet):
|
||||
|
||||
return downloaded_count
|
||||
|
||||
def _run_impl(self, result: Any, args: Sequence[str], config: Dict[str, Any]) -> int:
|
||||
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
|
||||
@@ -1139,26 +1239,26 @@ class Download_File(Cmdlet):
|
||||
|
||||
# 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"))
|
||||
):
|
||||
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:")
|
||||
("magnet:",
|
||||
"alldebrid:",
|
||||
"hydrus:",
|
||||
"ia:",
|
||||
"internetarchive:")
|
||||
)
|
||||
looks_like_windows_path = (
|
||||
(len(candidate) >= 2 and candidate[1] == ":")
|
||||
or candidate.startswith("\\\\")
|
||||
or candidate.startswith("\\")
|
||||
or candidate.endswith(("\\", "/"))
|
||||
or candidate.startswith("\\\\") or candidate.startswith("\\")
|
||||
or candidate.endswith(("\\",
|
||||
"/"))
|
||||
)
|
||||
if (not looks_like_url) and (not looks_like_provider) and looks_like_windows_path:
|
||||
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)
|
||||
@@ -1168,7 +1268,9 @@ class Download_File(Cmdlet):
|
||||
return 1
|
||||
|
||||
quiet_mode = (
|
||||
bool(config.get("_quiet_background_output")) if isinstance(config, dict) else False
|
||||
bool(config.get("_quiet_background_output"))
|
||||
if isinstance(config,
|
||||
dict) else False
|
||||
)
|
||||
ia_picker_exit = self._maybe_show_internetarchive_formats(
|
||||
raw_urls=raw_url,
|
||||
@@ -1194,7 +1296,9 @@ class Download_File(Cmdlet):
|
||||
preview = self._build_preview(raw_url, piped_items, total_items)
|
||||
|
||||
progress.ensure_local_ui(
|
||||
label="download-file", total_items=total_items, items_preview=preview
|
||||
label="download-file",
|
||||
total_items=total_items,
|
||||
items_preview=preview
|
||||
)
|
||||
|
||||
registry = self._load_provider_registry()
|
||||
@@ -1243,7 +1347,11 @@ class Download_File(Cmdlet):
|
||||
pass
|
||||
progress.close_local_ui(force_complete=True)
|
||||
|
||||
def _resolve_output_dir(self, parsed: Dict[str, Any], config: Dict[str, Any]) -> Optional[Path]:
|
||||
def _resolve_output_dir(self,
|
||||
parsed: Dict[str,
|
||||
Any],
|
||||
config: Dict[str,
|
||||
Any]) -> Optional[Path]:
|
||||
"""Resolve the output directory from storage location or config."""
|
||||
output_dir_arg = parsed.get("path") or parsed.get("output")
|
||||
if output_dir_arg:
|
||||
@@ -1252,7 +1360,10 @@ class Download_File(Cmdlet):
|
||||
out_path.mkdir(parents=True, exist_ok=True)
|
||||
return out_path
|
||||
except Exception as e:
|
||||
log(f"Cannot use output directory {output_dir_arg}: {e}", file=sys.stderr)
|
||||
log(
|
||||
f"Cannot use output directory {output_dir_arg}: {e}",
|
||||
file=sys.stderr
|
||||
)
|
||||
return None
|
||||
|
||||
storage_location = parsed.get("storage")
|
||||
@@ -1267,7 +1378,7 @@ class Download_File(Cmdlet):
|
||||
|
||||
# Priority 2: Config default output/temp directory
|
||||
try:
|
||||
from config import resolve_output_dir
|
||||
from SYS.config import resolve_output_dir
|
||||
|
||||
final_output_dir = resolve_output_dir(config)
|
||||
except Exception:
|
||||
@@ -1279,7 +1390,10 @@ class Download_File(Cmdlet):
|
||||
try:
|
||||
final_output_dir.mkdir(parents=True, exist_ok=True)
|
||||
except Exception as e:
|
||||
log(f"Cannot create output directory {final_output_dir}: {e}", file=sys.stderr)
|
||||
log(
|
||||
f"Cannot create output directory {final_output_dir}: {e}",
|
||||
file=sys.stderr
|
||||
)
|
||||
return None
|
||||
|
||||
return final_output_dir
|
||||
|
||||
Reference in New Issue
Block a user