feat(external): mega.nz via megatools in the runtime image (Phase 4c)
Use `megatools dl` (Debian-native apt package) for mega.nz public links rather than MEGAcmd — no external MEGA apt repo/key to add, one apt line. Adds `megatools` to the runtime Dockerfile; the fetcher's mega backend now shells `megatools dl --path <dir> <url>` (key in the #fragment is preserved by the extractor). gdown (gdrive) is already a pip dep in the runtime image. NOTE: build.yml builds the image on main/tags only (not dev), so this Dockerfile change is verified on the next dev→main merge, not by this dev push. The fetcher code path is unit-tested via the mocked _run_mega_get seam. With this, all 5 hosts download end-to-end once a celery download-worker runs. Refs FC #830 (Phase 4c). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+4
-1
@@ -18,13 +18,16 @@ ENV PYTHONUNBUFFERED=1 \
|
||||
|
||||
# System deps: ffmpeg (transcode + thumbnails, FC-2), unar (archives, FC-2),
|
||||
# libpq for psycopg, postgresql-client + zstd for FC-5 backup/restore
|
||||
# (pg_dump + tar --zstd), image libs.
|
||||
# (pg_dump + tar --zstd), image libs, megatools (mega.nz public-link downloads
|
||||
# for off-platform file-host links, #830 — `megatools dl`; Debian-native, no
|
||||
# external MEGA apt repo needed).
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ffmpeg \
|
||||
unar \
|
||||
libpq5 \
|
||||
postgresql-client \
|
||||
zstd \
|
||||
megatools \
|
||||
libjpeg62-turbo \
|
||||
libwebp7 \
|
||||
libpng16-16 \
|
||||
|
||||
@@ -16,8 +16,8 @@ Backends:
|
||||
- pixeldrain : GET the /api/file/{id} endpoint.
|
||||
- mediafire : scrape the download page for the direct link + stream GET.
|
||||
- gdrive : gdown (handles the confirm-token + virus-scan interstitial).
|
||||
- mega : MEGAcmd `mega-get` subprocess (public link incl. #key); needs
|
||||
the binary in the runtime image.
|
||||
- mega : `megatools dl` subprocess (public link incl. #key); needs the
|
||||
`megatools` binary in the runtime image (Debian apt package).
|
||||
|
||||
Public links work credential-free (rule 26); per-host creds are a later Settings
|
||||
concern. Plain-HTTP homelab — no secure-context API. The HTTP / gdown /
|
||||
@@ -89,16 +89,17 @@ def _gdown_download(url: str, out_dir: str) -> str | None:
|
||||
|
||||
def _run_mega_get(url: str, out_dir: str, *, timeout: float) -> None:
|
||||
"""Download a mega.nz public link (key in the #fragment) into out_dir via
|
||||
MEGAcmd's `mega-get`. Raises ExternalFetchError on non-zero exit."""
|
||||
# Fixed argv (not shell): only `url` is external input, and it's a positional
|
||||
# arg to mega-get, so there's no shell-injection surface.
|
||||
`megatools dl` (the Debian `megatools` package). Raises ExternalFetchError
|
||||
on non-zero exit."""
|
||||
# Fixed argv (not shell): only `url` is external input, passed positionally,
|
||||
# so there's no shell-injection surface.
|
||||
proc = subprocess.run(
|
||||
["mega-get", url, out_dir],
|
||||
["megatools", "dl", "--path", out_dir, url],
|
||||
capture_output=True, text=True, timeout=timeout, check=False,
|
||||
)
|
||||
if proc.returncode != 0:
|
||||
raise ExternalFetchError(
|
||||
f"mega-get exit {proc.returncode}: {(proc.stderr or '').strip()[:300]}"
|
||||
f"megatools dl exit {proc.returncode}: {(proc.stderr or '').strip()[:300]}"
|
||||
)
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -41,5 +41,5 @@ py7zr>=1,<2
|
||||
|
||||
# Google Drive fetcher for off-platform file-host links (external downloads,
|
||||
# #830). Handles Drive's confirm-token + virus-scan interstitial. mega.nz uses
|
||||
# the MEGAcmd `mega-get` binary instead (added to the runtime image, not pip).
|
||||
# the `megatools` binary instead (Debian apt pkg in the runtime image, not pip).
|
||||
gdown>=5,<6
|
||||
|
||||
Reference in New Issue
Block a user