mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 12:05:07 +00:00
fix(remote): forward track selection params to server and improve error display
Forward range, vcodec, quality, and best_available from client to server so services fetch the correct manifests (e.g. HDR10 instead of SDR). Exit with error when no video tracks match the requested range filter. Use Rich logger for remote API errors instead of plain click.ClickException.
This commit is contained in:
@@ -1561,6 +1561,9 @@ class dl:
|
||||
missing_ranges = [r for r in range_ if not any(x.range == r for x in title.tracks.videos)]
|
||||
for color_range in missing_ranges:
|
||||
self.log.warning(f"Skipping {color_range.name} video tracks as none are available.")
|
||||
if not title.tracks.videos:
|
||||
self.log.error(f"There's no {', '.join(r.name for r in range_)} Video Track...")
|
||||
sys.exit(1)
|
||||
|
||||
if vbitrate:
|
||||
if any(r == Video.Range.HYBRID for r in range_):
|
||||
|
||||
@@ -1231,7 +1231,39 @@ def _create_service_instance(
|
||||
cdm = _resolve_server_cdm(normalized_service, profile, data.get("cdm_type"))
|
||||
|
||||
ctx.obj = ContextData(config=service_config, cdm=cdm, proxy_providers=proxy_providers, profile=profile)
|
||||
ctx.params = {"proxy": proxy_param, "no_proxy": data.get("no_proxy", False)}
|
||||
# Reconstruct track selection params from client data
|
||||
from unshackle.core.tracks import Video
|
||||
|
||||
range_names = data.get("range_")
|
||||
range_values = None
|
||||
if range_names:
|
||||
range_values = []
|
||||
for name in range_names:
|
||||
try:
|
||||
range_values.append(Video.Range[name])
|
||||
except KeyError:
|
||||
pass
|
||||
range_values = range_values or None
|
||||
|
||||
vcodec_names = data.get("vcodec")
|
||||
vcodec_values = None
|
||||
if vcodec_names:
|
||||
vcodec_values = []
|
||||
for name in vcodec_names:
|
||||
try:
|
||||
vcodec_values.append(Video.Codec[name])
|
||||
except KeyError:
|
||||
pass
|
||||
vcodec_values = vcodec_values or None
|
||||
|
||||
ctx.params = {
|
||||
"proxy": proxy_param,
|
||||
"no_proxy": data.get("no_proxy", False),
|
||||
"range_": range_values,
|
||||
"vcodec": vcodec_values,
|
||||
"quality": data.get("quality"),
|
||||
"best_available": data.get("best_available", False),
|
||||
}
|
||||
|
||||
service_module = Services.load(normalized_service)
|
||||
|
||||
@@ -1258,6 +1290,10 @@ def _create_service_instance(
|
||||
"client_region",
|
||||
"no_proxy",
|
||||
"cdm_type",
|
||||
"range_",
|
||||
"vcodec",
|
||||
"quality",
|
||||
"best_available",
|
||||
}
|
||||
|
||||
service_init_params = inspect.signature(service_module.__init__).parameters
|
||||
|
||||
@@ -68,7 +68,8 @@ class RemoteClient:
|
||||
if resp.status_code >= 400:
|
||||
error_msg = result.get("message", resp.text)
|
||||
error_code = result.get("error_code", "UNKNOWN")
|
||||
raise click.ClickException(f"Server error [{error_code}]: {error_msg}")
|
||||
log.error(f"Server error [{error_code}]: {error_msg}")
|
||||
raise SystemExit(1)
|
||||
return result
|
||||
|
||||
def post(self, endpoint: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
@@ -492,6 +493,20 @@ class RemoteService:
|
||||
create_data["profile"] = profile
|
||||
if no_proxy:
|
||||
create_data["no_proxy"] = True
|
||||
# Forward track selection params so the server fetches the right manifests
|
||||
if self.ctx.parent:
|
||||
range_ = self.ctx.parent.params.get("range_")
|
||||
if range_:
|
||||
create_data["range_"] = [r.name for r in range_]
|
||||
vcodec = self.ctx.parent.params.get("vcodec")
|
||||
if vcodec:
|
||||
create_data["vcodec"] = [c.name for c in vcodec]
|
||||
quality = self.ctx.parent.params.get("quality")
|
||||
if quality:
|
||||
create_data["quality"] = list(quality)
|
||||
if self.ctx.parent.params.get("best_available"):
|
||||
create_data["best_available"] = True
|
||||
|
||||
if self._service_params:
|
||||
create_data.update(self._service_params)
|
||||
|
||||
@@ -530,7 +545,8 @@ class RemoteService:
|
||||
|
||||
if status == "failed":
|
||||
error = resp.get("error", "Authentication failed on server")
|
||||
raise click.ClickException(f"Remote auth failed: {error}")
|
||||
log.error(f"Remote auth failed: {error}")
|
||||
raise SystemExit(1)
|
||||
|
||||
if status == "pending_input":
|
||||
prompt = resp.get("prompt", "Enter input: ")
|
||||
@@ -543,7 +559,8 @@ class RemoteService:
|
||||
|
||||
time.sleep(poll_interval)
|
||||
|
||||
raise click.ClickException("Remote authentication timed out")
|
||||
log.error("Remote authentication timed out")
|
||||
raise SystemExit(1)
|
||||
|
||||
def get_titles(self) -> Titles_T:
|
||||
if self._titles is not None:
|
||||
|
||||
Reference in New Issue
Block a user