feat(metadata)!: replace animeapi with a first-class anilist provider

--anilist supersedes --animeapi (REST: anilist_id); the keyless AniList
GraphQL provider joins the registry with title search, mal: ID lookup,
an ANILIST mkv tag, and the anilist_title_language config option.
Services mark anime via Service.ANIME / Title.anime for anilist-first
metadata resolution with fall-through.
This commit is contained in:
imSp4rky
2026-08-11 16:42:05 -06:00
parent ebb4e74318
commit 72581ba5d2
24 changed files with 794 additions and 196 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ after the flag's internal destination rather than its visible name; set these ex
| `--list` | `list` |
| `--tmdb` | `tmdb_id` |
| `--imdb` | `imdb_id` |
| `--animeapi` | `animeapi_id` |
| `--anilist` | `anilist_id` |
| `-naa` / `--noatmos` | `no_atmos` |
| `-o` / `--output` | `output_dir` |
| `--cdm-only` / `--vaults-only` | `cdm_only` |
+1 -1
View File
@@ -36,7 +36,7 @@ Where the file lives, how unshackle discovers it, and how to edit it:
| [DRM & CDM](drm.md) | `cdm`, `remote_cdm`, `decryption` |
| [Network & proxy](network.md) | `network`, `headers`, `proxy_providers` |
| [Key vaults](vaults.md) | `key_vaults`, `vault_timeout` |
| [External API keys](misc.md#external-api-keys) | `omdb_api_key`, `tmdb_api_key`, `tvdb_api_key`, `tvdb_pin`, `tvdb_order`, `simkl_client_id`, `metadata_providers`, `disable_metadata`, `decrypt_labs_api_key`, `ipinfo_api_key` |
| [External API keys](misc.md#external-api-keys) | `omdb_api_key`, `tmdb_api_key`, `tvdb_api_key`, `tvdb_pin`, `tvdb_order`, `simkl_client_id`, `metadata_providers`, `anilist_title_language`, `disable_metadata`, `decrypt_labs_api_key`, `ipinfo_api_key` |
| [Caching & updates](misc.md#caching-updates) | `title_cache_enabled`, `title_cache_time`, `title_cache_max_retention`, `update_checks`, `update_check_interval` |
| [Logging, privacy & debug](misc.md#logging-privacy-debug) | `redact_paths`, `debug`, `debug_keys`, `debug_requests`, `set_terminal_bg` |
| [Deprecated & removed](misc.md#deprecated-removed-keys) | `curl_impersonate`, `downloader`, `scene_naming` |
+27 -10
View File
@@ -17,6 +17,7 @@ each metadata provider can actually answer with, see
| `tvdb_pin` | str | `""` | Subscriber PIN, only needed for a user-supported TVDB key. Leave empty for a normal project key. |
| `tvdb_order` | str | `""` | Default for `--tvdb-order`: renumber episodes to a TVDB season order (`official`, `dvd`, `absolute`, `alternate`, `regional`). Empty keeps the numbering the service gives. |
| `metadata_providers` | list or map | *(see below)* | Metadata providers to use, in the order they are tried. |
| `anilist_title_language` | str | `english` | Which AniList title variant to use: `english`, `romaji`, or `native`. |
| `disable_metadata` | bool | `false` | Set to `true` to stop all automatic metadata lookups. An ID you give yourself is still looked up. |
| `decrypt_labs_api_key` | str | `""` | Global Decrypt Labs API key (used by remote CDM / vault). |
| `ipinfo_api_key` | str | `""` | ipinfo.io API key for IP/region lookups. |
@@ -33,16 +34,32 @@ each metadata provider can actually answer with, see
ignored with a warning. Leave it unset for the default order:
```yaml
metadata_providers: [imdb, omdb, simkl, tmdb, tvdb]
metadata_providers: [imdb, omdb, simkl, tmdb, tvdb, anilist]
```
Whatever the order, a provider is skipped when its API key is missing. `imdb` needs no
key, so it is always available. Available names are `imdb`, `omdb`, `simkl`, `tmdb`, and
`tvdb`. The old name `imdbapi` still works and is read as `imdb`.
Whatever the order, unshackle skips a provider that has no API key. `imdb` and
`anilist` need no key, so they are always available. Available names are `imdb`, `omdb`,
`simkl`, `tmdb`, `tvdb`, and `anilist`. The old name `imdbapi` still works and is read as
`imdb`.
`anilist` is last in the default order. It only answers for anime and returns nothing for
anything else, so it is harmless there. Move it earlier if you mostly download anime.
The order applies to a title search and to a direct lookup of an ID you give with
`--tmdb`, `--imdb`, or `--tvdb`. A supplied ID always goes to the providers that read
that kind of ID, and it never falls back to a title search.
`--tmdb`, `--imdb`, `--tvdb`, or `--anilist`. A supplied ID always goes to the providers
that read that kind of ID, and it never falls back to a title search.
!!! note "Which AniList title `anilist_title_language` picks"
AniList holds up to three titles for a work: the English one, the romaji transliteration,
and the native one. This option says which of them unshackle uses:
```yaml
anilist_title_language: romaji
```
A work does not always have all three. When the one you asked for is unset on AniList's
side, unshackle falls back in the order english → romaji → native. It takes the first one
that is set, so you always get a title.
!!! note "What `disable_metadata` turns off"
With `disable_metadata: true`, unshackle never contacts a metadata provider on its own.
@@ -53,10 +70,10 @@ each metadata provider can actually answer with, see
disable_metadata: true
```
An ID you give with `--tmdb`, `--imdb`, `--tvdb`, or `--animeapi` is your permission to use
that ID, so it still works: the ID is looked up directly, the other IDs are cross
referenced from it, and `--enrich` still reads that source. Only the lookups you did not
ask for are stopped.
An ID you give with `--tmdb`, `--imdb`, `--tvdb`, or `--anilist` is your permission to use
that ID. That lookup still works. unshackle looks the ID up directly, cross references the other
IDs from it, and `--enrich` still reads that source. Only the lookups you did not ask for
are stopped.
!!! note "The `imdb` provider needs no key"
It replaces the earlier `imdbapi` provider, which read a third-party mirror