b1757b631c
The Floor bar used a file-count poller that jumps 0→~99% for small/fast albums (streamrip reports only 0/1). But yt-dlp and slskd already emit real byte-level progress via the on_progress callback the pipeline was discarding (lambda _pct: None). - Thread a throttled on_progress → Job.downloadProgress (write on a >=1% move or every 0.5s; clamped 0..1; write failures swallowed). Called synchronously from adapter.download on the pipeline thread, so it reuses the main conn safely. - The file-count poller stays as the FALLBACK: it skips writing while a `reports` flag is set (an adapter is driving real progress), and the flag is cleared per attempt so a fall-through to streamrip still gets the estimate. - Smooth bars for YouTube + Soulseek now; Qobuz/streamrip keeps the file-count estimate until its per-track callback is hooked later. worker 216 tests / 7-skip (on_progress write/throttle/clamp covered; existing pipeline tests now exercise the fake's on_progress end-to-end). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
58 lines
1.8 KiB
Python
58 lines
1.8 KiB
Python
import os
|
|
import threading
|
|
|
|
from lyra_worker.pipeline import _count_staged_audio, _make_on_progress
|
|
from tests.conftest import insert_request
|
|
|
|
|
|
def _dp(conn, job_id):
|
|
with conn.cursor() as cur:
|
|
cur.execute('SELECT "downloadProgress" FROM "Job" WHERE id = %s', (job_id,))
|
|
return cur.fetchone()[0]
|
|
|
|
|
|
def test_on_progress_marks_reporting_and_writes(conn):
|
|
job_id = insert_request(conn)
|
|
reports = threading.Event()
|
|
cb = _make_on_progress(conn, job_id, reports)
|
|
cb(0.3)
|
|
assert reports.is_set() # signals the poller to yield
|
|
assert _dp(conn, job_id) == 0.3
|
|
|
|
|
|
def test_on_progress_throttles_tiny_moves(conn):
|
|
job_id = insert_request(conn)
|
|
cb = _make_on_progress(conn, job_id, threading.Event())
|
|
cb(0.30)
|
|
cb(0.305) # <1% and <0.5s later → throttled, not written
|
|
assert _dp(conn, job_id) == 0.3
|
|
cb(0.6) # >=1% move → written
|
|
assert _dp(conn, job_id) == 0.6
|
|
|
|
|
|
def test_on_progress_clamps_out_of_range(conn):
|
|
job_id = insert_request(conn)
|
|
_make_on_progress(conn, job_id, threading.Event())(1.5)
|
|
assert _dp(conn, job_id) == 1.0
|
|
_make_on_progress(conn, job_id, threading.Event())(-0.2)
|
|
assert _dp(conn, job_id) == 0.0
|
|
|
|
|
|
def test_count_staged_audio_counts_nested_audio_files_only(tmp_path):
|
|
nested = tmp_path / "Artist" / "Album"
|
|
nested.mkdir(parents=True)
|
|
(nested / "01.flac").write_bytes(b"")
|
|
(nested / "02.flac").write_bytes(b"")
|
|
(nested / "03.flac").write_bytes(b"")
|
|
(nested / "cover.jpg").write_bytes(b"")
|
|
|
|
assert _count_staged_audio(str(tmp_path)) == 3
|
|
|
|
|
|
def test_count_staged_audio_empty_dir_is_zero(tmp_path):
|
|
assert _count_staged_audio(str(tmp_path)) == 0
|
|
|
|
|
|
def test_count_staged_audio_missing_dir_is_zero():
|
|
assert _count_staged_audio("/nonexistent/path/for/sure") == 0
|