fix(downloads): a download larger than the space left says so, not "processing failed"
yt-dlp refuses a file announced over `max_filesize` by logging one line and returning with no file (measured, and pinned in test_formats against a local server): the worker found no output and failed the job as `postprocess`. `formats.watching_size_cap` now sees that line through our yt-dlp logger, and the download (and, should it ever happen, a YouTube clip's range fetch) fails as the owner's refusal with DOWNLOAD_TOO_BIG_MESSAGE, classified `quota_exceeded`. The download's quota copy says it does not fit in what is left — true at a full cap too — instead of "Storage full". A pre-existing type error the change touched is fixed (baseline down by one).
This commit is contained in:
@@ -3,6 +3,13 @@ playability guarantee) and must SELECT H.264 (not merely prefer it), so shared d
|
||||
every browser incl. iOS/Safari. Non-mp4 containers and non-H.264 vcodecs are coerced, not honoured.
|
||||
See the iPad AV1 broken-player fix + the format narrowing."""
|
||||
|
||||
import contextlib
|
||||
import functools
|
||||
import http.server
|
||||
import threading
|
||||
|
||||
import yt_dlp
|
||||
|
||||
from app.downloads import edit as editmod
|
||||
from app.downloads import formats
|
||||
|
||||
@@ -162,3 +169,40 @@ def test_the_mp3_fix_moved_the_audio_cache_identity(monkeypatch):
|
||||
current = formats.format_sig(audio)
|
||||
monkeypatch.setattr(formats, "_AUDIO_SIG_VERSION", 4)
|
||||
assert formats.format_sig(audio) != current
|
||||
|
||||
|
||||
class _QuietFiles(http.server.SimpleHTTPRequestHandler):
|
||||
def log_message(self, *args): # the test's output is yt-dlp's, not the server's
|
||||
pass
|
||||
|
||||
def handle(self):
|
||||
# yt-dlp hangs up on a file over the cap as soon as it reads its size.
|
||||
with contextlib.suppress(ConnectionError):
|
||||
super().handle()
|
||||
|
||||
|
||||
def test_yt_dlp_refuses_a_file_over_the_cap_without_raising_and_the_watch_sees_it(tmp_path):
|
||||
# The boundary `watching_size_cap` reads, held against the yt-dlp this image pins: over
|
||||
# `max_filesize` its HTTP downloader logs one line and RETURNS — no exception, no file — so
|
||||
# without the watch the pipeline would only find "no output file" and call it a processing fault.
|
||||
served = tmp_path / "served"
|
||||
served.mkdir()
|
||||
(served / "v.mp4").write_bytes(b"\0" * 200_000)
|
||||
srv = http.server.ThreadingHTTPServer(
|
||||
("127.0.0.1", 0), functools.partial(_QuietFiles, directory=str(served))
|
||||
)
|
||||
threading.Thread(target=srv.serve_forever, daemon=True).start()
|
||||
url = f"http://127.0.0.1:{srv.server_port}/v.mp4"
|
||||
try:
|
||||
for cap, refused in ((1_000, True), (10_000_000, False)):
|
||||
out = tmp_path / f"out-{cap}"
|
||||
opts = formats.build_ydl_opts(
|
||||
{}, str(out / "%(id)s.%(ext)s"), lambda d: None, max_bytes=cap
|
||||
)
|
||||
with formats.watching_size_cap() as over, yt_dlp.YoutubeDL(opts) as ydl:
|
||||
ydl.extract_info(url, download=True)
|
||||
assert over[0] is refused, cap
|
||||
files = [p for p in out.glob("*") if p.suffix == ".mp4"] if out.exists() else []
|
||||
assert bool(files) is not refused, cap
|
||||
finally:
|
||||
srv.shutdown()
|
||||
|
||||
Reference in New Issue
Block a user