Commit Graph
18 Commits
Author SHA1 Message Date
Renamr Scaffold 21d78b8f3a Add Align Up/Down list reordering and naming-scheme Presets
Align Up/Down now swaps the selected file with its neighbor in the shared
item list (Original Files and New Names stay positionally paired, matching
the original FileBot's "align" buttons for manually lining up mismatched
lists).

Naming-scheme Presets: up to 9 saved expressions, one per digit slot,
persisted as presets.json (src-tauri/src/presets.rs, same load/save
pattern as settings.rs/history.rs). A new Presets panel lists all 9 slots
with Save Current / Apply / Clear, and a global 1-9 keydown handler applies
a slot instantly from anywhere in the app (ignored while a text field is
focused or a modal is open).
2026-08-29 09:39:52 +00:00
Renamr Scaffold 94eb26f778 Add release-tag naming-scheme fields (resolution, source, codecs, group)
Match now also parses filename-only release-tag text - resolution, source
(BluRay/HDTV/WEB-DL/...), video/audio codec, and release group - via a new
guess_release_info() in renamr-core's matching module, wired through a new
guess_release_info Tauri command and called alongside the existing TV/movie
guess for every file. Naming schemes can now reference
{resolution}/{source}/{video codec}/{audio codec}/{release group}, or
FileBot's own short names ({vf}/{source}/{vc}/{ac}/{group}).
2026-08-29 09:29:14 +00:00
Renamr ScaffoldandClaude Sonnet 5 fd4e6f66f0 Add Move/Copy/Symlink rename actions, with undo support for all three
- renamr-core::rename: new RenameAction enum (Move/Copy/Symlink, default Move,
  mirroring net.filebot.cli.CmdlineOperations's --action modes). execute_renames() now
  takes an action applied to the whole batch. Copy uses fs::copy (source untouched);
  Symlink uses std::os::unix::fs::symlink / std::os::windows::fs::symlink_file behind a
  cfg(unix)/cfg(windows) split. Same conflict policy (skip, never overwrite) and
  auto-created destination folders apply to all three actions. 8 new tests.
- renamr-core::history: HistoryBatch now records which action produced it
  (#[serde(default)] so old history.json entries - all implicitly Move - still
  deserialize). revert_one() branches on it: Move still moves the file back; Copy/
  Symlink undo by deleting the copy/symlink (using symlink_metadata so a broken link is
  still recognized as present and removable) - the original was never touched by those
  actions, so there's nothing to move back. 3 new tests.
- src-tauri: execute_rename command takes the chosen action and threads it through to
  both execute_renames and record_batch.
- Frontend: a Move/Copy/Symlink segmented selector in the "Confirm Rename" modal
  (remembered across modal opens, defaults to Move), action-aware subtitle/button
  copy, and a status message using the right verb (Renamed/Copied/Symlinked). Only Move
  reconciles a loaded item's id/name/bindings to the new path afterward, since Copy/
  Symlink leave the source file exactly where it was. History panel now shows a Copy/
  Symlink badge on non-Move batches and explains what Undo does for each.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-29 04:31:16 +00:00
Renamr ScaffoldandClaude Sonnet 5 aab8e28246 Add per-item exclude to the rename confirmation modal
Each row in the "Confirm Rename" plan now has a small x button that drops just that
file from the batch without closing the modal or needing to cancel and re-select
beforehand (previously it was all-or-nothing - "Exclude Selected" on the file list was
the only way to leave a file out, and only before opening Rename at all). Excluding
every row disables the confirm button and shows an empty-plan hint instead of sending
an empty batch. No Rust changes needed - this is pure plan-state filtering in the
frontend, RenamePlanEntry's shape is unchanged.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-29 04:12:35 +00:00
Renamr ScaffoldandClaude Sonnet 5 45a9f5d523 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]>
2026-08-29 04:04:16 +00:00
Renamr Scaffold 93b5ac5e56 Add rename history with undo
- New crates/renamr-core/src/history module: HistoryBatch/HistoryEntry
  records, revert_batch() moves files back to their original paths
  (skip-on-conflict, same policy as rename::execute_renames; recreates a
  deleted destination folder defensively), push_batch() maintains a
  most-recent-first log capped at 50 batches. A partial port of the idea
  behind net.filebot.HistoryDialog, as a flat undo stack rather than a full
  session/element log. 6 new tests.
- New src-tauri/src/history.rs: persists the log as history.json in the OS
  app-config directory (same location as settings.json). execute_rename now
  takes an AppHandle and calls history::record_batch after every rename,
  recording only the items that actually got renamed. Two new commands:
  list_rename_history and undo_rename_batch.
- Frontend: the History button (previously a no-op) now opens a panel
  listing past rename batches with a timestamp, file count, and the
  old-name/new-name pairs, each with an Undo button. Undoing reconciles any
  currently-loaded item back to its pre-rename path/name, same pattern as
  post-rename reconciliation.
- Verified via cargo test (45 total)/check + npm build + a full Playwright
  pass: loaded mocked files, renamed them, opened History, undid the batch,
  and confirmed both the UI and the (mocked) backend state matched at every
  step.
2026-08-29 03:44:38 +00:00
Renamr Scaffold 658a235e05 Let the naming scheme organize files into subfolders
- rename::rename_one now resolves new_name relative to the source file's
  own directory, allowing / as a subdirectory separator (e.g. a naming
  scheme like {show name}/{episode name}) instead of rejecting it. Missing
  intermediate directories are created automatically via create_dir_all.
