docs: apply simplified technical english across docs and docstrings.

This commit is contained in:
imSp4rky
2026-08-19 16:31:06 -06:00
parent 4177cb2267
commit 66971230c3
135 changed files with 2651 additions and 2570 deletions
+25 -25
View File
@@ -1,13 +1,13 @@
# The Configuration File
Almost everything about how unshackle behaves is controlled by a single YAML file named `unshackle.yaml`: where it saves downloads, which CDM it uses, your credentials, proxies, filename templates, and more. This page covers where that file lives, how unshackle finds it, the shape of its contents, the directory layout unshackle builds around it, and how to edit values from the command line.
A single configuration file named `unshackle.yaml` controls almost everything about how unshackle behaves. It sets where unshackle saves downloads, which CDM it uses, your credentials, proxies, filename templates, and more. This page gives where that file lives, how unshackle finds it, and the shape of its contents. It also gives the directory layout unshackle makes around it, and how to edit values from the command line.
!!! note "Where the exhaustive key list lives"
This page is an overview. For the complete, key-by-key breakdown of every setting, its type, and its default, see the [Configuration Reference](../reference/configuration/index.md).
## The config filename
The main configuration file is always named `unshackle.yaml`. It is a plain YAML file. You can open and edit it in any text editor, or manage individual values with the [`unshackle cfg`](#editing-the-config-with-unshackle-cfg) command.
The main configuration file is always named `unshackle.yaml`. It uses plain YAML. You can open and edit it in any text editor, or manage individual values with the [`unshackle cfg`](#editing-the-config-with-unshackle-cfg) command.
If you have never created one, that is fine: unshackle runs entirely on built-in defaults when no config file exists. The file only needs to contain the keys you want to change from their defaults.
@@ -42,13 +42,13 @@ The third location, your per-user config directory, is the recommended place for
```
!!! tip "Not sure which file is being used?"
Run `unshackle env info`. It prints the path the config was loaded from (or tells you none was found), along with every directory unshackle is currently using.
Operate `unshackle env info`. It prints the path unshackle loaded the config from, or tells you that it found none. It also prints every directory unshackle currently uses.
The config is read exactly once, when unshackle starts. If you edit the file, the change takes effect on the next command you run.
The config is read exactly once, when unshackle starts. If you edit the file, the change takes effect on the next command.
## Top-level structure
`unshackle.yaml` is a flat map of top-level keys. Each key configures one area of the program. You only include the keys you want to change; everything else falls back to its default.
`unshackle.yaml` is a flat map of top-level config keys. Each config key configures one area of the program. You include only the config keys you want to change. Everything else falls back to its default.
Here is a small, realistic example that sets a download location, a release tag, a default CDM, and one service's credentials:
@@ -93,14 +93,14 @@ The top-level keys group loosely into these areas:
For the full list with types and defaults, see the [Configuration Reference](../reference/configuration/index.md).
!!! warning "Unknown keys are silently ignored"
unshackle does not validate your config against a schema. If you misspell a key, it is simply skipped and the default is used. You will not get an error. Double-check key names (and their nesting) if a setting does not seem to apply.
unshackle does not validate your config against a schema. If you misspell a config key, unshackle skips it and uses the default. You will not get an error. Examine the config key names (and their nesting) if a setting does not seem to apply.
## Setting download defaults (`dl:`)
If you always pass the same `dl` flags (a language, a resolution, a codec), put them under a
`dl:` key once and unshackle applies them to every download. Any flag from
[Downloading](../guide/downloading.md) works here; the key is the flag's long name with dashes
turned into underscores (`--best-available` → `best_available`).
`dl:` config key once and unshackle applies them to every download. Any flag from
[Downloading](../guide/downloading.md) works here. The config key is the flag's long name with
dashes turned into underscores (`--best-available` → `best_available`).
```yaml title="unshackle.yaml"
dl:
@@ -111,7 +111,7 @@ dl:
downloads: 2 # two tracks at once
```
You can still override any of these on the command line for a one-off; an explicit flag
You can still override any of these on the command line for a one-off. An explicit flag
always beats the config default. You can also scope defaults to a single service by nesting a
`dl:` block under it:
@@ -128,11 +128,11 @@ services:
Most keys are obvious, but set these exact ones: `range` (`-r`), `list` (`--list`),
`tmdb_id` (`--tmdb`), `imdb_id` (`--imdb`), `tvdb_id` (`--tvdb`), `no_atmos` (`--noatmos`), and `output_dir`
(`-o`). The [Configuration Reference](../reference/configuration/download.md#dl) has the full list
and every available key.
and every available config key.
## The directory layout
The `directories` key controls where unshackle reads and writes its various files. Each directory has a sensible default, and you can override most of them by giving a new path. Paths support `~` for your home directory.
The `directories` config key controls where unshackle reads and writes its various files. Each directory has a sensible default, and you can override most of them by giving a new path. A path can use `~` for your home directory.
```yaml title="unshackle.yaml"
directories:
@@ -160,11 +160,11 @@ The directories unshackle uses:
| `fonts` | Bundled fonts | Yes |
!!! note "Some directories cannot be moved"
unshackle protects five internal entries: `app_dirs`, `core_dir`, `namespace_dir`, `user_configs`, and `data`. If you list any of them under `directories`, unshackle ignores the override. This is intentional; those paths are tied to where the package is installed.
unshackle protects five internal entries: `app_dirs`, `core_dir`, `namespace_dir`, `user_configs`, and `data`. If you write any of them under `directories`, unshackle ignores the override. This is intentional. Those paths come from the package location and your OS user directories.
### The `services` directory is special
Unlike the other entries, `services` is a **list**, and each entry can be either a local folder or a remote repository. This lets you mix your own local service code with services pulled from Git:
Unlike the other entries, `services` is a **list**, and each entry can be either a local folder or a remote repository. This lets you mix your own local services with services pulled from Git:
```yaml title="unshackle.yaml"
directories:
@@ -174,31 +174,31 @@ directories:
- ~/code/local-services # a local folder
```
unshackle searches entries in the order listed, and **the first source to define a given service tag wins**, so put local folders last if you want them to act as fallbacks rather than overrides. unshackle clones remote repositories on first use and refreshes them at most once a day. See [Creating a Service](../dev/creating-a-service.md) for how service discovery and repositories work.
unshackle examines the entries in the order you wrote them, and **the first source to define a given service tag wins**. Put local folders last if you want them to act as fallbacks and not overrides. unshackle clones remote repositories on first use and refreshes them at most once a day. See [Creating a Service](../dev/creating-a-service.md) for how service discovery and repositories work.
## The `filenames` key
## The `filenames` config key
Alongside `directories`, the `filenames` key lets you override the templates unshackle uses when naming its own working and log files (for example the log filename or the temporary chapters file). Most users never need to touch this. The available names and their default templates are listed in the [Configuration Reference](../reference/configuration/directories.md#filenames).
Alongside `directories`, the `filenames` config key lets you override the templates unshackle uses when it names its own working and log files. Two examples are the log filename and the temporary chapters file. Most users never need to touch this. The [Configuration Reference](../reference/configuration/directories.md#filenames) gives the available names and their default templates.
## Editing the config with `unshackle cfg`
You do not have to edit `unshackle.yaml` by hand. The `unshackle cfg` command reads and writes individual values for you, creating the config file (and its parent directory) if it does not exist yet.
**Read a single value** by passing its key. Nested keys use dot notation:
**Read a single value** by passing its config key. Nested config keys use dot notation:
```console
$ unshackle cfg tag
$ unshackle cfg cdm.default
```
**Set a value** by passing a key and a value:
**Set a value** by passing a config key and a value:
```console
$ unshackle cfg tag MYGRP
$ unshackle cfg cdm.default my_device_l3
```
unshackle parses the value as a Python literal, so write booleans as `True`/`False` and quote the strings inside a list (`"['en']"`). Anything that is not valid Python literal syntax is stored as a plain string:
unshackle parses the value as a Python literal, so write booleans as `True`/`False` and quote the strings inside a list (`"['en']"`). unshackle stores anything that is not valid Python literal syntax as a plain string:
```console
$ unshackle cfg update_checks False
@@ -211,19 +211,19 @@ $ unshackle cfg vault_timeout 30
$ unshackle cfg cdm.default --unset
```
**List everything** currently set with `--list`:
**Show everything** currently set with `--list`:
```console
$ unshackle cfg --list
```
When it writes, `unshackle cfg` targets the config file that was loaded. If none exists yet, it creates `unshackle.yaml` inside the `unshackle` package folder (search location 1), not your OS user-config directory. To keep the config outside the package, create the file at the user-config path yourself first, then `unshackle cfg` writes to it.
When it writes, `unshackle cfg` targets the config file that unshackle loaded. If none exists yet, it makes `unshackle.yaml` inside the `unshackle` package folder (location 1 above), not your OS user-config directory. To keep the config outside the package, make the file at the user-config path yourself first, then `unshackle cfg` writes to it.
!!! warning "Editing with `cfg` strips comments"
Because `unshackle cfg` rewrites the whole file when it saves, any comments in `unshackle.yaml` are removed by a write. If you keep important notes as comments, edit the file by hand instead, or keep those notes elsewhere.
Because `unshackle cfg` rewrites the whole file when it saves, a write removes any comments in `unshackle.yaml`. If you keep important notes as comments, edit the file by hand instead, or keep those notes elsewhere.
## Next steps
- Browse the [Configuration Reference](../reference/configuration/index.md) for every key and default.
- Browse the [Configuration Reference](../reference/configuration/index.md) for every config key and default.
- Set up your first download in [Downloading](../guide/downloading.md).
- Learn how services are discovered and updated in [Creating a Service](../dev/creating-a-service.md).
- Learn how unshackle discovers and updates services in [Creating a Service](../dev/creating-a-service.md).
+21 -21
View File
@@ -24,18 +24,18 @@ version it needs, and the external command-line tools it expects to find on your
| [dovi_tool](https://github.com/quietvoid/dovi_tool) | ≥ 2.1 | Dolby Vision handling |
| [SubtitleEdit](https://github.com/SubtitleEdit/subtitleedit/releases) | ≥ 5.0 | Subtitle conversion (optional) |
The sections below explain each of these and how to confirm your setup is
complete.
The sections below tell you about each of these, and how to make sure that your
setup is complete.
## Python version support
## Python versions
unshackle requires **Python 3.11 or newer, up to and including 3.14**
(`requires-python = ">=3.11,<3.15"`). Anything older than 3.11 or 3.15 and
later is unsupported and the installer will refuse to build the environment.
later is unsupported, and the installer refuses to assemble the environment.
You do not usually need to install a matching Python interpreter by hand, since
`uv` can download and manage one for you. If you are working inside an existing
virtual environment, make sure it is on a supported version.
`uv` can download and manage one for you. If you work inside an existing
virtual environment, make sure that it is on a supported version.
## Installing with uv
@@ -54,14 +54,14 @@ unshackle --help
```
!!! tip "Upgrading and removing"
Because it is installed from a git URL, re-run the same
`uv tool install` command (uv will update in place) to pull a newer build,
Because you installed it from a git URL, re-run the same
`uv tool install` command (uv will update in place) to get a newer version,
and use `uv tool uninstall unshackle` to remove it.
### Running from a clone
If you would rather work from a checkout of the repository (for example to try
an in-development branch or to keep local service code alongside unshackle), use
an in-development branch or to keep your own local services alongside unshackle), use
`uv run` inside the clone. This keeps the project's virtual environment active
for the duration of the command, so you do not have to activate it yourself.
@@ -71,8 +71,8 @@ cd unshackle
uv run unshackle --help
```
Every command shown elsewhere in these docs works the same way from a clone,
just prefix it with `uv run`:
Every command shown elsewhere in these docs works the same way from a clone.
Prefix it with `uv run`:
```shell
uv run unshackle env check
@@ -81,7 +81,7 @@ uv run unshackle env check
!!! note "Developer note"
Contributors will also want the development and test dependency groups. The
project defines `dev` (linters, type checkers) and `test` (pytest and
friends) groups in `pyproject.toml`; install them with
friends) groups in `pyproject.toml`. Install them with
`uv sync --group dev --group test` inside the clone. End users can ignore
these entirely.
@@ -109,12 +109,12 @@ These must be present for core downloading, decryption, and muxing to work:
unshackle decrypts with shaka-packager unless you explicitly configure a
different decryptor. If it is missing, protected downloads will fail at the
decryption step. See the [configuration reference](../reference/configuration/drm.md#decryption) for the
`decryption` key if you want to switch to `mp4decrypt`.
`decryption` config key if you want to switch to `mp4decrypt`.
### Recommended and optional tools
These extend unshackle's capabilities. Install the ones relevant to what you
download. For example, `dovi_tool` only matters if you handle Dolby Vision.
download. For example, `dovi_tool` only matters if you download Dolby Vision video.
| Tool | Binary looked up | Why it is needed |
| --- | --- | --- |
@@ -138,10 +138,10 @@ download. For example, `dovi_tool` only matters if you handle Dolby Vision.
## Verifying your installation
After installing, confirm the command runs and that unshackle can see the tools
it depends on.
After installation, make sure that the command works and that unshackle can see
the tools it depends on.
### Confirm the command is available
### Make sure the command is available
```shell
unshackle --help
@@ -150,9 +150,9 @@ unshackle --help
This prints the list of available commands (`dl`, `env`, `kv`,
`serve`, `wvd`, `prd`, `search`, `util`, `cfg`, `import`). If your shell reports
that `unshackle` is not found, the `uv tool` bin directory is probably not on
your `PATH`. Run `uv tool update-shell` and open a new terminal.
your `PATH`. Operate `uv tool update-shell` and open a new terminal.
### Check external dependencies
### Examine the external dependencies
The `env check` subcommand inspects your environment and reports which tools it
found:
@@ -187,10 +187,10 @@ unshackle env info
```
If no configuration file exists yet, this command lists the locations unshackle
searches for one, so you know where to create it. See the
searches for one, so you know where to make it. See the
[configuration guide](configuration-file.md) for the details of that file.
## Next steps
- Set up your [configuration](configuration-file.md) file (`unshackle.yaml`).
- Start [downloading](../guide/downloading.md) content once your tools check out.
- Start [downloading](../guide/downloading.md) titles when `env check` finds every required tool.
+43 -39
View File
@@ -1,8 +1,8 @@
# Quick Start
This page takes you from a fresh install to your first downloaded file. You will
create the one piece of configuration unshackle insists on, supply the service
module and CDM it needs to fetch and decrypt media, run a basic `unshackle dl`
make the one piece of configuration unshackle insists on, supply the service
module and CDM it needs to fetch and decrypt media, operate a basic `unshackle dl`
command, and learn where the finished file lands.
!!! note "Before you start"
@@ -16,11 +16,11 @@ command, and learn where the finished file lands.
([step 3](#3-write-a-service)). `EXAMPLE` in this guide stands in for the tag you
give yours.
## 1. Check your environment
## 1. Examine your environment
unshackle drives several external tools (FFmpeg, MKVToolNix, shaka-packager, and
others) to decrypt, repack, and mux media. Confirm they are visible before you
download anything:
others) to decrypt, repack, and mux media. Make sure that they are visible before
you download anything:
```shell
unshackle env check
@@ -35,16 +35,18 @@ matter for the features that use them.
The summary line at the bottom reports `installed/total` and lists anything
required that is still missing, so you know exactly what to install next.
## 2. Create a minimal config
## 2. Make a minimal config
unshackle reads a single YAML file named `unshackle.yaml`. To see where it looks
for that file, and where it *would* accept one if you have not made it yet, run:
unshackle reads a single configuration file named `unshackle.yaml`. To see where it
looks for that file, and where it *would* accept one if you have not made it yet,
use this command:
```shell
unshackle env info
```
If no config exists, this prints the candidate locations. In search order they are:
If no config exists, this prints the candidate locations. In the order unshackle
examines them, they are:
1. `unshackle.yaml` inside the unshackle package folder.
2. `unshackle.yaml` in that folder's parent.
@@ -52,10 +54,10 @@ If no config exists, this prints the candidate locations. In search order they a
(`~/.config/unshackle/` on Linux, `%LOCALAPPDATA%\unshackle\` on Windows,
`~/Library/Application Support/unshackle/` on macOS).
The **first** file that exists wins. Create `unshackle.yaml` in one of those
The **first** file that exists wins. Make `unshackle.yaml` in one of those
locations.
### The one key you must set
### The one config key you must set
unshackle refuses to start a download unless it knows how to name the output file.
That means `output_template` is the one setting a first run genuinely requires.
@@ -67,14 +69,14 @@ output_template:
series: "{title} {season_episode} {episode_name?} {quality} {source}"
```
Each `{variable}` is filled in from the title and the tracks you downloaded. The
full set of valid variables, including `resolution`, `video`, `audio`, `hdr`,
`edition`, `tag`, and more, is documented in [Output and Naming](../guide/output-and-naming.md).
unshackle fills in each `{variable}` from the title and the tracks you downloaded.
[Output and Naming](../guide/output-and-naming.md) gives the full set of valid
variables, including `resolution`, `video`, `audio`, `hdr`, `edition`, `tag`, and more.
!!! note "Spaces or dots?"
unshackle auto-detects your naming style from the template: if the separators
between variables are mostly spaces, it uses spaces; if they are mostly dots,
it produces scene-style `Title.S01E01.1080p` names. Write the template in the
between variables are mostly spaces, it uses spaces. If they are mostly dots,
it makes scene-style `Title.S01E01.1080p` names. Write the template in the
style you want the filenames to look.
!!! warning "Editing config from the CLI strips comments"
@@ -95,8 +97,8 @@ commands.
## 4. Add a CDM for DRM
Most streaming content is encrypted. To fetch decryption keys, unshackle needs a
**CDM**, a Widevine device (`.wvd`) or a PlayReady device (`.prd`). Register a
Most streaming services encrypt their titles. To fetch content keys, unshackle
needs a **CDM**, a Widevine device (`.wvd`) or a PlayReady device (`.prd`). Add a
Widevine device you already have with:
```shell
@@ -104,8 +106,8 @@ unshackle wvd add /path/to/device.wvd
```
This validates the file and moves it into your WVDs directory. Then point services
at it in your config. The `cdm` map is keyed by service tag, with a `default` that
covers everything else:
at it in your config. The `cdm` map uses the service tag as its config key, with a
`default` that covers everything else:
```yaml title="unshackle.yaml"
cdm:
@@ -114,20 +116,20 @@ cdm:
```
PlayReady works the same way with `.prd` files created and managed by the
[`prd`](../guide/cli-reference.md#prd) command. If a title is DRM-free, no CDM is needed.
[`prd`](../guide/cli-reference.md#prd) command. If a title is DRM-free, unshackle needs no CDM.
!!! tip
Run `unshackle wvd parse my_device` to inspect a device's security level and
contents, and `unshackle env info` to confirm where WVDs and PRDs are stored.
Operate `unshackle wvd parse my_device` to inspect a device's security level
and contents, and `unshackle env info` to show where unshackle stores WVDs and PRDs.
## 5. Provide authentication
## 5. Supply authentication
Services that require a login read either **cookies** or **credentials**.
- **Cookies**: export the service's cookies to a Netscape-format text file and
place it in your cookies directory. unshackle looks for, in order:
`cookies/{SERVICE}.txt`, then `cookies/{SERVICE}/{profile}.txt`, then
`cookies/{SERVICE}/default.txt`. So a file at `cookies/EXAMPLE.txt` is picked up
`cookies/{SERVICE}/default.txt`. So unshackle finds a file at `cookies/EXAMPLE.txt`
automatically for the `EXAMPLE` service.
- **Credentials**: store a username and password per service in your config:
@@ -143,21 +145,21 @@ depends on the service module.
## 6. Find a title (optional)
If you have a URL or ID already, skip this. Otherwise, search the service for a
title and note the `id` it prints, since that is what you feed to `dl`:
If you have a URL or ID already, skip this. Otherwise, find a title on the service
and note the `id` it prints, because that is what you feed to `dl`:
```shell
unshackle search EXAMPLE "My Show"
```
You can also list what a service exposes for a given title without downloading:
You can also show what a service gives for a given title without downloading:
```shell
unshackle dl --list-titles EXAMPLE 81234567 # show seasons/episodes
unshackle dl --list EXAMPLE 81234567 # show available tracks
```
## 7. Run your first download
## 7. Do your first download
A download always has three parts:
@@ -175,8 +177,9 @@ A good first command asks for 1080p with English audio:
unshackle dl -q 1080 -l en EXAMPLE 81234567
```
unshackle will fetch the title, select the tracks matching your flags, acquire
keys through your CDM (and any key vaults), then decrypt, mux, and tag the result.
unshackle will fetch the title, select the tracks that match your flags, and get
the content keys through your CDM (and any key vaults). It then decrypts, muxes, and
tags the result.
### Handy first flags
@@ -208,16 +211,17 @@ codec, bitrate, channel-layout, and track-type selection.
## 8. Where the output lands
By default, unshackle writes finished files to the `downloads` directory
(`unshackle env info` shows its exact path; the built-in default is a `downloads`
folder one level above the installed `unshackle` package). Override it per run with `-o`:
By default, unshackle writes finished files to the `downloads` directory.
`unshackle env info` shows its exact path. The built-in default is a `downloads`
folder one level above the installed `unshackle` package. Override it for one
command with `-o`:
```shell
unshackle dl -q 1080 -o /mnt/media/incoming EXAMPLE 81234567
```
- unshackle writes **movies** as a single `.mkv` file named from your `movies` template.
- **TV episodes** are grouped into a per-show / per-season folder (from your
- unshackle groups **TV episodes** into a per-show / per-season folder (from your
`series` template) unless you pass `--no-folder`.
- unshackle builds the filename from your `output_template` and adds IMDb/TMDB/TVDB IDs to
the file's metadata tags when available.
@@ -233,12 +237,12 @@ directories:
- **[Downloading](../guide/downloading.md)**. The full `dl` command: quality, codecs,
languages, track selection, hybrid Dolby Vision, and output control.
- **[Configuration](configuration-file.md)**. Every `unshackle.yaml` key, plus
- **[Configuration](configuration-file.md)**. Every `unshackle.yaml` config key, plus
directories, key vaults, proxies, and naming templates.
- **[REST API](../dev/rest-api/index.md)**. Run the `serve` server to drive downloads over
HTTP.
- **[REST API](../dev/rest-api/index.md)**. Operate the `serve` server to drive downloads
over HTTP.
!!! tip "You are never far from help"
`unshackle --help`, `unshackle dl --help`, and `unshackle <command> --help`
list every option. When in doubt, add `--list` to a `dl`
show every option. When in doubt, add `--list` to a `dl`
command to preview what it would do before it downloads anything.