Add local season/episode matching and on-disk rename (skip-on-conflict, confirm-first)

This commit is contained in:
Renamr Scaffold
2026-08-29 02:42:31 +00:00
parent d0c29048be
commit bab9bfa1ec
9 changed files with 851 additions and 24 deletions
+25
View File
@@ -1,6 +1,8 @@
mod files;
use renamr_core::format::ExpressionFormat;
use renamr_core::matching::{self, EpisodeGuess};
use renamr_core::rename::{self, RenamePlanItem, RenameResult};
use renamr_core::string_bindings;
use std::collections::HashMap;
@@ -15,12 +17,35 @@ fn render_expression(expression: String, bindings: HashMap<String, String>) -> R
.map_err(|e| e.to_string())
}
/// Guesses a season/episode number pair (and series name) from a filename using local
/// regex patterns only - no network calls, no metadata lookup. Returns `None` when the
/// filename doesn't carry a recognizable season/episode marker (movies, already-clean
/// names, etc).
#[tauri::command]
fn guess_episode(filename: String) -> Option<EpisodeGuess> {
matching::guess_episode(&filename)
}
/// Executes a batch of planned on-disk renames (same-directory rename only; conflicting
/// targets are skipped, never overwritten - see `renamr_core::rename` for the policy).
/// The UI is expected to have already shown the user the full old-name/new-name plan
/// and gotten explicit confirmation before calling this - there is no undo yet.
/// Runs off the main thread since real filesystem I/O shouldn't block the UI.
#[tauri::command]
async fn execute_rename(items: Vec<RenamePlanItem>) -> Vec<RenameResult> {
tauri::async_runtime::spawn_blocking(move || rename::execute_renames(&items))
.await
.unwrap_or_default()
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_dialog::init())
.invoke_handler(tauri::generate_handler![
render_expression,
guess_episode,
execute_rename,
files::pick_files,
files::pick_folder,
files::expand_dropped_paths,