mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 12:05:07 +00:00
feat(dl): add --cdm to pin one CDM device for a run
Overrides the cdm config mapping (and its quality/DRM sub-entries) for the whole run; the REST API cdm field now flows through the same param.
This commit is contained in:
@@ -186,6 +186,7 @@ order the service used, then renumbers the episodes into the order you asked for
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--cdm-only` / `--vaults-only` | Use only the CDM, or only Key Vaults, for key acquisition. |
|
||||
| `--cdm <name>` | Use the named CDM device from the `cdm` config mapping for this run, ignoring the service/default mapping. |
|
||||
| `--skip-dl` | Skip the download but still retrieve keys. |
|
||||
| `--export` | Export track info and keys to a JSON file in the exports directory. |
|
||||
|
||||
|
||||
@@ -751,6 +751,7 @@ By default, unshackle checks your **key vaults** first and only asks a **CDM** t
|
||||
a content key when the vault misses. You can force one side or the other:
|
||||
|
||||
- `--cdm-only`: only use the CDM (skip vaults).
|
||||
- `--cdm <name>`: use the named CDM device for this run, ignoring the `cdm` config mapping (including its quality and Widevine/PlayReady sub-entries).
|
||||
- `--vaults-only`: only use key vaults and never license through the CDM. A missing
|
||||
content key fails.
|
||||
|
||||
@@ -945,6 +946,7 @@ authoritative list.
|
||||
| `--workers` / `--downloads` / `--slow` | | Concurrency and pacing. |
|
||||
| `--list` / `--list-titles` / `--skip-dl` | | Dry runs. |
|
||||
| `--cdm-only` / `--vaults-only` | | Content key source control. |
|
||||
| `--cdm <name>` | | Pin one CDM device, bypassing the `cdm` config mapping. |
|
||||
| `--export` | | Export track info and keys to JSON. |
|
||||
| `--tmdb` / `--imdb` / `--tvdb` / `--anilist` / `--enrich` | | Metadata overrides. |
|
||||
| `--tvdb-order` | | Renumber episodes to a TVDB season order. |
|
||||
|
||||
@@ -498,6 +498,7 @@ control this trade-off on the `dl` command:
|
||||
|------|--------|
|
||||
| `--vaults-only` | Never send a license request; use only cached/vault keys. Fails if a content key is missing. |
|
||||
| `--cdm-only` | Ignore vaults for sourcing keys and always perform a fresh license request. |
|
||||
| `--cdm <name>` | Use the named CDM device for this run instead of the one the `cdm` config maps for the service. |
|
||||
|
||||
See [key vaults](vaults.md) for how to configure vault backends.
|
||||
|
||||
|
||||
@@ -9,8 +9,9 @@ the [DRM & CDM guide](../../guide/drm-and-cdm.md). Device files themselves live
|
||||
- **Type:** `dict` · **Default:** `{}`
|
||||
|
||||
Maps a service tag to the CDM (Widevine/PlayReady device) to use, with a `default` fallback.
|
||||
Resolution is case-insensitive: a per-request API override wins, then the per-service entry,
|
||||
then `default`.
|
||||
Resolution is case-insensitive: an override (`dl --cdm <name>`, or the `cdm` field of an API
|
||||
job) wins, then the per-service entry, then `default`. An override pins one device for the whole
|
||||
run and skips any quality or Widevine/PlayReady sub-entries.
|
||||
|
||||
```yaml
|
||||
cdm:
|
||||
|
||||
@@ -833,6 +833,13 @@ class dl:
|
||||
default=None,
|
||||
help="Only use CDM, or only use Key Vaults for retrieval of Decryption Keys.",
|
||||
)
|
||||
@click.option(
|
||||
"--cdm",
|
||||
"cdm_name",
|
||||
type=str,
|
||||
default=None,
|
||||
help="Use this CDM device for the run, overriding the cdm config mapping.",
|
||||
)
|
||||
@click.option("--no-proxy", is_flag=True, default=False, help="Force disable all proxy use.")
|
||||
@click.option(
|
||||
"--no-proxy-download",
|
||||
@@ -1201,6 +1208,7 @@ class dl:
|
||||
f"Applied service-specific '{config_key}' overrides for {self.service}: {override_value}"
|
||||
)
|
||||
|
||||
self.cdm_override = ctx.params.get("cdm_name")
|
||||
cdm_only = ctx.params.get("cdm_only")
|
||||
|
||||
if cdm_only:
|
||||
@@ -1504,6 +1512,8 @@ class dl:
|
||||
self.service_anime = bool(getattr(service, "ANIME", False))
|
||||
self.service_daily = bool(getattr(service, "DAILY", False))
|
||||
self.server_cdm = getattr(service, "_server_cdm", False)
|
||||
if self.server_cdm and self.cdm_override:
|
||||
self.log.warning("--cdm is ignored: this remote service licenses with the server CDM")
|
||||
self._remote_service = service if hasattr(service, "_server_cdm") else None
|
||||
start_time = time.time()
|
||||
|
||||
|
||||
@@ -440,6 +440,7 @@ def perform_download(
|
||||
"no_proxy": params.get("no_proxy", False),
|
||||
"no_proxy_download": params.get("no_proxy_download", False),
|
||||
"profile": params.get("profile"),
|
||||
"cdm_name": params.get("cdm"),
|
||||
"repack": params.get("repack", False),
|
||||
"tag": params.get("tag"),
|
||||
"tmdb_id": params.get("tmdb_id"),
|
||||
@@ -484,10 +485,6 @@ def perform_download(
|
||||
daily=params.get("daily", False),
|
||||
output_dir=Path(params["output_dir"]) if params.get("output_dir") else None,
|
||||
)
|
||||
# Per-request CDM override (a device name in the WVDs dir); get_cdm() takes it first.
|
||||
if params.get("cdm"):
|
||||
dl_instance.cdm_override = params["cdm"]
|
||||
|
||||
# Per-request credential ("user:pass"); feed it into the map get_credentials() reads so a
|
||||
# client can authenticate without anything being persisted to disk. Without a profile,
|
||||
# get_credentials() falls back to "default", so store it there too rather than dropping it
|
||||
|
||||
@@ -757,6 +757,9 @@ async def download(request: web.Request) -> web.Response:
|
||||
cdm_only:
|
||||
type: boolean
|
||||
description: Only use CDM for content key retrieval (true) or only vaults (false) (default - None)
|
||||
cdm:
|
||||
type: string
|
||||
description: CDM device name on the server to license with, overriding the cdm config mapping. Requires serve.cdm_overrides to allow it (default - None)
|
||||
proxy:
|
||||
type: string
|
||||
description: Proxy URI or country code (default - None)
|
||||
|
||||
Reference in New Issue
Block a user