Commit Graph
87 Commits
Author SHA1 Message Date
imSp4rky b710b5b0c9 feat(titles): add a sports output and folder template kind
A sport episode uses output_template.sports with a {date} in the template's separator style; the flag survives --remote, the REST API and export.
2026-11-03 08:43:05 -07:00
imSp4rky 842ece3802 fix(manifests): skip filtered dash periods after the main content and keep them over export
A manifest snapshot module now saves and restores DASH/ISM parser state for --remote and export/import, so an import keeps the service's period filter without fetching the manifest.
2026-11-02 20:41:27 -07:00
imSp4rky eeff83b820 fix(api): cast download job options with the dl click types
cast_dl_params feeds ctx.params to dl() and dl.result() as on the CLI. A string lang value now returns 400 instead of splitting into letters, and -r accepts HDR10+.
2026-11-02 20:30:40 -07:00
imSp4rky 65c8e60a7a fix(api): check and cast download job service options like a session does
A bad value now gets 400 INVALID_PARAMETERS at submit and the worker casts each option; a flat dl key such as quality or lang no longer fills a service option of the same name.
2026-11-01 20:21:42 -07:00
imSp4rky 99f0c269be fix(api): refuse a non-public proxy host for a key without server_proxy
Closes the loopback and LAN route to the server's own forwarders, including backslash, percent-escape and *.localhost forms.
2026-11-01 20:04:06 -07:00
imSp4rky e509db618e fix(api): keep a pooled remote session to the api key that opened it
The pool key now includes the caller's API key and client_region, so a hit never skips the server_proxy and region checks that a fresh session runs.
2026-11-01 19:47:19 -07:00
imSp4rky e6a627118f feat(tracks): add a display-only note shown in --list and over --remote 2026-10-30 16:17:36 -06:00
imSp4rky 5206b3cab6 refactor(remote)!: send service options only in service_params
A service option named like a dl option (e.g. --profile) is no longer dropped or mixed with the dl value; the server casts nested values and keeps cli defaults nested.
2026-10-30 16:16:56 -06:00
imSp4rky d12a943d96 fix(api): show filename codec and range labels in codec_display and range_display 2026-10-28 15:34:52 -06:00
imSp4rky 9f86464826 fix(api): cache the health update check and fix a remote-session test fixture 2026-10-27 13:38:57 -06:00
imSp4rky 756c2ce2b5 feat(remote): reopen a lost remote session and resume at the current title 2026-10-27 13:24:31 -06:00
imSp4rky 9017ab95b7 feat(tracks): add Video.hdr10_base and forward s_lang over remote and REST
A DV track with an HDR10 base (profile 8.1) lists as DV+HDR10; dl_params now carry s_lang.
2026-10-27 13:06:48 -06:00
imSp4rky cc33600cc7 feat(tracks): add muxing.original_label to mark original-language tracks
Adds the label to audio, subtitle and embedded audio names unless the name already says it, and escapes track lines in the --list tree.
2026-10-24 22:51:35 -06:00
imSp4rky 80bda08f36 feat(tracks): add muxing.track_names none to leave unnamed tracks unnamed
A track the service gives no name keeps none (--list shows [VTT] | en); SDH, CC, Forced and Descriptive labels still apply.
2026-10-24 21:24:31 -06:00
imSp4rky ecf17baffe feat(tracks): add native track names with muxing.track_names
Set muxing.track_names to native to name an unnamed track in its own language (中文(繁體), Português (Portugal)) in place of English. The same script and region rules apply. --list, the muxed names and the REST API track_name follow the option. A test fixture resets the muxing options, so a local unshackle.yaml cannot change test results.
2026-10-24 12:43:50 -06:00
imSp4rky 1175035317 feat(tracks): name unnamed tracks by language and tag subtitle scripts
Unnamed tracks get the English language name (default region left out); subtitle tags gain the script their region implies (zh-TW -> zh-Hant-TW). Refs #169
2026-10-24 10:59:21 -06:00
imSp4rky cc4bf19706 fix(vaults): stop false bad-key flags from a failed decode check
Judge a vault KID only on a file whose KID map holds it, tell remote vaults of a bad pair only once another key replaces it, and let the server CDM unflag a pair it returns; the server never flags a CDM-licensed pair. Log FFmpeg stderr on a failed check and name the missing CDM when none is set.
2026-10-23 15:31:26 -06:00
imSp4rky eeaf16cd83 fix(remote): keep each session cookie's domain, path and secure flag
The client set server cookies with no domain and sent all of them to every host, so a CDN refused segment requests with 400 header too large. rnet sessions now send cookies too.
2026-10-23 09:42:01 -06:00
imSp4rky 5086dafff3 feat(api)!: add a server drain and never answer with a 5xx
POST/DELETE /api/dashboard/drain refuses new sessions and jobs (SERVER_DRAINING, 409) and warns open sessions. A CDN can replace a 5xx body, so server errors are now 422, retryable ones and the tunnel check 424, and a new middleware turns any 5xx into 422.

