mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-06-11 03:32:10 +00:00
feat(api): aggregate REST download progress with weighting, track labels and mux stage
Replace the class-level Track.download monkeypatch with a per-job progress sink threaded through dl.result(). The API now reports a single aggregate signal instead of each track's bouncing 0-100%:
- bitrate-weighted completion so video/audio dominate subtitles
- completed_tracks/total_tracks counts and active_tracks labels (e.g. "video 2160p DV", "audio en-US 5.1")
- downloads fill 0-90%; repackaging (when needed) and a "muxing" stage carry it to 100% so post-download work is no longer frozen at 100%
- monotonic throughout (handles the download->decrypt callable reuse)
Also:
- accept "HDR10P" as the canonical API range value ("HDR10+" still works)
- declare AUTH_METHODS opt-in on the Service base
- raise typed APIError (WORKER_ERROR/DOWNLOAD_ERROR) from the worker path
- move the progress helpers to unshackle/core/api/progress.py
This commit is contained in:
@@ -9,13 +9,8 @@ import pytest
|
||||
from aiohttp import web
|
||||
|
||||
from unshackle.core.api import handlers
|
||||
from unshackle.core.api.download_manager import (
|
||||
DownloadJob,
|
||||
JobStatus,
|
||||
_redact_parameters,
|
||||
_redact_text,
|
||||
_secret_values,
|
||||
)
|
||||
from unshackle.core.api.download_manager import (DownloadJob, JobStatus, _redact_parameters, _redact_text,
|
||||
_secret_values)
|
||||
from unshackle.core.api.errors import APIError, APIErrorCode
|
||||
|
||||
pytestmark = pytest.mark.unit
|
||||
@@ -140,3 +135,18 @@ async def test_credential_allowed_when_enabled(stub_handler):
|
||||
stub_handler.setattr(handlers.config, "serve", {"allow_job_credentials": True})
|
||||
resp = await handlers.download_handler({"service": "ATV", "title_id": "t", "credential": "u:p"})
|
||||
assert isinstance(resp, web.Response)
|
||||
|
||||
|
||||
# ---------- range validation ----------
|
||||
|
||||
|
||||
def test_range_validation_accepts_hdr10p_and_alias():
|
||||
# canonical "HDR10P" and back-compat "HDR10+" both pass; mixed casing too
|
||||
assert handlers.validate_download_parameters({"range": ["HDR10P", "DV", "SDR"]}) is None
|
||||
assert handlers.validate_download_parameters({"range": ["hdr10+"]}) is None
|
||||
assert handlers.validate_download_parameters({"range": "HYBRID"}) is None
|
||||
|
||||
|
||||
def test_range_validation_rejects_unknown_and_lists_hdr10p():
|
||||
err = handlers.validate_download_parameters({"range": ["HDR99"]})
|
||||
assert err and "HDR10P" in err and "HDR99" in err
|
||||
|
||||
Reference in New Issue
Block a user