mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 20:15:10 +00:00
feat(dl): allow --tvdb as an --enrich metadata source
This commit is contained in:
@@ -394,7 +394,7 @@ Create a download job. Requires `service` and `title_id`; every other field is a
|
||||
| `tag` | string | `null` | Release group tag. |
|
||||
| `tmdb_id` / `imdb_id` / `tvdb_id` / `animeapi_id` | - | `null` | External ID overrides for tagging. |
|
||||
| `tvdb_order` | `official`, `dvd`, `absolute`, `alternate`, `regional` | `null` | Renumber episodes to a TVDB season order. Falls back to the `tvdb_order` config option. |
|
||||
| `enrich` | boolean | `false` | Override title/year from external source, and fill in the original language. |
|
||||
| `enrich` | boolean | `false` | Override title/year from external source, and fill in the original language. Needs one of `tmdb_id`, `imdb_id`, `tvdb_id` or `animeapi_id`; without one the job fails instead of returning `400`. |
|
||||
| `output_dir` | string | `null` | Override output directory. |
|
||||
| `no_cache` / `reset_cache` | boolean | `false` | Title cache controls. |
|
||||
|
||||
|
||||
@@ -152,9 +152,9 @@ Keep only certain track types, or skip certain track types. Attachments are alwa
|
||||
|---|---|
|
||||
| `--tmdb` | TMDB ID (integer). |
|
||||
| `--imdb` | IMDb ID, e.g. `tt1375666`. |
|
||||
| `--tvdb` | TVDB ID (integer). Skips the series lookup that `--tvdb-order` would otherwise do. |
|
||||
| `--tvdb` | TVDB ID (integer). Skips the series lookup that `--tvdb-order` would otherwise do. `--enrich` reads it too. |
|
||||
| `--animeapi` | AnimeAPI ID, e.g. `mal:12345` or `anilist:98765` (defaults to MAL). Back-fills TMDB/IMDb/TVDB. |
|
||||
| `--enrich` | Override show title/year from the external source, and fill in the original language. **Requires** one of `--tmdb`, `--imdb`, or `--animeapi`. |
|
||||
| `--enrich` | Override show title/year from the external source, and fill in the original language. **Requires** one of `--tmdb`, `--imdb`, `--tvdb`, or `--animeapi`. |
|
||||
| `--tvdb-order` | Renumber episodes to a TVDB season order: `official` (aired), `dvd`, `absolute`, `alternate`, or `regional`. Needs `tvdb_api_key`. |
|
||||
|
||||
#### Episode ordering
|
||||
|
||||
@@ -583,7 +583,7 @@ tagging and naming:
|
||||
| `--imdb` | `--imdb tt1375666` | Use this IMDb ID. |
|
||||
| `--tvdb` | `--tvdb 73871` | Use this TVDB ID instead of looking the series up. |
|
||||
| `--animeapi` | `--animeapi mal:12345` | Resolve via AnimeAPI (`mal:`/`anilist:` prefix; defaults to MAL). |
|
||||
| `--enrich` | - | Override the show title and year from an external source, and fill in the original language. **Requires** one of `--tmdb`, `--imdb`, or `--animeapi`. |
|
||||
| `--enrich` | - | Override the show title and year from an external source, and fill in the original language. **Requires** one of `--tmdb`, `--imdb`, `--tvdb`, or `--animeapi`. |
|
||||
| `--tvdb-order` | `--tvdb-order dvd` | Renumber episodes to a TVDB season order. Needs `tvdb_api_key`. |
|
||||
|
||||
```shell title="Force the right IMDb match and enrich the title"
|
||||
@@ -611,8 +611,10 @@ all end up as the same language.
|
||||
- `--tmdb` reads TMDB.
|
||||
- `--imdb` tries IMDxAPI, then falls back to OMDb. Since `imdb_api_enabled` is `false` by
|
||||
default, an OMDb key is what makes this path work for most people.
|
||||
- `--animeapi` supplies a title only, so pair it with `--tmdb` or `--imdb` if you also want
|
||||
the year and language.
|
||||
- `--tvdb` reads TVDB. It needs `tvdb_api_key`.
|
||||
- `--animeapi` supplies a title, plus whichever IDs AnimeAPI knows for the show. If that
|
||||
includes a TMDB, IMDb or TVDB ID, the year and language come from that provider. If it
|
||||
does not, pair it with `--tmdb`, `--imdb` or `--tvdb`.
|
||||
|
||||
Language is the one field `--enrich` will not overwrite. A service that already reported an
|
||||
original language keeps it, because the platform knows its own catalogue better than a
|
||||
|
||||
@@ -14,7 +14,7 @@ each metadata provider can actually answer with, see
|
||||
| `omdb_api_key` | str | `""` | [OMDb](https://www.omdbapi.com/) API key for IMDb metadata lookups; a more reliable alternative to IMDxAPI. Free keys are available on the OMDb site. |
|
||||
| `tmdb_api_key` | str | `""` | TMDB API key for metadata enrichment and external-ID tags. |
|
||||
| `simkl_client_id` | str | `""` | SIMKL client ID for metadata lookups; an alternative/fallback source to TMDB. |
|
||||
| `tvdb_api_key` | str | `""` | [TheTVDB v4](https://thetvdb.com/api-information) API key; a fallback source to TMDB, strongest on TV series. Free keys are available on the TVDB site. |
|
||||
| `tvdb_api_key` | str | `""` | [TheTVDB v4](https://thetvdb.com/api-information) API key; a fallback source to TMDB, strongest on TV series. Also the source `--enrich --tvdb` reads. Free keys are available on the TVDB site. |
|
||||
| `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 | *(see below)* | Metadata providers to use, in the order they are tried. |
|
||||
|
||||
@@ -157,6 +157,27 @@ def test_cached_tvdb_result_keeps_enriched_ids() -> None:
|
||||
assert result.external_ids.tmdb_id == 615
|
||||
|
||||
|
||||
@pytest.mark.parametrize(("kind", "path"), [("tv", "/series/73871/extended"), ("movie", "/movies/73871/extended")])
|
||||
def test_get_by_id_supplies_what_enrich_needs(monkeypatch: pytest.MonkeyPatch, kind: str, path: str) -> None:
|
||||
p = TVDBProvider()
|
||||
seen: list[str] = []
|
||||
|
||||
def fake_get(request_path: str, params: dict) -> dict:
|
||||
seen.append(request_path)
|
||||
return {
|
||||
"name": "Cowboy Bebop",
|
||||
"year": "1998",
|
||||
"originalLanguage": "jpn",
|
||||
"remoteIds": [{"sourceName": "IMDB", "id": "tt0213338"}],
|
||||
}
|
||||
|
||||
monkeypatch.setattr(p, "_get", fake_get)
|
||||
result = p.get_by_id(73871, kind)
|
||||
assert seen == [path]
|
||||
assert (result.title, result.year, result.original_language) == ("Cowboy Bebop", 1998, "jpn")
|
||||
assert result.external_ids.imdb_id == "tt0213338"
|
||||
|
||||
|
||||
def test_get_episodes_fails_closed_on_a_truncated_listing(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
p = TVDBProvider()
|
||||
pages: dict[int, object] = {0: {"episodes": [{"id": n} for n in range(500)]}, 1: None}
|
||||
|
||||
@@ -616,7 +616,7 @@ class dl:
|
||||
"tvdb_id",
|
||||
type=int,
|
||||
default=None,
|
||||
help="Use this TVDB ID for --tvdb-order instead of looking the series up automatically.",
|
||||
help="Use this TVDB ID for --tvdb-order and --enrich instead of looking the series up automatically.",
|
||||
)
|
||||
@click.option(
|
||||
"--tvdb-order",
|
||||
@@ -638,7 +638,7 @@ class dl:
|
||||
default=False,
|
||||
help=(
|
||||
"Override show title and year from external source, and fill in the original language "
|
||||
"if the service did not provide one. Requires --tmdb, --imdb, or --animeapi."
|
||||
"if the service did not provide one. Requires --tmdb, --imdb, --tvdb, or --animeapi."
|
||||
),
|
||||
)
|
||||
@click.option(
|
||||
@@ -871,8 +871,10 @@ class dl:
|
||||
if not self.tvdb_id and anime_ids.tvdb_id:
|
||||
self.tvdb_id = anime_ids.tvdb_id
|
||||
|
||||
if self.enrich and not (self.tmdb_id or self.imdb_id or self.animeapi_title):
|
||||
raise click.UsageError("--enrich requires --tmdb, --imdb, or --animeapi to provide a metadata source.")
|
||||
if self.enrich and not (self.tmdb_id or self.imdb_id or self.tvdb_id or self.animeapi_title):
|
||||
raise click.UsageError(
|
||||
"--enrich requires --tmdb, --imdb, --tvdb, or --animeapi to provide a metadata source."
|
||||
)
|
||||
|
||||
# Initialize debug logger with service name if debug logging is enabled
|
||||
if config.debug or logging.root.level == logging.DEBUG:
|
||||
@@ -1552,9 +1554,19 @@ class dl:
|
||||
enrich_year = imdb_result.year
|
||||
enrich_lang = parse_language(imdb_result.original_language)
|
||||
break
|
||||
elif self.tvdb_id:
|
||||
provider = providers.get_provider("tvdb")
|
||||
tvdb_result = provider.get_by_id(self.tvdb_id, kind) if provider else None
|
||||
if tvdb_result:
|
||||
if not enrich_title:
|
||||
enrich_title = tvdb_result.title
|
||||
enrich_year = tvdb_result.year
|
||||
enrich_lang = parse_language(tvdb_result.original_language)
|
||||
|
||||
if enrich_lang:
|
||||
self.log.info(f"Original language from metadata: {enrich_lang}")
|
||||
elif not (enrich_title or enrich_year):
|
||||
self.log.warning("--enrich found no metadata; is the provider's API key configured?")
|
||||
|
||||
if enrich_title or enrich_year or enrich_lang:
|
||||
for t in titles if isinstance(titles, (Series, Movies)) else [titles]:
|
||||
|
||||
@@ -764,7 +764,7 @@ async def download(request: web.Request) -> web.Response:
|
||||
description: Anime database ID via AnimeAPI, e.g. mal:12345 (default - None)
|
||||
enrich:
|
||||
type: boolean
|
||||
description: Override show title and year from external source (default - false)
|
||||
description: Override show title and year from external source, and fill in the original language. Requires one of tmdb_id, imdb_id, tvdb_id or animeapi_id (default - false)
|
||||
no_folder:
|
||||
type: boolean
|
||||
description: Disable folder creation for TV shows (default - false)
|
||||
@@ -794,7 +794,7 @@ async def download(request: web.Request) -> web.Response:
|
||||
description: Use this IMDB ID (e.g. tt1375666) for tagging (default - None)
|
||||
tvdb_id:
|
||||
type: integer
|
||||
description: Use this TVDB ID for tagging and episode ordering (default - None)
|
||||
description: Use this TVDB ID for tagging, episode ordering and enrichment (default - None)
|
||||
tvdb_order:
|
||||
type: string
|
||||
enum: [official, dvd, absolute, alternate, regional]
|
||||
|
||||
Reference in New Issue
Block a user