BREAKING CHANGE: INTERNAL_ERROR, DOWNLOAD_ERROR, WORKER_ERROR and the fallback return 422 instead of 500; NETWORK_ERROR and SERVICE_UNAVAILABLE return 424 instead of 503; /api/tunnel/check failures return 424 instead of 502.
2026-10-21 17:15:33 -06:00
imSp4rky 39ec591c48 fix(api)!: send service and DRM errors as 422, not 502
Cloudflare replaces an origin 502 body with its own page, so clients got "502: Bad gateway" in place of the error and resent each failed licence.

BREAKING CHANGE: SERVICE_ERROR and DRM_ERROR now return HTTP 422 instead of 502.
2026-10-21 11:43:33 -06:00
imSp4rky 2cc5e44957 feat(search): add --remote to search through a remote server
The client sends its credentials, cookies and cache, but none for an anonymous-search service. The API relay uses the same path.
2026-10-18 13:23:04 -06:00
imSp4rky d7c6907329 feat(tracks): probe dv tracks for hdr10+ and list them as DV+HDR10P
A DV track that carries HDR10+ keeps its DV range and gets Video.hdr10plus, sent in the REST track JSON and to remote clients.
2026-10-18 11:43:44 -06:00
imSp4rky 35871f3a52 feat(hybrid): generate dolby vision from hdr10+ with --generate-dv
Builds per-scene L1 in unshackle (PQ mean, letterbox-aware) with a generate_dv_mode config (v29/v40/legacy); a failed hybrid no longer exits 0 with no video.
2026-10-17 16:40:14 -06:00
imSp4rky 14bd2f2c7e feat(api): relay services from remote servers with pooled sessions and login prompts 2026-10-16 19:03:56 -06:00
imSp4rky a4ce70a53c feat(tracks)!: match a language tag to the variant it means
A tag with a region (en-US, es-419) matches only that variant and reports a miss instead of taking another region. A bare tag takes the variant it means (pt -> pt-BR, es -> es-ES) and falls back to any variant only when that one is missing. `orig` prefers the title's own tag, `-sl orig` resolves, forced and SDH subtitles are picked from their own pools, and the track name no longer strips the region from the cached language.

BREAKING CHANGE: -l es-419 no longer selects es-ES, and language_priority, language_tags and muxing.default_language treat a regional tag as exact.
2026-10-15 12:26:39 -06:00
imSp4rky d41bb73d9e feat(remote): decrypt service-owned cbcs samples on the server
The client downloads the file and sends binary sample frames to a new samples route.
2026-10-14 11:03:14 -06:00
imSp4rky 4fbaf2a61a feat(api): forward exact_lang to the service context
The remote-dl client sends exact_lang in dl_params, and REST download jobs set it in the service ctx, so a service can skip the manifests of close-match languages.
2026-10-13 15:07:01 -06:00
imSp4rky ecdfb667c9 feat(dl): add --sample and --include-sample
--sample downloads only a time window of a title (default 120-180 s) and cuts the mux to it. --include-sample cuts a 60 s sample from a finished file. Both write to a Sample folder with a SAMPLE tag on the filename
2026-10-11 14:53:50 -06:00
imSp4rky 0a7c76561c feat(search): add ANONYMOUS_SEARCH to skip the login for a service
A service that sets the flag gets no cookie load, no authenticate() call and no cookie save on a search, on the CLI and in the REST search handler. /api/services reports it as anonymous_search.
2026-10-10 13:21:14 -06:00
imSp4rky 09cae2ec3f feat(serve): relay approval messages to jobs and proxy remote downloads
A REST job shows a wait_for_approval message as its notice field. search, list-titles and list-tracks fail at once on a login that needs the user. A remote client downloads through the --proxy it sends.
2026-10-07 11:15:16 -06:00
imSp4rky 5b0369e63a feat(service): add wait_for_approval and return the cache for a login with no prompt
A pair code shown in a log line never answers a prompt, so the server read that login as anonymous and kept the session cache.
2026-10-07 09:03:18 -06:00
imSp4rky 3477d09cc2 feat(dl): add --audio-description-only and --forced-subs-only
Each keeps one kind of track inside its track type. A run of more than one title skips a title that has no such track. The REST API rejects a non-boolean value for a boolean dl param, and the DASH parser reads audio description from Role elements.
2026-10-06 12:45:52 -06:00
imSp4rky 1d2cb3a102 fix(dl): read the vaults first under --all-drm
A DRM system sends a challenge only for a KID with no content key. --cdm-only keeps one challenge per system for each set of KIDs.
2026-10-05 16:43:54 -06:00
imSp4rky ee38477b11 feat(dl): add --all-drm to license Widevine and PlayReady per track
Each DRM system sends one challenge per KID set in a run, also when a vault has the content keys. Needs a CDM for each system in the cdm config.
2026-10-05 15:22:01 -06:00
imSp4rky fdcc653b66 fix(api): keep the worker's error on failed jobs, gate tracebacks behind --debug-api
Failed jobs now keep the worker's traceback, error_details and error_code instead of the "Worker exited" wrapper. error_traceback and worker_stderr only reach API clients under --debug-api.
2026-09-29 15:53:10 -06:00
imSp4rky 37e2b59bce feat(dl): add --latest-episodes N to download the N newest episodes
Split episodes count once. Exposed as latest_episodes on the REST API. Closes #159.
2026-09-28 09:01:40 -06:00
imSp4rky 174192882f feat(serve): relay service prompts from download jobs to the REST client
A job's input_prompt carries a service's request_input() prompt; the client answers it with POST /api/download/jobs/{job_id}/input.
2026-09-25 09:32:35 -06:00
imSp4rky 7d31153c7f feat(remote): cap server CDM licensing by height per API key and service
A session above the cap licenses with the client's own device, and a track above it in an uncapped -q run is handed back to the client. Also names the fallback in the ccextractor crash warning.
2026-09-24 16:50:26 -06:00
imSp4rky 91db1fa0b1 feat(remote): keep slow remote session requests alive with a heartbeat
Titles, tracks and licence stream a newline every 30s until the body is ready, so a slow service outlasts the client timeout and proxy idle limits; add a per-server timeout.
2026-09-24 10:18:03 -06:00
imSp4rkyandAntCardFr 783c8ae1c2 feat(proxies): add Control D proxy provider
Runs a loopback forwarder per region-named profile (unshackle-<region>), so
--proxy and --proxy-download can exit in different countries

