Add movie support to Fetch Data: local title/year guessing plus TMDB movie lookup
- renamr-core::matching: guess_movie() extracts a movie title (and release year, if
present) from a filename using the same year/quality-token boundary heuristics real
release names follow, as a fallback when guess_episode() finds no season/episode
marker.
- renamr-core::web::tmdb: search_movie()/lookup_movie() mirror the TV client, reusing
the same Sorensen-Dice title-disambiguation as lookup_episode(), narrowed further by
TMDB's own primary_release_year filter when a year was locally guessed. Also exposed
search_tv_best_match() and fixed a latent gap where the real Fetch Data command path
(metadata.rs::fetch_season) bypassed the fuzzy show-name disambiguation entirely,
doing its own raw first-result selection instead of reusing it.
- src-tauri: new guess_movie command and fetch_movie_metadata command/types
(MovieFetchQuery/Outcome/Result), registered alongside the existing TV commands.
- Frontend: Item now tracks mediaKind ("tv"/"movie"/null); Match tries guess_episode
then falls back to guess_movie; Fetch Data resolves TV and movie targets via their
own commands concurrently and merges results. A single batch can mix TV and movie
files - each only fills in the fields that apply to it. Movie fields ({movie name},
{year}, reusing {airdate} for release date, matching FileBot's own unified binding)
are documented in the naming-scheme field reference.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
93b5ac5e56
commit
45a9f5d523
@@ -5,15 +5,17 @@ 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
|
||||
detection ("Match") is working, real online metadata lookups against TMDB ("Fetch
|
||||
Data") are working — including fuzzy show-name disambiguation, so a search that
|
||||
returns several similarly-named shows doesn't just take TMDB's top-ranked hit — and the
|
||||
actual on-disk rename operation is wired up (skip-on-conflict, with a confirmation step
|
||||
showing the full old-path/new-path plan before anything touches disk). Rename can also
|
||||
organize files into subfolders — including ones that don't exist yet — when the naming
|
||||
scheme includes a `/`. Every completed rename is logged to a history panel that can
|
||||
undo it, moving files back to their original paths. Full media-metadata bindings are
|
||||
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 rename operation is wired up
|
||||
(skip-on-conflict, with a confirmation step showing the full old-path/new-path plan
|
||||
before anything touches disk). Rename can also organize files into subfolders —
|
||||
including ones that don't exist yet — when the naming scheme includes a `/`. Every
|
||||
completed rename is logged to a history panel that can undo it, moving files back to
|
||||
their original paths. A single loaded batch can freely mix TV episodes and movies —
|
||||
each file only fills in the fields that apply to it. Full media-metadata bindings are
|
||||
not yet ported. See "Porting roadmap" below.
|
||||
|
||||
The naming scheme is fully user-editable from the app (the "Naming Scheme" button next
|
||||
@@ -106,12 +108,13 @@ that item is skipped rather than overwritten.
|
||||
|
||||
```
|
||||
crates/renamr-core/ Pure Rust core: naming-expression engine (ported), local
|
||||
filename-based season/episode matching (ported, `matching/`),
|
||||
text-similarity scoring for disambiguating search results
|
||||
(`similarity/`, partial `EpisodeMetrics` port), a TMDB metadata
|
||||
client (`web/tmdb.rs` — TV search + episode lookup, disambiguated
|
||||
via `similarity/`, tested against a mocked HTTP server via
|
||||
`mockito`), the on-disk rename engine (`rename/`) —
|
||||
filename-based season/episode *and movie title/year* matching
|
||||
(ported, `matching/`), 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
|
||||
rename engine (`rename/`) —
|
||||
skip-on-conflict, can also organize into (auto-created)
|
||||
subfolders when the naming scheme includes `/` — and a rename
|
||||
history/undo log (`history/`, a partial `HistoryDialog` port).
|
||||
@@ -119,18 +122,19 @@ crates/renamr-core/ Pure Rust core: naming-expression engine (ported), local
|
||||
datasource clients (TVDB/AniDB/etc).
|
||||
No Tauri dependency, so it builds and unit-tests standalone.
|
||||
src-tauri/ Tauri app shell: exposes renamr-core as commands to the frontend
|
||||
(naming-scheme rendering, filename matching, TMDB metadata fetch,
|
||||
executing a rename plan, native file/folder dialogs, drag-and-drop
|
||||
expansion), plus `settings.rs` (TMDB token) and `history.rs`
|
||||
(rename history/undo log) — both stored as JSON in the OS
|
||||
app-config directory — app metadata/icons/window config
|
||||
(tauri.conf.json).
|
||||
(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
|
||||
plan, native file/folder dialogs, drag-and-drop expansion), plus
|
||||
`settings.rs` (TMDB token) and `history.rs` (rename history/undo
|
||||
log) — both 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 matching, TMDB
|
||||
fetch (behind a Settings modal for the API token), a
|
||||
confirm-before-touching-disk modal for the actual rename, and a
|
||||
History panel that can undo a past rename.
|
||||
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
|
||||
rename, and a History panel that can undo a past rename.
|
||||
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).
|
||||
@@ -191,25 +195,30 @@ ported from, for anyone picking this up:
|
||||
3. **Matching/similarity engine** — `net.filebot.similarity.*`. Local filename-based
|
||||
season/episode detection is done (`crates/renamr-core/src/matching`, ported from the
|
||||
pattern-matching half of `SeasonEpisodeMatcher.java`, adapted to Rust's `regex` crate
|
||||
which lacks lookahead/lookbehind — wired to the "Match" button). Show-name
|
||||
disambiguation is also done (`crates/renamr-core/src/similarity`, a partial port of
|
||||
the *scoring* idea behind `EpisodeMetrics.java`'s fuzzy title-matching cascade —
|
||||
Sorensen-Dice similarity over normalized-title character bigrams): "Fetch Data" now
|
||||
picks whichever TMDB search result is textually closest to the local guess rather
|
||||
than just trusting TMDB's relevance/popularity-ranked first hit, and reports "not
|
||||
found" instead of guessing when nothing in the results is a plausible match at all.
|
||||
`DateMatcher` (numbering/air-date-based identification, the other half of the
|
||||
original `EpisodeMetrics`) is not ported — Renamr doesn't do date-based episode
|
||||
identification.
|
||||
which lacks lookahead/lookbehind — wired to the "Match" button), and so is a local
|
||||
movie title/year heuristic (`guess_movie` in the same module) used as a fallback
|
||||
whenever a filename carries no season/episode marker — a release name is either a TV
|
||||
episode or a movie, never both. Title disambiguation is also done
|
||||
(`crates/renamr-core/src/similarity`, a partial port of the *scoring* idea behind
|
||||
`EpisodeMetrics.java`'s fuzzy title-matching cascade — Sorensen-Dice similarity over
|
||||
normalized-title character bigrams), shared by both the TV and movie TMDB lookups:
|
||||
"Fetch Data" picks whichever TMDB search result is textually closest to the local
|
||||
guess rather than just trusting TMDB's relevance/popularity-ranked first hit, and
|
||||
reports "not found" instead of guessing when nothing in the results is a plausible
|
||||
match at all. `DateMatcher` (numbering/air-date-based identification, the other half
|
||||
of the original `EpisodeMetrics`) is not ported — Renamr doesn't do date-based
|
||||
episode identification.
|
||||
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 TV (`crates/renamr-core/src/web/tmdb.rs`,
|
||||
`reqwest` + `serde_json`, Bearer-token auth) — search-by-name plus per-season episode
|
||||
lookup, wired to "Fetch Data", disambiguating multi-result searches via the
|
||||
AniDB, OMDb, TVmaze, OpenSubtitles, etc. TMDB is done for both TV and movies
|
||||
(`crates/renamr-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. TMDB movie lookup and all other sources (TheTVDB, AniDB,
|
||||
OMDb, TVmaze, OpenSubtitles) are not yet started.
|
||||
TMDB's top-ranked hit. All other sources (TheTVDB, AniDB, OMDb, TVmaze,
|
||||
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`,
|
||||
`--action`, `--conflict`, `-get-subtitles`, `-script`, etc.). The rename operation is
|
||||
|
||||
Reference in New Issue
Block a user