- New validate_relative_target() replaces the old is_plain_filename():
  still rejects anything that could escape the source directory (empty
  path segments - which also catches a leading-slash absolute path -
  and . / .. segments) plus backslashes (Renamr always treats / as the
  scheme's folder separator regardless of OS), but now allows a
  legitimate multi-segment relative path through.
- The "Unchanged" check now compares the full resolved target path to the
  source, not just the filename, since a computed name can now include
  directory components.
- 6 new tests: organizing into a new subfolder, nested subfolders that
  don't exist yet, conflict detection still works for organized targets,
  and rejection of backslashes / doubled / leading / trailing slashes.
- Frontend: naming-scheme editor hint explains the / convention, and the
  rename confirmation modal notes when a plan will create new subfolders.
- No changes needed in the naming-expression engine itself - it already
  treats / between two {} scriptlets as ordinary literal text.
2026-08-29 03:36:06 +00:00
Renamr Scaffold 855f9bea24 Disambiguate Fetch Data's TMDB search results by name similarity
- New crates/renamr-core/src/similarity module: a partial port of the
  scoring idea behind FileBot's EpisodeMetrics.java - normalizes titles
  (lowercase, strips a trailing release-year parenthetical, collapses
  punctuation/whitespace) and scores them with a Sorensen-Dice coefficient
  over character bigrams. best_title_match() picks whichever candidate is
  textually closest to the query, provided it clears a minimum threshold;
  ties keep the earlier (i.e. TMDB-ranked) candidate.
- TmdbClient::lookup_episode now uses best_title_match instead of blindly
  taking the first search result, so a more popular but differently-named
  show can no longer beat an exact-but-lower-ranked match to the top - and
  reports NotFound instead of guessing when nothing in the results is a
  plausible match at all.
- 7 new tests (5 in similarity, 2 in tmdb) including the concrete regression
  case this fixes: searching "Chuck" with TMDB returning "Chucky" ranked
  above "Chuck" now correctly picks "Chuck".
- Also fixes a gitignore gap from last delivery: the _to_delete*/ scratch-dir
  pattern used to work around this repo's mounted-folder git-lock quirk had
  only ever been applied directly on the device, never carried back into the
  zip this delivery is built from - so the last delivery's cp -rf silently
  reintroduced the untracked-lock-file risk. Fixed in both places now.
2026-08-29 03:27:19 +00:00
Renamr Scaffold 717acb5de1 Broaden .gitignore to _to_delete*/ and untrack second stray scratch dir 2026-08-29 03:16:01 +00:00
Renamr Scaffold 5db1cb414b Untrack accidental _to_delete scratch dir, add it to .gitignore 2026-08-29 03:15:40 +00:00
Renamr Scaffold f89589bc88 Make the naming scheme fully user-editable, with the user's preferred format as default
- ExpressionFormat::compile_scriptlet now falls back to treating a {token} as a
  literal multi-word binding key when it's neither a valid Rhai identifier nor
  valid Rhai script, but still looks like a plain human-typed field name (only
  letters/digits/underscores/spaces). This is what lets `{show name}` work
  without anyone needing to know Rhai, while real Rhai script (even containing
  spaces) still takes priority and genuine syntax errors still surface.
- New default naming scheme app-wide: `{show name} - {season number}x
  {episode number} - {episode name}` (previously the terser {n} - {s00e00} -
  {t} form). Match/Fetch Data auto-upgrade targets updated to match, and
  sample items carry both the short FileBot-style keys and the new
  human-readable ones side by side.
- Naming scheme editor UI rewritten: explains the field is fully editable,
  lists available fields grouped by when they become available (always /
  after Match / after Fetch Data), and clarifies Rhai script is also
  supported for anyone who wants it.
- 3 new unit tests for the plain-field-name fallback (multi-word lookup
  works, real Rhai still takes priority, genuine syntax errors still error).
2026-08-29 03:15:21 +00:00
Renamr Scaffold d1fc4039a7 Add TMDB metadata client and Fetch Data: real episode titles/air dates via TMDB, with a Settings modal for the API token 2026-08-29 03:01:19 +00:00
Renamr Scaffold bab9bfa1ec Add local season/episode matching and on-disk rename (skip-on-conflict, confirm-first) 2026-08-29 02:42:31 +00:00
Renamr Scaffold d0c29048be Fix long filenames overflowing the window instead of truncating: flex/grid items need explicit min-width:0 to shrink below content size 2026-08-29 02:15:49 +00:00
Renamr Scaffold bab05826ef Fix freeze on file/folder picker dialogs: use the non-blocking dialog API instead of blocking_pick_files()/blocking_pick_folder(), which deadlock when called from a command handler 2026-08-29 02:10:56 +00:00
Renamr Scaffold 07ce595f77 Add real file loading: native file/folder picker + OS drag-and-drop, backed by real Rust commands (pick_files/pick_folder/expand_dropped_paths) 2026-08-29 02:06:14 +00:00
Renamr Scaffold 87e150f31b Rebuild UI as a faithful recreation of the original Aurora-themed layout: sidebar panel nav, two-pane rename list, live naming-scheme preview 2026-08-29 01:55:54 +00:00
Renamr Scaffold e01852f292 Initial Renamr scaffold: Tauri (Rust core + React/TS UI), naming-expression engine ported+tested 2026-08-29 01:43:12 +00:00