Thanks to Orni_ for the original code and the test account.

Co-authored-by: AntCardFr <24798811+AntCardFR@users.noreply.github.com>
2026-09-23 13:23:50 -06:00
imSp4rky db771a13c6 fix(remote): forward dl track selection and profile to remote sessions
Remote sessions now carry -l/-vl/-al/-a/-fs under a nested dl_params, so services fetch the requested audio versions. Server-account tokens for non-default accounts move from default to the account name, so each account logs in once after upgrade.
2026-09-22 12:52:05 -06:00
imSp4rky 4639d9d496 fix(remote): let the server's CDM mapping decide the DRM system under server_cdm
A client with a local PlayReady device asked the server for a PlayReady licence on a service the server maps to a Widevine device. Both server_cdm routes now share one candidate list from one config lookup, report the system that licensed in drm_type, and the client adopts it.
2026-09-22 10:54:31 -06:00
imSp4rky cd6a38aec8 fix(remote): stop warning about missing keys for tracks that carry no DRM
The server names the clear tracks in the licence response and the client skips them instead of warning for every requested track without keys.
2026-09-19 22:05:30 -06:00
imSp4rky 9c9e059e2d fix(remote): forward nested service cache files to and from the server
Cache keys are now the path relative to the service cache dir without .json, so Cacher keys like session_web/<sha1> reach the remote session. The credential filter runs on every path segment, the suffix is appended rather than substituted, and both sides cap the map at 64 keys.
2026-09-19 21:42:01 -06:00
imSp4rky cf2906f120 fix(cli): make the click param types the one source of codec spellings
--acodec now lists its codecs in --help, --vcodec drops the duplicate entries, and the REST API derives its allowlists from the same types, so AC-4, DDP, VORB and sub_format "original" stop being rejected and H264 stops being silently dropped. Adds shell completion for --acodec and repairs MultipleChoice completion. Raises the click floor to 8.2.
2026-09-17 19:22:19 -06:00
imSp4rky ffda836442 fix(remote): return session cache for device-code and cache-only logins
Answered login prompts and uploaded cache now count as client auth; the client closes on exit and keeps the remote session alive during long downloads.
2026-09-16 19:36:31 -06:00
imSp4rky aec45e30cc feat(service): add GEOBLOCK negative geofence
Regions in GEOBLOCK refuse the service and everything else is allowed. A hit stops the run with a region error instead of auto-proxying; the check also covers proxy exits and the remote-dl client region.
2026-09-16 15:06:43 -06:00
imSp4rky aa36d4c225 feat(vaults): report bad keys to the vault that served them 2026-09-13 20:46:38 -06:00
imSp4rky a0515f8d57 feat(dl): add --proxy-download for a separate download proxy
Manifest, licence and auth stay on --proxy; track, subtitle and attachment downloads use the second proxy. Also exposed as proxy_download on the REST download job with the same server_proxy gate. The download session now ignores HTTP(S)_PROXY and copies rnet cookies set by name.
2026-09-13 14:41:01 -06:00
imSp4rky e40421a855 fix(serve): defer service hot reload while a remote session uses it
Remote-only serve no longer builds the download queue manager just to read busy services.
2026-09-13 12:21:31 -06:00