fix(worker): smooth Qobuz download progress via streamrip byte hook
streamrip reports progress only per concurrent track, so Job.downloadProgress came solely from the file-count poller — 0% until every track landed, then a jump to 100%. Patch streamrip.media.track.get_progress_callback to aggregate per-track byte deltas over an estimated album total (avg started-track size × len(album.tracks)) into one smooth, generally-climbing 0..1 fraction routed through the pipeline's on_progress. Capped at 0.99; the pipeline sets 1.0 on completion. No signature changes — track count read from the resolved album. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
from lyra_worker.adapters._streamrip import _ProgressAggregator
|
||||
|
||||
|
||||
def _record():
|
||||
seen: list[float] = []
|
||||
return seen, seen.append
|
||||
|
||||
|
||||
def test_equal_size_tracks_aggregate_monotonically_to_near_one():
|
||||
# 4 tracks of 100 bytes each, all started up front (concurrency covers the album), then
|
||||
# each downloaded in 25-byte chunks. Fraction must climb monotonically 0→~1.
|
||||
seen, cb = _record()
|
||||
agg = _ProgressAggregator(4, cb)
|
||||
for _ in range(4):
|
||||
agg.start_track(100)
|
||||
for _ in range(16): # 16 chunks * 25 bytes = 400 bytes = full album
|
||||
agg.advance(25)
|
||||
|
||||
assert seen == sorted(seen) # monotonic non-decreasing
|
||||
assert all(0.0 <= f <= 0.99 for f in seen) # never negative, capped at 0.99
|
||||
assert seen[-1] == 0.99 # reaches the cap when all bytes are in
|
||||
assert seen[len(seen) // 2] > 0.3 # genuinely climbs mid-download (no 0→100 jump)
|
||||
|
||||
|
||||
def test_estimate_uses_track_count_before_all_tracks_start():
|
||||
# Only the first of 4 tracks has started; with a known track count the estimate already
|
||||
# spans the whole album, so finishing track 1 reports ~1/4, not ~1/1.
|
||||
seen, cb = _record()
|
||||
agg = _ProgressAggregator(4, cb)
|
||||
agg.start_track(100)
|
||||
agg.advance(100) # track 1 fully downloaded
|
||||
assert abs(seen[-1] - 0.25) < 0.01
|
||||
|
||||
|
||||
def test_zero_or_missing_sizes_never_emit_and_never_divide_by_zero():
|
||||
seen, cb = _record()
|
||||
agg = _ProgressAggregator(0, cb)
|
||||
agg.advance(50) # no track started yet -> no emit
|
||||
agg.start_track(0) # a track with unknown size
|
||||
agg.advance(50) # est_total still 0 -> still no emit, no crash
|
||||
assert seen == []
|
||||
Reference in New Issue
Block a user