Commit Graph
177 Commits
Author SHA1 Message Date
imSp4rky af69e8aad4 feat(proxy): try bare --proxy providers in proxy_providers key order
Basic stays first and Control D last; the rest follow their config key order. Geofence and proxy_map lookups go through pick_proxy and skip a provider that fails.
2026-10-23 08:20:39 -06:00
imSp4rky 3e9c26bd46 refactor(config): log the duplicate-key warning without the python warning prefix 2026-10-22 20:16:35 -06:00
imSp4rky 9dd97bcd25 feat(config): warn with the lines of a duplicate key in any config load 2026-10-22 20:12:59 -06:00
imSp4rky 1ec236f61b feat(proxy): accept an @ selector as a server_map value
A value starting with - or @ applies to its region (fr: -datacamp); a value with @ after a server is a whole query (fr: fr-bod@195.86.24.103). A selector in --proxy still wins.
2026-10-22 14:03:25 -06:00
imSp4rky 4753fcd7bc feat(proxy): select a vpn server by network or ip with @
On NordVPN, Windscribe and Surfshark, `@<name>` keeps and `@-<name>` skips a hosting network; `@<ip>` and `@-<ip>` pick or skip one server. The connect line names the server, IP and network. Surfshark pins an IP through a loopback TLS port.
2026-10-22 13:53:30 -06:00
imSp4rky 0eaefcaa2b fix(proxy): name the reason when the Control D forwarder answers 502 2026-10-21 18:35:26 -06:00
imSp4rky a7e68b7d20 fix(tracks): keep a locked segment file from hiding the download error
On Windows a worker can still hold a .!dev file open when a track fails; cleanup now ignores that OSError and still stashes the segments.
2026-10-21 18:25:50 -06:00
imSp4rky e5c339934c fix(remote): send the typed --proxy to the server when it resolved to loopback
dl and search keep the typed --proxy value, so --proxy controld:ca --remote sends the server the Control D resolver, not this machine's forwarder. The Control D log names the location and masks the resolver ID in place of 127.0.0.1.
2026-10-21 11:03:10 -06:00
imSp4rky f5bd24b5e9 fix(import): take a missing title language from the exported tracks
A title with no language now takes the language of an original-language track, else a
video track, so an unlabelled MPD re-parses and -l orig works. A track that no longer
matches its manifest is dropped with a warning instead of failing at download.
2026-10-21 10:36:03 -06:00
imSp4rky 012bf45270 fix(hls): keep PlayReady session-data keys by matching the URN string 2026-10-20 20:05:03 -06:00
imSp4rky f2273b8e97 feat(dl): keep failed track segments across runs in a resume stash
Stash a failed or cancelled track's segments outside the task temp dir and restore them on the next download. Also drop a pre-sized data file with its .!dev control file.
2026-10-20 19:53:42 -06:00
imSp4rky 08a2257be3 fix(api): parse client cookies with the dl cookie parser 2026-10-20 12:46:44 -06:00
imSp4rky ef75ea7d7a feat(dl): add --local to override a remote: true service config 2026-10-19 14:25:03 -06:00
imSp4rky 3aaf9c4107 fix(services): route a service remote from services.<TAG>.dl.remote
Click picks the subcommand before the dl callback applies the service config, so Services.resolve_command now applies remote and server first. A REST API job routes from its request only.
2026-10-19 14:19:07 -06:00
imSp4rky 1a8e633fdc feat(dash): flag dv profile 8 tracks from supplementalCodecs and use hdr10+dv as the hybrid 2026-10-18 17:18:11 -06:00
imSp4rky 6fdfeb9cae test: replace real service tags and brands with generic placeholders 2026-10-18 12:17:08 -06:00
imSp4rky 768e35d905 feat(hybrid): use a dv track that carries hdr10+ as the hybrid of its resolution 2026-10-18 12:11:02 -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 811e0a19c0 feat(tracks): probe HDR10 tracks for HDR10+ SEI before selection
Relabel HEVC HDR10 tracks whose first fragment carries ST 2094-40 SEI as HDR10P, for dl, the REST API and remote sessions. Config key hdr10plus_probe (default true).
2026-10-17 18:58:48 -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 9f4625d971 fix(proxy): do not warn about requests to a configured remote CDM 2026-10-16 17:58:38 -06:00
imSp4rky bfda31ce4a fix(proxy): keep service traffic on --proxy and warn about requests that bypass it
--proxy now overrides HTTP(S)_PROXY and the Windows system proxy while keeping the env CA bundle. Core fallback sessions use the run's proxy, and a warn-only audit hook names service code that sends a request or opens a raw socket outside the proxy; a session with proxy_exempt = True opts out.
2026-10-16 16:12:42 -06:00
imSp4rky dc169f81e1 fix(vaults): stop querying sibling KIDs and skip unavailable vaults
The server CDM stub names only the manifest's KIDs; sibling keys stay content keys. API and HTTP vaults retry a 429, and a vault that is down or still rate limited costs one timeout per run.
2026-10-16 14:49:37 -06:00
imSp4rky ecb8296de8 fix(import): add decrypts_samples to ImportService 2026-10-16 09:12:02 -06:00
imSp4rky 71a0383258 fix(console): count spacing combining marks as one cell
Rich measures Indic marks like ि as zero width, so the --list panel border drifted on Hindi, Telugu and Tamil labels.
2026-10-15 17:36:04 -06:00
imSp4rky dedbf00f75 test(vaults): replace sleeps with events in the parallel retry test 2026-10-15 16:28:33 -06:00
imSp4rky 89f433963a fix(session): log "Retrying" only when a retry follows
A per-call max_retries=0 logged "Retrying... (1/0)" before raising, and the last of the default retries logged "(6/5)".
2026-10-15 14:48:20 -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 c231114cda feat(ip-info): return timezone and add a required-field filter
get_ip_info(require=...) skips a geolocation API whose result lacks a required field, so ipinfo Lite falls through to ipinfo.io or ip-api.in.
2026-10-15 10:30:21 -06:00
imSp4rky 8a1fbf2de1 feat(music): embed plain lyrics and save timed lyrics from Song.synced_lyrics 2026-10-14 12:37:43 -06:00
imSp4rky b107bca168 feat(music): save lyrics beside the audio and keep song fields over remote
Song.lyrics_suffix writes the lyrics file; song fields set in get_tracks now reach a remote client.
2026-10-14 11:04:29 -06:00
imSp4rky 9ef7a8bd06 fix(session): cap Retry-After on the requests retry policies
A server-sent Retry-After could park a run for up to six hours.
2026-10-13 19:59:14 -06:00
imSp4rky 5ff2bef550 fix(cacher): resolve cache expiry by unix time 2026-10-13 19:58:50 -06:00
imSp4rky 6b04d7b137 fix(vaults): lengthen the whole-file key check and steady its HEVC test
Wrong-key HEVC noise can decode clean for seconds in small frames, so the tail check now decodes 8 s. The test clips are 640x360 with a fixed IV.
2026-10-13 17:32:29 -06:00
imSp4rky e7bb825def perf(manifests): decode manifests without charset detection
Parse an MPD from bytes and read every M3U8 playlist as UTF-8 unless the server sent a charset. Fixes mojibake on text/* responses.
2026-10-13 16:11:13 -06:00
imSp4rky 3e64a7d684 fix(api): follow the cdm config key order for the server CDM 2026-10-13 13:40:38 -06:00
imSp4rky 2ba442f50e feat(dl): load the DRM system a cdm entry lists first
The first of the widevine / playready config keys in a cdm entry sets which device loads first and which DRM system licenses a track that offers the two. An entry that lists playready first changes from Widevine to PlayReady.
2026-10-13 12:44:11 -06:00
imSp4rky af4e6d5d47 fix(hls): read the key id from the init segment when the PSSH has none
An EXT-X-KEY whose Widevine PSSH holds a content id and no key id raised KIDNotFound. Covers download, licence-only, --all-drm, session keys, import and the server CDM path. Fixes #166.
2026-10-13 12:14:34 -06:00
imSp4rky 355df2e54f fix(import): carry the HLS segment filter in an export
An import kept the segments a service drops and failed on their key. A licence-only run now also licenses a key that starts part-way.
2026-10-08 10:38:49 -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 94e5264396 fix(cdm): send a PlayReady licence without an XML declaration as XML
A remote CDM tried base64 first on any licence not starting with "<?xml", which can decode XML text into garbage. Also lists L3 as a device_name.
2026-10-06 13:59:40 -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 9fc25e53d5 fix(hybrid): read the container file for a base that had the DV fixup
The fixup replaces a track with a raw HEVC file, which has no duration and cannot be seeked, so Level 5 crop detection raised KeyError.
2026-10-05 17:32:30 -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 9bc6f5fb58 fix(dl): keep the --enrich title and year after get_tracks
A service that sets its title again in get_tracks, as a remote session does, replaced the metadata name and year, so the file took the service's title. A song takes only the language.
2026-10-04 15:57:51 -06:00
imSp4rky 73bdb98d3e fix(console): write UTF-8 to redirected streams on Windows 2026-10-02 14:07:05 -06:00
imSp4rky 34eb94b55d fix(sanitize): normalise filenames to NFC and keep combining marks
Remove only control characters in unicode mode. A mark after a zero width joiner or a digit was still dropped (#161). In ASCII mode a decomposed title now transliterates like the composed one.

Names change for titles with combining marks, compatibility ideographs or decomposed spellings, so an existing library can get a second folder.
2026-10-02 13:22:04 -06:00
Chaloemchai 7b3794333f fix(sanitize): keep nonspacing marks on letters in unicode filenames (#162) 2026-10-02 11:56:56 -06:00