# MovieMapper Rust Implementation Plan ## Overview This document outlines the implementation plan for a Rust-based version of MovieMapper. The Rust implementation will focus on the business logic layer while maintaining compatibility with the existing Electron frontend. ## Project Structure ``` Rust/ ├── src/ │ ├── lib.rs │ ├── main.rs │ ├── model/ │ │ ├── mod.rs │ │ ├── file.rs │ │ ├── show.rs │ │ └── episode.rs │ ├── service/ │ │ ├── mod.rs │ │ ├── file_scanner.rs │ │ ├── file_metadata.rs │ │ ├── tvdb_api.rs │ │ ├── file_mapper.rs │ │ ├── audit_logger.rs │ │ └── tag_manager.rs │ ├── utils/ │ │ ├── mod.rs │ │ ├── ffmpeg.rs │ │ ├── path.rs │ │ └── error.rs │ └── config/ │ ├── mod.rs │ └── settings.rs ├── tests/ │ ├── unit/ │ │ ├── file_scanner_tests.rs │ │ ├── file_metadata_tests.rs │ │ ├── tvdb_api_tests.rs │ │ ├── file_mapper_tests.rs │ │ ├── audit_logger_tests.rs │ │ └── tag_manager_tests.rs │ ├── integration/ │ │ ├── integration_tests.rs │ │ └── end_to_end_tests.rs │ └── fixtures/ │ ├── test_files/ │ └── test_data.json ├── Cargo.toml ├── Cargo.lock ├── FEATURES.md (copied from root) └── README.md ``` ## Phase 1: Project Setup and Core Model (Week 1) ### Tasks 1. Initialize Rust project with `cargo new` 2. Configure `Cargo.toml` with dependencies 3. Create model structs 4. Implement basic error handling 5. Set up testing framework ### Dependencies ```toml [dependencies] serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.11", features = ["json"] } thiserror = "1.0" anyhow = "1.0" chrono = { version = "0.4", features = ["serde"] } notify = "6.1" tracing = "0.1" tracing-subscriber = "0.3" ffmpeg-next = "5.0" dirs = "5.0" dotenv = "0.15" [dev-dependencies] tempfile = "3.10" tokio-test = "0.4" ``` ### Model Structs ```rust // src/model/file.rs pub struct MediaFile { pub path: PathBuf, pub name: String, pub size: u64, pub modified: DateTime, pub duration: String, pub quality: String, pub fps: String, pub is_folder: bool, pub is_problematic: bool, pub tags: Vec, } // src/model/show.rs pub struct Show { pub id: i64, pub series_name: String, pub status: String, pub first_aired: Option, pub overview: String, pub image: String, pub slug: String, } // src/model/episode.rs pub struct Episode { pub id: i64, pub name: String, pub number: i32, pub season_number: i32, pub aired: Option, pub runtime: Option, } ``` ### Implementation Checklist - [x] Initialize Rust project - [x] Configure Cargo.toml - [x] Create model structs (File, Show, Episode, Season) - [x] Implement custom error types with `thiserror` - [x] Set up basic logging with `tracing` - [x] Create unit test structure --- ## Phase 2: File Scanning and Metadata Extraction (Week 2) ### Tasks 1. Implement directory scanning 2. Integrate FFmpeg for metadata extraction 3. Implement progress reporting 4. Handle problematic files gracefully 5. Write unit tests for scanning logic ### Key Functions ```rust // src/service/file_scanner.rs pub struct FileScanner { extensions: Vec, } impl FileScanner { pub fn new() -> Self; pub async fn scan_directory( &self, path: &Path, progress_callback: Option<&mut dyn FnMut(usize, usize, &str)>, ) -> Result, ScannerError>; pub fn is_media_file(&self, path: &Path) -> bool; } // src/service/file_metadata.rs pub struct MetadataExtractor; impl MetadataExtractor { pub async fn extract_duration(&self, path: &Path) -> Result; pub async fn extract_quality(&self, path: &Path) -> Result; pub async fn extract_metadata(&self, path: &Path) -> Result; } ``` ### Implementation Checklist - [x] Implement directory scanning (non-recursive) - [x] Integrate FFmpeg for metadata extraction - [x] Handle permission errors gracefully - [x] Implement progress callback support - [x] Add tests for file scanning - [x] Add tests for metadata extraction - [x] Test with problematic files --- ## Phase 3: TVDB API Integration (Week 3) ### Tasks 1. Implement authentication flow 2. Implement search functionality 3. Implement show details fetch 4. Implement season/episode fetch 5. Handle API errors and edge cases 6. Write API integration tests ### Key Functions ```rust // src/service/tvdb_api.rs pub struct TVDBClient { base_url: String, api_key: String, token: Option, } impl TVDBClient { pub async fn new(api_key: &str) -> Result; pub async fn authenticate(&mut self) -> Result<(), TVDBError>; pub async fn search(&self, query: &str) -> Result, TVDBError>; pub async fn get_show_details(&self, show_id: i64) -> Result; pub async fn get_season_episodes( &self, show_id: i64, season_number: i32, ) -> Result, TVDBError>; } ``` ### Implementation Checklist - [x] Implement authentication with token caching - [x] Implement search endpoint - [x] Implement show details endpoint - [x] Implement episodes endpoint - [x] Handle API rate limiting - [x] Add tests for all API endpoints - [x] Test with real API calls --- ## Phase 4: File Mapping and Renaming (Week 4) ### Tasks 1. Implement file mapping logic 2. Implement Jellyfin naming convention 3. Implement episode range handling 4. Implement folder renaming with TVDB ID 5. Handle file conflicts 6. Write comprehensive mapping tests ### Key Functions ```rust // src/service/file_mapper.rs pub struct FileMapper; impl FileMapper { pub async fn map_files( &self, files: &[MediaFile], show_name: &str, season_number: i32, tvdb_id: Option, ) -> Result; pub fn generate_jellyfin_filename( &self, show_name: &str, season: i32, episode_start: i32, episode_end: i32, quality: &str, extension: &str, ) -> String; } ``` ### Implementation Checklist - [x] Implement Jellyfin filename generation - [x] Handle episode ranges - [x] Implement folder renaming - [x] Handle file conflicts - [x] Add tests for mapping logic - [x] Test with various file patterns --- ## Phase 5: Audit Logging and File Operations (Week 5) ### Tasks 1. Implement audit logging 2. Implement file movement 3. Implement folder creation 4. Handle file operations safely 5. Write tests for file operations ### Key Functions ```rust // src/service/audit_logger.rs pub struct AuditLogger; impl AuditLogger { pub fn new(directory: &Path); pub fn log_event(&self, action: &str, details: serde_json::Value) -> Result<(), AuditError>; } // src/service/file_operations.rs pub struct FileOperations; impl FileOperations { pub fn move_file(&self, source: &Path, destination: &Path) -> Result<(), FileError>; pub fn create_folder(&self, path: &Path) -> Result<(), FileError>; pub fn rename_file(&self, old_path: &Path, new_name: &str) -> Result<(), FileError>; } ``` ### Implementation Checklist - [x] Implement audit logging to `.audit` files - [x] Implement safe file movement - [x] Implement folder creation - [x] Implement file renaming - [x] Add tests for audit logging - [x] Add tests for file operations --- ## Phase 6: Tag Management (Week 6) ### Tasks 1. Implement tag data structures 2. Implement tag application/removal 3. Implement bulk tag operations 4. Implement tag-based file movement 5. Write tag management tests ### Key Functions ```rust // src/service/tag_manager.rs pub struct TagManager; impl TagManager { pub fn add_tag(&mut self, file_path: &Path, tag: &str) -> Result<(), TagError>; pub fn remove_tag(&mut self, file_path: &Path, tag: &str) -> Result<(), TagError>; pub fn get_tags(&self, file_path: &Path) -> Vec<&str>; pub fn get_tagged_files(&self, tag: &str) -> Vec<&Path>; pub fn move_tagged_files(&self, tag: &str, target_folder: &Path) -> Result; } ``` ### Implementation Checklist - [x] Implement tag data structures - [x] Implement tag application logic - [x] Implement tag removal logic - [x] Implement bulk operations - [x] Add tests for tag management - [x] Test with multiple tags --- ## Phase 7: Integration and End-to-End Testing (Week 7) ### Tasks 1. Write integration tests 2. Write end-to-end tests 3. Test with real file system 4. Test with TVDB API 5. Test error handling 6. Performance testing ### Test Scenarios ```rust // tests/integration/file_scanner_tests.rs #[tokio::test] async fn test_scan_directory_with_media_files() { // Create test directory structure // Scan directory // Verify results } // tests/integration/tvdb_api_tests.rs #[tokio::test] async fn test_search_and_fetch_details() { // Search for a show // Fetch details // Verify results } // tests/integration/file_mapping_tests.rs #[tokio::test] async fn test_map_files_to_jellyfin_format() { // Create test files // Map files // Verify renamed files } ``` ### Implementation Checklist - [x] Write integration tests for all modules - [x] Write end-to-end tests - [x] Test with real file system - [x] Test with TVDB API - [x] Add error handling tests - [x] Performance testing --- ## Phase 8: Documentation and Examples (Week 8) ### Tasks 1. Write comprehensive documentation 2. Create example usage 3. Write migration guide 4. Create troubleshooting guide 5. Write benchmark tests ### Documentation Checklist - [x] API documentation with `cargo doc` - [x] User guide - [x] Developer guide - [x] Migration guide from JavaScript version - [x] Troubleshooting guide - [x] Performance benchmarks --- ## Testing Strategy ### Unit Tests - Test individual functions in isolation - Mock external dependencies (FFmpeg, TVDB API) - Aim for 90%+ code coverage ### Integration Tests - Test module interactions - Test with real file system - Test with TVDB API ### End-to-End Tests - Test complete workflows - Test error scenarios - Test edge cases ### Test Commands ```bash # Run all tests cargo test # Run unit tests only cargo test --lib # Run integration tests cargo test --test integration # Run with coverage cargo tarpaulin # Run benchmarks cargo bench ``` --- ## Known Challenges and Solutions ### Challenge 1: FFmpeg Integration **Solution**: Use `ffmpeg-next` crate for FFmpeg bindings. Handle errors gracefully and provide fallback values. ### Challenge 2: TVDB API Authentication **Solution**: Implement token caching with expiration. Handle token refresh automatically. ### Challenge 3: File System Operations **Solution**: Use `notify` crate for file system events. Implement atomic file operations. ### Challenge 4: Progress Reporting **Solution**: Use callback functions for progress updates. Implement async/await for non-blocking operations. ### Challenge 5: Cross-Platform Path Handling **Solution**: Use `PathBuf` and `Path` for all path operations. Handle platform-specific path separators. --- ## Success Criteria - [x] All features from JavaScript version implemented - [x] 90%+ test coverage - [x] All tests passing - [x] Documentation complete - [x] Performance meets or exceeds JavaScript version - [x] No memory leaks - [x] Clean error handling --- ## Future Enhancements 1. **Caching Layer**: Implement caching for TVDB API responses 2. **Database Integration**: Store show and file information 3. **Advanced File Matching**: Better episode identification algorithms 4. **Export Functionality**: Export organized collections 5. **Drag and Drop UI**: Native drag and drop support 6. **Batch Operations**: Support for batch file operations