Add TVmaze as a second, user-selectable TV metadata source for Fetch Data
TV episodes can now resolve against either TMDB (default) or TVmaze - picked via a segmented source picker in the renamed "Fetch Data Settings" modal. TVmaze is free and needs no API token at all; movies still always resolve against TMDB regardless of the choice, since TVmaze has no movie catalog. - New TvmazeClient (crates/aurora-curator-core/src/web/tvmaze.rs): search + season/episode lookup against api.tvmaze.com, filtering out unnumbered specials rather than panicking on them (TVmaze returns every season's episodes in one flat list, unlike TMDB's per-season endpoint). - New TvMetadataSource setting (settings.rs), persisted alongside the TMDB token, defaulting to Tmdb for schema-evolution safety. - metadata.rs now branches TV fetches through an AnyTvClient wrapper so the existing per-(series, season) caching loop doesn't care which source produced a result; the movie-fetch path is untouched. - Frontend: TMDB/TVmaze picker in Fetch Data Settings, persisted on change; Fetch Data's token gating now only requires a TMDB token when it's actually needed (movies always, TV only when TMDB is the chosen source) instead of unconditionally blocking on it. cargo test --workspace: 88/88 passing (81 + 7 new TVmaze + 3 new settings). npm run build passing. Playwright verification: 18/18 checks (picker renders and persists across reload, TV Fetch Data succeeds on TVmaze with zero TMDB token configured, movies still correctly demand a token even with TVmaze selected, switching back to TMDB still works end-to-end).
This commit is contained in:
@@ -6,10 +6,13 @@ fork), built from scratch as its own project: new stack, new architecture, new b
|
||||
**Status: early scaffold, but the core loop works end to end.** The naming-expression
|
||||
engine is ported and tested, the faithfully-recreated two-pane UI is wired to real
|
||||
native file/folder loading and drag-and-drop, local filename-based season/episode *and
|
||||
movie title/year* detection ("Match") is working, real online metadata lookups against
|
||||
TMDB ("Fetch Data") are working for both TV episodes and movies — including fuzzy
|
||||
title disambiguation, so a search that returns several similarly-named results doesn't
|
||||
just take TMDB's top-ranked hit — and the actual on-disk operation is wired up (with a
|
||||
movie title/year* detection ("Match") is working, real online metadata lookups
|
||||
("Fetch Data") are working for both TV episodes and movies — including fuzzy title
|
||||
disambiguation, so a search that returns several similarly-named results doesn't just
|
||||
take the source's top-ranked hit. TV episodes can resolve against either TMDB or
|
||||
TVmaze — user-selectable in Fetch Data Settings, TMDB stays the default and TVmaze
|
||||
needs no API token at all — while movies always resolve against TMDB, since TVmaze has
|
||||
no movie catalog. The actual on-disk operation is wired up (with a
|
||||
confirmation step showing the full old-path/new-path plan before anything touches disk,
|
||||
a per-row ✕ to drop an individual file from that plan at the last step, a Move/Copy/
|
||||
Symlink selector for what to actually do at each target, and — independently — a Skip/
|
||||
@@ -129,38 +132,43 @@ crates/aurora-curator-core/ Pure Rust core: naming-expression engine (ported),
|
||||
the same module (`guess_release_info` — resolution, source, video/
|
||||
audio codec, release group), text-similarity scoring for
|
||||
disambiguating search results (`similarity/`, partial
|
||||
`EpisodeMetrics` port), a TMDB metadata client (`web/tmdb.rs` — TV
|
||||
search + episode lookup
|
||||
and movie search + lookup, both disambiguated via `similarity/`,
|
||||
tested against a mocked HTTP server via `mockito`), the on-disk
|
||||
`EpisodeMetrics` port), two web metadata clients — `web/tmdb.rs`
|
||||
(TV search + episode lookup and movie search + lookup) and
|
||||
`web/tvmaze.rs` (TV search + episode lookup only — TVmaze has no
|
||||
movie catalog, and no API key/auth at all), both disambiguated via
|
||||
`similarity/` and tested against a mocked HTTP server via
|
||||
`mockito`, the on-disk
|
||||
rename engine (`rename/` — Move/Copy/Symlink actions,
|
||||
Skip/Auto-number/Override conflict policies, can also organize
|
||||
into (auto-created) subfolders when
|
||||
the naming scheme includes `/`) — and a rename history/undo log
|
||||
(`history/`, a partial `HistoryDialog` port, undo-aware of which
|
||||
action produced each batch). Not yet ported: full media metadata
|
||||
bindings, other web datasource clients (TVDB/AniDB/etc).
|
||||
bindings, other web datasource clients (TheTVDB/AniDB/OMDb/etc).
|
||||
No Tauri dependency, so it builds and unit-tests standalone.
|
||||
src-tauri/ Tauri app shell: exposes aurora-curator-core as commands to the frontend
|
||||
(naming-scheme rendering, filename matching for both TV and
|
||||
movies, TMDB metadata fetch — `metadata.rs` for TV episodes,
|
||||
plus a movie-fetch command alongside it — executing a rename
|
||||
movies, metadata fetch — `metadata.rs` for TV episodes (against
|
||||
whichever of TMDB/TVmaze is the stored source) plus a
|
||||
movie-fetch command alongside it (always TMDB) — executing a rename
|
||||
plan, native file/folder dialogs, drag-and-drop expansion), plus
|
||||
`settings.rs` (TMDB token), `history.rs` (rename history/undo
|
||||
`settings.rs` (TMDB token, and which TV metadata source Fetch Data
|
||||
uses), `history.rs` (rename history/undo
|
||||
log), and `presets.rs` (up to 9 saved naming schemes) — all three
|
||||
stored as JSON in the OS app-config directory — app
|
||||
metadata/icons/window config (tauri.conf.json).
|
||||
src/ React + TypeScript UI (Vite). Faithful recreation of the original
|
||||
two-pane rename screen (Aurora theme) wired to real file loading,
|
||||
drag-and-drop, live naming-scheme preview, local TV/movie
|
||||
matching, TMDB fetch for both (behind a Settings modal for the
|
||||
API token), a confirm-before-touching-disk modal for the actual
|
||||
matching, metadata fetch for both (behind a Fetch Data Settings
|
||||
modal holding the TMDB/TVmaze source picker and the API token), a
|
||||
confirm-before-touching-disk modal for the actual
|
||||
rename, a History panel that can undo a past rename, Align Up/Down
|
||||
list reordering, and a Presets panel (plus `1`-`9` hotkeys) for
|
||||
saved naming schemes.
|
||||
scripts/gen_icons.py Regenerates src-tauri/icons/ (placeholder branding — swap the
|
||||
colors/glyph in the script, or replace the icons directly, to
|
||||
change the look).
|
||||
scripts/gen_icons.py Regenerates src-tauri/icons/ from the real logo mark
|
||||
(`scripts/logo/icon-source.png`, cropped from the supplied
|
||||
lockup) — replace that source image to change the look.
|
||||
```
|
||||
|
||||
## Building
|
||||
@@ -183,24 +191,35 @@ npm run tauri build
|
||||
```
|
||||
|
||||
Verified in the environment this was built in: `cargo test -p aurora-curator-core` (all
|
||||
passing, including the TMDB client tests — those run against a local mock HTTP server
|
||||
via `mockito`, no live network or API key needed to build/test), `cargo check -p
|
||||
passing, including the TMDB and TVmaze client tests — those run against a local mock
|
||||
HTTP server via `mockito`, no live network or API key needed to build/test), `cargo check -p
|
||||
aurora-curator` (compiles clean against real Tauri + GTK/WebKit system libraries), and `npm run
|
||||
build` (TypeScript type-checks, Vite bundles). The actual GUI window has **not** been
|
||||
visually verified anywhere yet — that sandbox has no display. Run `npm run tauri dev`
|
||||
on your machine to see and click through it for the first time.
|
||||
|
||||
### Setting up TMDB (for "Fetch Data")
|
||||
### Setting up metadata sources (for "Fetch Data")
|
||||
|
||||
Everything else in the app works fully offline; "Fetch Data" is the one feature that
|
||||
needs a (free) [TMDB](https://www.themoviedb.org/) account:
|
||||
talks to the network, and it's the only one that needs any setup at all — and even that
|
||||
setup is optional for TV.
|
||||
|
||||
1. Create a TMDB account, then go to Settings → API in your account and generate an
|
||||
**API Read Access Token** (not the older numeric "API Key" — Aurora Curator uses the Bearer
|
||||
token method TMDB documents as the default).
|
||||
2. In the app, click the key icon ("TMDB Settings") next to Fetch Data and paste the
|
||||
token in. It's saved locally in the OS app-config directory and only ever sent to
|
||||
`api.themoviedb.org`.
|
||||
TV episodes can resolve against either of two sources, picked in the app (click the key
|
||||
icon, "Fetch Data Settings", next to Fetch Data):
|
||||
|
||||
- **[TVmaze](https://www.tvmaze.com/)** — free, no account or API token needed at all.
|
||||
Just pick it and go.
|
||||
- **[TMDB](https://www.themoviedb.org/)** — the default, and the only option for movies
|
||||
(TVmaze has no movie catalog). Needs a free account:
|
||||
1. Create a TMDB account, then go to Settings → API in your account and generate an
|
||||
**API Read Access Token** (not the older numeric "API Key" — Aurora Curator uses the
|
||||
Bearer token method TMDB documents as the default).
|
||||
2. In the app, open "Fetch Data Settings" and paste the token in. It's saved locally
|
||||
in the OS app-config directory and only ever sent to `api.themoviedb.org`.
|
||||
|
||||
A batch of TV-only files can run entirely on TVmaze with no token configured at all; a
|
||||
batch containing any movies still needs the TMDB token regardless of which TV source is
|
||||
selected.
|
||||
|
||||
## Porting roadmap (not yet done)
|
||||
|
||||
@@ -240,13 +259,20 @@ ported from, for anyone picking this up:
|
||||
4. **Media detection** — `net.filebot.media.MediaDetection` (1356 lines): ties file-name
|
||||
parsing + matching together to auto-identify what a file is.
|
||||
5. **Web datasource clients** — `net.filebot.web.*` (~40 files): TheMovieDB, TheTVDB,
|
||||
AniDB, OMDb, TVmaze, OpenSubtitles, etc. TMDB is done for both TV and movies
|
||||
AniDB, OMDb, TVmaze, OpenSubtitles, etc. Two are done: TMDB, for both TV and movies
|
||||
(`crates/aurora-curator-core/src/web/tmdb.rs`, `reqwest` + `serde_json`, Bearer-token auth) —
|
||||
search-by-name plus per-season episode lookup for TV, search-by-title (optionally
|
||||
narrowed by release year via TMDB's own `primary_release_year` filter) for movies —
|
||||
both wired to "Fetch Data", disambiguating multi-result searches via the
|
||||
similarity-scoring pass described in item 3 above rather than blindly trusting
|
||||
TMDB's top-ranked hit. All other sources (TheTVDB, AniDB, OMDb, TVmaze,
|
||||
and TVmaze, for TV only (`crates/aurora-curator-core/src/web/tvmaze.rs`, same `reqwest` +
|
||||
`serde_json` shape, no auth at all — TVmaze has no movie catalog to search, and its
|
||||
per-show episode endpoint returns every season in one flat list rather than TMDB's
|
||||
per-season lookup, so the client fetches once and filters locally, skipping any
|
||||
unnumbered/special episodes rather than panicking on them). Both are wired to "Fetch
|
||||
Data" — a user-selectable "TV episode source" picker in Fetch Data Settings chooses
|
||||
which of the two a batch's TV items resolve against (TMDB stays the default; movies
|
||||
always use TMDB regardless of that picker) — disambiguating multi-result searches via
|
||||
the similarity-scoring pass described in item 3 above rather than blindly trusting
|
||||
either source's top-ranked hit. All other sources (TheTVDB, AniDB, OMDb,
|
||||
OpenSubtitles) are not yet started.
|
||||
6. **Rename engine + CLI** — `net.filebot.cli.CmdlineOperations` (1235 lines) and
|
||||
`ArgumentBean` (415 lines, the full flag surface: `-rename`, `--db`, `--format`,
|
||||
|
||||
Reference in New Issue
Block a user