feat(setup): add unshackle setup command and cross-platform install scripts

setup downloads the external tools, writes a first config and imports CDM devices; install.sh and install.bat bootstrap uv and run it.
This commit is contained in:
imSp4rky
2026-10-01 12:21:24 -06:00
parent fdcc653b66
commit c7ab04028a
19 changed files with 1546 additions and 166 deletions
+12 -4
View File
@@ -17,11 +17,16 @@ When unshackle starts, it searches a fixed list of locations and uses the **firs
| # | Location | Typical path |
|---|----------|--------------|
| 1 | The unshackle package folder | `.../site-packages/unshackle/unshackle.yaml` |
| 2 | The parent of the package folder | `.../site-packages/unshackle.yaml` |
| 1 | The unshackle package folder | `<clone>/unshackle/unshackle.yaml` (a `uv` tool install: `.../site-packages/unshackle/unshackle.yaml`) |
| 2 | The parent of the package folder | `<clone>/unshackle.yaml` (a `uv` tool install: `.../site-packages/unshackle.yaml`) |
| 3 | Your OS user-config directory | see the table below |
The third location, your per-user config directory, is the recommended place for most installations, because it lives outside the package and survives reinstalls and upgrades. Its exact path depends on your operating system:
Where the file belongs depends on how you installed unshackle:
- **Git clone (recommended).** Keep the file at `unshackle/unshackle.yaml` inside the clone, which is location 1. [`unshackle setup`](installation.md#what-unshackle-setup-does) writes a new config there, and it stays with the clone when you update it.
- **`uv` tool install.** Use location 3, your per-user config directory. A `uv` tool upgrade replaces the package folder, so a file at location 1 or 2 is lost. `unshackle setup` writes a new config there.
The path of the per-user config directory depends on your operating system:
=== "Linux"
@@ -217,7 +222,10 @@ $ unshackle cfg cdm.default --unset
$ unshackle cfg --list
```
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.
When it writes, `unshackle cfg` targets the config file that unshackle loaded. If none exists yet, it makes `unshackle.yaml` in the `unshackle` package folder (location 1 above):
- **Git clone.** That is `unshackle/unshackle.yaml` in the clone, which is the correct place.
- **`uv` tool install.** A tool upgrade replaces the package folder and deletes that file. Run `unshackle setup` first, which writes the config to your user config directory, or make the file there yourself. Then `unshackle cfg` writes to it.
!!! warning "Editing with `cfg` strips comments"
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.
+199 -61
View File
@@ -2,15 +2,139 @@
unshackle is a modular archival tool for movies, TV, and music. It ships as a
single Python package named `unshackle` that installs one console command, also
called `unshackle`. This page covers installing that command, the Python
version it needs, and the external command-line tools it expects to find on your
`PATH`.
called `unshackle`. This page covers the install script, the `unshackle setup`
command, the Python version unshackle needs, and the external command-line tools
it expects to find.
!!! note "What you get"
Installing the package registers a single entry point, the `unshackle`
command. It covers everything: downloading, key-vault management, device
provisioning, the REST server, and the helper utilities.
## Install from a git clone (recommended)
A git clone with the install script is the recommended way to install unshackle.
A clone keeps unshackle, its external tools, its config, its data folders, and
your services together in one folder that you can see.
The repository has an install script for Linux (`install.sh`) and for Windows
(`install.bat`). The script installs `uv` if it is not found, installs unshackle,
and then runs [`unshackle setup`](#what-unshackle-setup-does).
=== "Linux"
```shell
git clone https://github.com/unshackle-dl/unshackle.git
cd unshackle
sh install.sh
```
=== "Windows"
```bat
git clone https://github.com/unshackle-dl/unshackle.git
cd unshackle
.\install.bat
```
In a clone, the script runs `uv sync` and then `uv run unshackle setup`. The last
lines of setup tell you to check your tools with `uv run unshackle env check`.
Run unshackle from the clone with `uv run unshackle ...`.
To install without a clone, see
[Advanced: install as a uv tool](#advanced-install-as-a-uv-tool).
## What `unshackle setup` does
`unshackle setup` prepares a new installation. The install script runs it for
you, and you can run it yourself at any time:
=== "From a clone"
```shell
uv run unshackle setup
```
=== "Installed as a uv tool"
```shell
unshackle setup
```
The command does these steps:
1. It shows which [external tools](#external-tools-on-your-path) are missing,
and where to get the ones that it cannot download.
2. It asks once for each tool or group of tools to download. The required
tools come first. shaka-packager and `mp4decrypt` share one DRM question, so
`mp4decrypt` comes with the required tools, but `env check` still shows it
as optional. The HDR and subtitle groups are optional. The prompts show the
version that setup downloads. On Windows, the subtitle question also shows
the download size of CCExtractor, which is much larger than the other tools.
It puts the downloads in a `binaries` folder
(see [Where setup puts files](#where-setup-puts-files)).
3. If no `unshackle.yaml` exists, it asks for a downloads folder and writes a
minimal config file.
4. It makes the data folders for cookies, WVDs, PRDs, and services.
5. It asks for `.wvd` and `.prd` devices to import. You can give a file or a
folder of devices, and it asks again until you give an empty answer. It
validates each file, copies it into the WVDs or PRDs folder, and prints one
line for each file. If setup wrote a new config in this run, it sets
`cdm.default` to the imported device. If you imported more than one, it
asks which one is the default.
6. It prints a summary of the tools that it found. If it wrote a config, it
gives the path of that config and a link to the
[configuration reference](../reference/configuration/index.md). Then it
tells you to run `env check` next.
You can run the command again. It skips the tools that it finds and never
overwrites an existing config.
!!! note "Not every tool has a download"
Setup downloads tools only on Linux and Windows, and only when the tool
has a portable build for your system. For other tools, setup prints where
to get them, for example a package manager. On macOS, setup downloads
nothing and prints these links for each missing tool.
On Linux, setup cannot download MKVToolNix, which is a required tool.
Install the `mkvtoolnix` package with your package manager (for example
`apt`, `dnf`, or `pacman`).
!!! warning "CCExtractor on Linux needs FUSE"
On Linux, setup downloads CCExtractor as an AppImage, which needs FUSE to
run. Setup runs the AppImage once after the download. If it does not run, setup removes it and prints the
manual install link. Install FUSE with your package manager and run setup
again, or install the `ccextractor` package instead.
### Where setup puts files
| Item | From a git clone | From a `uv` tool install |
| --- | --- | --- |
| External tools | `unshackle/binaries` in the clone | `binaries` in the user data directory |
| New config (`unshackle.yaml`) | `unshackle/unshackle.yaml` in the clone | The user config directory |
| Data folders (cookies, WVDs, PRDs, cache, logs, services, temp) | The default folders in the clone | The user data directory |
| Downloads | The folder that you give at the prompt | The folder that you give at the prompt |
On Windows, CCExtractor and its libraries go into their own `ccextractor`
subfolder of the tools folder.
On Linux, the user data directory is usually `~/.local/share/unshackle` and the
user config directory is usually `~/.config/unshackle`. On Windows, both are
`%LOCALAPPDATA%\unshackle`. Run `uv run unshackle env info` to see the paths that
unshackle uses. Its `User_Binaries` row shows the `binaries` folder in the user
data directory.
Setup writes a new config only when it finds no `unshackle.yaml` in any of the
[config locations](configuration-file.md). It keeps an existing config where it
is. In a clone, the new config sets only `directories.downloads`, so the data
folders stay at their defaults in the clone.
A `uv` tool upgrade replaces the package folder. For a `uv` tool install, setup
puts the tools in the user data directory and writes a `directories` block that
moves the data folders there, so an upgrade keeps them. If an existing config
keeps data folders inside the package of a `uv` tool install, setup shows a
warning and prints the `directories` lines to add.
## Requirements at a glance
| Requirement | Recommended version | Needed for |
@@ -37,38 +161,22 @@ You do not usually need to install a matching Python interpreter by hand, since
`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
## Installing by hand
The recommended way to install unshackle is as a `uv` tool. This creates an
isolated environment for the package and puts the `unshackle` command on your
`PATH` without touching your system Python.
```shell title="Install as a uv tool"
uv tool install git+https://github.com/unshackle-dl/unshackle.git
```
Once it finishes, the `unshackle` command is available globally:
```shell
unshackle --help
```
!!! tip "Upgrading and removing"
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.
If you do not use the install script, install unshackle with `uv` and then run
`unshackle setup`, or install the [external tools](#external-tools-on-your-path)
yourself.
### 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 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.
Use `uv run` inside the clone. It keeps the project's virtual environment active
for the duration of the command, so you do not have to activate it yourself. It
also installs the dependencies on the first run.
```shell title="Run from a git clone"
git clone https://github.com/unshackle-dl/unshackle.git
cd unshackle
uv run unshackle --help
uv run unshackle setup
```
Every command shown elsewhere in these docs works the same way from a clone.
@@ -78,6 +186,38 @@ Prefix it with `uv run`:
uv run unshackle env check
```
### Advanced: install as a uv tool
This way is for users who know `uv` tools and want the `unshackle` command on
their `PATH` without a clone.
!!! note "Where a uv tool install keeps files"
`uv tool install` puts unshackle into the tool folder of `uv`, not into a
folder that you choose. `unshackle setup` therefore puts the external
tools, the config, and the data folders in your user data and config
directories (see [Where setup puts files](#where-setup-puts-files)). A git
clone is the easier setup: its tools, config, data, and services stay in
one folder that you can see. On the first run from a `uv` tool install,
`unshackle setup` tells you this and asks if you want to continue.
Install the tool and run setup:
```shell title="Install as a uv tool"
uv tool install git+https://github.com/unshackle-dl/unshackle.git
unshackle setup
```
The install scripts also do this when you run one alone, without a clone: when
the script does not find the unshackle `pyproject.toml` next to it, it runs
`uv tool install` and then `unshackle setup`. When it finishes, it tells you to
open a new terminal, because the `PATH` change only applies to new terminals.
Run `unshackle env check` there.
!!! tip "Upgrading and removing"
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.
!!! note "Developer note"
Contributors will also want the development and test dependency groups. The
project defines `dev` (linters, type checkers) and `test` (pytest and
@@ -89,9 +229,13 @@ uv run unshackle env check
unshackle shells out to a number of external command-line programs for media
processing and DRM work. It looks for each one first in the `binaries/` folder
inside the installed package, and then falls back to your system `PATH`, so
installing these tools system-wide (or dropping them into that folder) both
work.
inside the installed package, then in the `binaries` folder of your user data
directory, and then on your system `PATH`. `unshackle setup` installs tools into
the first folder in a clone and into the second for a `uv` tool install. Installing a tool system-wide or putting it into one of those folders
both work.
`unshackle setup` installs the required tools and some optional ones for you.
Use the tables below when you install a tool by hand.
### Required tools
@@ -128,7 +272,7 @@ download. For example, `dovi_tool` only matters if you download Dolby Vision vid
| dovi_tool | `dovi_tool` | Dolby Vision metadata handling |
| HDR10Plus_tool | `hdr10plus_tool` | HDR10+ metadata handling |
| SubtitleEdit | `seconv`, `SubtitleEdit` | Subtitle conversion (the `SeConv` CLI from 5.x) |
| CCExtractor | `ccextractor` | Extracting closed captions |
| CCExtractor | `ccextractor`, `ccextractorwin`, `ccextractorwinfull` | Extracting closed captions |
| FFplay | `ffplay` | Simple preview player |
| MPV | `mpv` | Advanced preview player (used by `util crop`/`util range` previews) |
| HolaProxy | `hola-proxy` | Hola proxy provider support |
@@ -148,35 +292,12 @@ download. For example, `dovi_tool` only matters if you download Dolby Vision vid
## Verifying your installation
After installation, make sure that the command works and that unshackle can see
the tools it depends on.
### Make sure the command is available
```shell
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`. Operate `uv tool update-shell` and open a new terminal.
After installation, make sure that unshackle can see the tools it depends on.
### Examine the external dependencies
The `env check` subcommand inspects your environment and reports which tools it
found:
```shell
unshackle env check
```
=== "Output"
It prints a table grouped by category (Core, DRM, HDR, Subtitle, Player,
Network) with a status column: a green check for tools that resolved and a
red cross for those it could not find, plus a summary line such as
`All required tools installed ✓` or `Missing required: <names>`.
The `env check` subcommand is the first check. It inspects your environment and
reports which tools it found:
=== "From a clone"
@@ -184,8 +305,24 @@ unshackle env check
uv run unshackle env check
```
If a required tool shows as missing, install it and put it on your `PATH` (or in
the package's `binaries/` folder), then re-run the check.
=== "Installed as a uv tool"
```shell
unshackle env check
```
It prints a table grouped by category (Core, DRM, HDR, Subtitle, Player,
Network) with a status column: a green check for tools that resolved and a red
cross for those it could not find, plus a summary line such as
`All required tools installed ✓` or `Missing required: <names>`.
If a required tool shows as missing, `env check` tells you to run
`unshackle setup`. You can also install the tool by hand and put it on your
`PATH` (or in one of the `binaries` folders), then re-run the check.
!!! tip "`unshackle` is not found after a uv tool install"
The bin directory of `uv` tools is probably not on your `PATH`. Run
`uv tool update-shell` and open a new terminal.
### Inspect environment paths
@@ -193,7 +330,7 @@ To see where unshackle will read its configuration from and where it stores
downloads, caches, cookies, and devices, use:
```shell
unshackle env info
uv run unshackle env info
```
If no configuration file exists yet, this command lists the locations unshackle
@@ -202,5 +339,6 @@ searches for one, so you know where to make it. See the
## Next steps
- Set up your [configuration](configuration-file.md) file (`unshackle.yaml`).
- Set up your [configuration](configuration-file.md) file (`unshackle.yaml`), or
let `unshackle setup` write a first one.
- Start [downloading](../guide/downloading.md) titles when `env check` finds every required tool.
+38 -39
View File
@@ -6,9 +6,10 @@ module and CDM it needs to fetch and decrypt media, operate a basic `unshackle d
command, and learn where the finished file lands.
!!! note "Before you start"
This guide assumes unshackle is already installed and on your `PATH`. If
`unshackle --help` does not print a help screen, work through
[Installation](installation.md) first.
This guide assumes that you installed unshackle as
[Installation](installation.md) describes. The examples use the bare
`unshackle` command. From a git clone, the recommended install, run each
one as `uv run unshackle ...`, for example `uv run unshackle env check`.
!!! warning "unshackle includes no services"
unshackle handles manifests, DRM, downloading, and muxing. It does not include a
@@ -16,52 +17,47 @@ 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. Examine your environment
## 1. Run setup
unshackle drives several external tools (FFmpeg, MKVToolNix, shaka-packager, and
others) to decrypt, repack, and mux media. Make sure that they are visible before
you download anything:
others) to decrypt, repack, and mux media, and it needs a config file. The
`unshackle setup` command prepares both. If you used the install script, setup
has already run. You can run it again at any time:
```shell
unshackle setup
```
Setup downloads the missing required tools and, if you agree, groups of optional
tools. If no `unshackle.yaml` exists, it writes a minimal one with your downloads
folder. It also makes the data folders and lets you import `.wvd` and `.prd`
devices, one file or a whole folder at a time. [Installation](installation.md#what-unshackle-setup-does) tells you what
each step does and where the files go.
Then make sure that unshackle finds the tools:
```shell
unshackle env check
```
This prints a dependency table. The **required** tools (FFmpeg, FFprobe,
MKVToolNix, mkvpropedit, and shaka-packager) must show a green check. Optional
tools such as `dovi_tool` (Dolby Vision) and CCExtractor (closed captions) only
matter for the features that use them.
The **required** tools (FFmpeg, FFprobe, MKVToolNix, mkvpropedit, and
shaka-packager) must show a green check. Optional tools such as `dovi_tool`
(Dolby Vision) and CCExtractor (closed captions) only matter for the features
that use them.
!!! tip
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.
!!! note "Set up by hand"
To do these steps yourself, install the tools from the tables in
[Installation](installation.md#external-tools-on-your-path). Then run
`unshackle env info` to see where unshackle looks for `unshackle.yaml`, and
make the file in one of those locations. The
[configuration guide](configuration-file.md) gives the details.
## 2. Make a minimal config
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 the order unshackle
examines them, they are:
1. `unshackle.yaml` inside the unshackle package folder.
2. `unshackle.yaml` in that folder's parent.
3. `unshackle.yaml` in your OS user-config directory
(`~/.config/unshackle/` on Linux, `%LOCALAPPDATA%\unshackle\` on Windows,
`~/Library/Application Support/unshackle/` on macOS).
The **first** file that exists wins. Make `unshackle.yaml` in one of those
locations.
### The one config key you must set
## 2. Check the output template
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.
Everything else has a sensible default. A minimal, working config looks like this:
Everything else has a sensible default. The config that setup writes copies `tag`
and `output_template` from the example config. A minimal, working config looks like this:
```yaml title="unshackle.yaml"
output_template:
@@ -98,7 +94,9 @@ commands.
## 4. Add a CDM for DRM
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
needs a **CDM**, a Widevine device (`.wvd`) or a PlayReady device (`.prd`). If you
imported devices during `unshackle setup`, they are already in place. If setup also
wrote your config, it set `cdm.default` to the device that you chose. Otherwise, add a
Widevine device you already have with:
```shell
@@ -217,7 +215,8 @@ 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`
`unshackle env info` shows its exact path. A config from `unshackle setup` uses the
folder that you gave at its prompt. Without that setting, the default is a `downloads`
folder one level above the installed `unshackle` package. Override it for one
command with `-o`: