# MovieMapper Feature Specification ## Project Overview A desktop application for organizing and managing movie and TV show collections with intelligent file mapping using TheTVDB API. ## Current State - Electron-based application (v40.4.1) - TheTVDB v4 API integration with bearer token authentication - FFmpeg-based media file metadata extraction - Basic file renaming and directory navigation - Audit logging to `.audit` files ## Target Architecture - **Main Process**: Rust backend with Node.js Electron bridge - **Renderer Process**: Electron web UI (unchanged) - **Performance**: Native Rust for CPU-intensive operations ## Core Features ### 1. Directory Scanning (Rust Implementation) **Priority**: High **Status**: Current - Node.js, Target - Rust **Requirements**: - Non-recursive directory scanning - Media file detection (mp4, mkv, avi, mov, flv, webm) - FFmpeg metadata extraction (duration, quality, FPS) - Progress callback support for UI updates - Permission error handling **API**: ```rust pub struct FileMetadata { pub path: String, pub name: String, pub size: u64, pub modified: SystemTime, pub duration: String, pub quality: String, pub fps: String, pub is_folder: bool, } pub fn scan_directory( directory_path: &str, progress_callback: Option> ) -> Result, ScanError>; ``` ### 2. FFmpeg Integration (Rust Implementation) **Priority**: High **Status**: Current - fluent-ffmpeg, Target - ffmpeg-kit or rust-ffmpeg **Requirements**: - ffprobe for metadata extraction - Duration calculation (mm:ss format) - Video quality detection (4K, 1440p, 1080p, 720p, 480p) - Frame rate extraction - Graceful error handling for corrupted files **API**: ```rust pub struct VideoStreamInfo { pub width: u32, pub height: u32, pub codec: String, pub frame_rate: f64, } pub struct AudioStreamInfo { pub codec: String, pub channels: u32, pub sample_rate: u32, } pub struct MediaInfo { pub duration: f64, // seconds pub format: String, pub video_streams: Vec, pub audio_streams: Vec, } pub fn probe_file(path: &str) -> Result; ``` ### 3. TheTVDB API Integration (Rust Implementation) **Priority**: High **Status**: Current - axios, Target - reqwest with async/await **Requirements**: - TVDB v4 API authentication (apikey → token) - Show search with query - Show details with seasons - Episode listing per season - Token caching (30-day validity) - Rate limiting handling **API**: ```rust pub struct Show { pub id: u64, pub name: String, pub status: Option, pub first_aired: Option, pub overview: Option, pub image: Option, pub slug: Option, } pub struct Season { pub id: u64, pub number: u32, pub episode_count: u32, } pub struct Episode { pub id: u64, pub name: String, pub number: u32, pub season_number: u32, pub aired: Option, pub overview: Option, } pub struct TVDBClient { token: Option, api_key: String, } impl TVDBClient { pub fn new(api_key: String) -> Self; pub async fn search(&self, query: &str) -> Result, TVDBError>; pub async fn get_show_details(&self, show_id: u64) -> Result; pub async fn get_seasons(&self, show_id: u64) -> Result, TVDBError>; pub async fn get_episodes(&self, show_id: u64, season_number: u32) -> Result, TVDBError>; } ``` ### 4. File Operations (Rust Implementation) **Priority**: High **Status**: Current - Node.js fs, Target - std::fs + tokio **Requirements**: - File renaming with atomic operations - Directory creation (recursive) - File movement to folder (extras, commentary, etc.) - Audit log writing - Conflict detection (duplicate files) **API**: ```rust pub struct AuditLogEntry { pub timestamp: String, pub action: AuditAction, pub details: HashMap, } pub enum AuditAction { RenameFile { old_path: String, new_path: String }, MoveFile { original_path: String, new_path: String, folder: String }, } pub struct FileManager { base_path: String, } impl FileManager { pub fn new(base_path: &str) -> Self; pub async fn rename_file(&self, old_path: &str, new_name: &str) -> Result<(), FileError>; pub async fn move_to_folder(&self, file_path: &str, folder_name: &str) -> Result; pub async fn write_audit_log(&self, action: AuditAction) -> Result<(), FileError>; } ``` ### 5. File Mapping/Batch Rename (Rust Implementation) **Priority**: High **Status**: Current - Node.js, Target - Rust **Requirements**: - Parse show name from folder - Extract season number (multiple formats: "Season 01", "S01", etc.) - Map files to episodes using TVDB data - Handle single episodes and episode ranges (1-3) - Quality suffix support - Folder naming with TVDB ID **API**: ```rust pub struct EpisodeMapping { pub show_name: String, pub season_number: u32, pub episodes: Vec, pub quality: Option, } pub struct EpisodeRange { pub start: u32, pub end: u32, } pub struct MappingResult { pub success_count: u32, pub error_count: u32, pub renamed_files: Vec, } pub async fn begin_mapping( directory: &str, files: Vec, tvdb_id: u64, client: &TVDBClient ) -> Result; ``` ### 6. IPC Bridge (Rust Implementation) **Priority**: Medium **Status**: Current - Direct ipcMain/handle, Target - Node.js addon or IPC socket **Requirements**: - Node.js native addon or IPC interface - Async message handling - Progress event streaming - Error propagation **API**: ```rust #[repr(C)] pub struct IpcMessage { pub channel: *const c_char, pub data: *const c_char, } pub type IpcCallback = extern "C" fn(channel: *const c_char, data: *const c_char); #[no_mangle] pub extern "C" fn init_ipc(callback: IpcCallback); #[no_mangle] pub extern "C" fn handle_request(channel: *const c_char, data: *const c_char) -> *const c_char; ``` ## Implementation Phases ### Phase 1: Core Foundation (Weeks 1-2) - [ ] Set up Rust project structure - [ ] Implement FileMetadata and scan_directory - [ ] Integrate FFmpeg for metadata extraction - [ ] Create basic error types - [ ] Write unit tests for core utilities ### Phase 2: API Integration (Weeks 2-3) - [ ] Implement TVDBClient with authentication - [ ] Add show search functionality - [ ] Implement show details and episode fetching - [ ] Add token caching mechanism - [ ] Write integration tests ### Phase 3: File Operations (Weeks 3-4) - [ ] Implement FileManager with async operations - [ ] Add audit logging - [ ] Implement file movement and renaming - [ ] Add conflict detection - [ ] Write integration tests ### Phase 4: File Mapping (Weeks 4-5) - [ ] Implement begin_mapping logic - [ ] Add episode range handling - [ ] Implement quality suffix logic - [ ] Add folder naming with TVDB ID - [ ] Write integration tests ### Phase 5: IPC Bridge (Weeks 5-6) - [ ] Create Node.js native addon - [ ] Implement message handling - [ ] Add progress streaming - [ ] Handle async callbacks - [ ] Write integration tests ### Phase 6: Testing & Documentation (Weeks 6-7) - [ ] Comprehensive integration tests - [ ] Performance benchmarks - [ ] Documentation - [ ] Migration guide ## Technical Decisions ### FFmpeg Integration **Option A**: ffmpeg-kit (prebuilt binaries) - Pros: Easy setup, cross-platform - Cons: Larger binary size **Option B**: rust-ffmpeg (FFmpeg C bindings) - Pros: Full control, smaller binary - Cons: Build complexity, dependency management **Decision**: ffmpeg-kit for rapid development and reliability ### Async Runtime - tokio for async operations - Standard library for sync operations - Cross-platform async file I/O ### Error Handling - Custom error types with meaningful messages - Consistent error propagation - Detailed logging for debugging ### Testing Strategy - Unit tests for pure functions - Integration tests for file operations - Mock TVDB API for API tests - Benchmark tests for performance-critical paths ## Success Criteria - [ ] All features work identically to Node.js version - [ ] Performance improvement for large directories - [ ] Memory usage below Node.js baseline - [ ] No crashes or memory leaks - [ ] All tests passing - [ ] Documentation complete