diff --git a/src/main.rs b/src/main.rs index 8865e41..2bd7b48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,19 @@ use clap::{arg, command, value_parser}; +use ratatui::crossterm::event::{self, Event, KeyCode, KeyModifiers}; use ratatui::layout::{Constraint::Max, Layout}; use ratatui::text::Line; use ratatui::widgets::{Block, Paragraph, Wrap}; use ratatui::Frame; -use ratatui::crossterm::event::{self, Event, KeyCode, KeyModifiers}; use serde::Deserialize; use serde_json::from_reader; use std::cmp::PartialEq; use std::fs::{copy, File}; use std::path::PathBuf; +use std::process::exit; use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; use std::sync::{Arc, Mutex}; use std::thread::{sleep, spawn}; use std::time::{Duration, SystemTime}; -use std::process::exit; const VIDEO: [&str; 8] = ["mp4", "webm", "mov", "avi", "wmv", "flv", "mkv", "qt"]; const AUDIO: [&str; 4] = ["mp3", "wav", "ogg", "opus"]; @@ -25,7 +25,7 @@ enum Progress { Done, } -#[derive(Deserialize)] +#[derive(Deserialize, Clone)] struct Config { video: PathBuf, audio: PathBuf, @@ -33,10 +33,20 @@ struct Config { document: PathBuf, } +impl Config { + fn contains(&self, path: &PathBuf) -> bool { + if &self.video == path || &self.audio == path || &self.image == path || &self.document == path { + true + } else { + false + } + } +} + struct Status { progress: Progress, path: PathBuf, - message: String + message: String, } impl Default for Status { @@ -44,7 +54,7 @@ impl Default for Status { Status { progress: Progress::Working, path: PathBuf::new(), - message: String::new() + message: String::new(), } } } @@ -57,20 +67,20 @@ struct FileMover { } impl FileFinder { - fn run(self, folder: &PathBuf) -> Arc> { + fn run(self, folder: &PathBuf, config: Config) -> Arc> { let folder = folder.clone(); let status = Arc::new(Mutex::new(Status::default())); let status_clone = status.clone(); spawn(move || { if folder.is_dir() { - self.read_folder(folder, status_clone.clone()); + self.read_folder(folder, status_clone.clone(), &config); } status_clone.lock().unwrap().progress = Progress::Done; }); status } - fn read_folder(&self, folder: PathBuf, status: Arc>) { + fn read_folder(&self, folder: PathBuf, status: Arc>, config: &Config) { let mut now = SystemTime::now(); if let Ok(dir_iter) = folder.read_dir() { for entry in dir_iter { @@ -85,7 +95,9 @@ impl FileFinder { } } if path.is_dir() { - self.read_folder(path, status.clone()); + if !config.contains(&path) { + self.read_folder(path, status.clone(), config); + } } else if path.is_file() { self.sender .send(path) @@ -101,12 +113,10 @@ impl FileFinder { } impl FileMover { - fn run(self, config: &PathBuf) -> Arc> { + fn run(self, config: Config) -> Arc> { let mut now = SystemTime::now(); let status = Arc::new(Mutex::new(Status::default())); let status_clone = status.clone(); - let config_file = File::open(config).expect("Could not open config file"); - let config: Config = from_reader(config_file).expect("Could not parse config file"); spawn(move || { for file in self.receiver.iter() { if let Ok(elapsed) = now.elapsed() { @@ -132,12 +142,18 @@ impl FileMover { if let Some(destination) = destination { let result = copy(&file, &destination); if result.is_err() { - status_clone.lock().unwrap().message = format!("Error: Could not copy file {:?}\n{}", file.file_name().unwrap(), result.err().unwrap()); + status_clone.lock().unwrap().message = format!( + "Error: Could not copy file {:?}\n{}", + file.file_name().unwrap(), + result.err().unwrap() + ); } else { - status_clone.lock().unwrap().message = format!("Successfully copied file {:?}", file.file_name().unwrap()); + status_clone.lock().unwrap().message = format!( + "Successfully copied file {:?}", + file.file_name().unwrap() + ); } } - } } sleep(Duration::from_millis(100)); @@ -177,7 +193,10 @@ fn main() { let finder = FileFinder::new(sender); let mover = FileMover::new(receiver); - let finder_status = finder.run(folder); + let config_file = File::open(config).expect("Could not open config file"); + let config: Config = from_reader(config_file).expect("Could not parse config file"); + + let finder_status = finder.run(folder, config.clone()); let mover_status = mover.run(config); while finder_status.lock().unwrap().progress == Progress::Working @@ -187,20 +206,24 @@ fn main() { .draw(|frame: &mut Frame| { let layout = Layout::vertical([Max(5), Max(5)]); let [reader_area, mover_area] = layout.areas(frame.area()); - let reader = vec![Line::from(format!( - "Discovered: {:?}", - finder_status.lock().unwrap().path - )), - Line::from(finder_status.lock().unwrap().message.clone())]; + let reader = vec![ + Line::from(format!( + "Discovered: {:?}", + finder_status.lock().unwrap().path + )), + Line::from(finder_status.lock().unwrap().message.clone()), + ]; let reader_paragraph = Paragraph::new(reader) .block(Block::bordered().title("FileFinder status")) .centered() .wrap(Wrap { trim: true }); - let mover = vec![Line::from(format!( - "Current file: {:?}", - mover_status.lock().unwrap().path - )), - Line::from(mover_status.lock().unwrap().message.clone())]; + let mover = vec![ + Line::from(format!( + "Current file: {:?}", + mover_status.lock().unwrap().path + )), + Line::from(mover_status.lock().unwrap().message.clone()), + ]; let mover_paragraph = Paragraph::new(mover) .block(Block::bordered().title("FileMover status")) .centered() @@ -212,14 +235,15 @@ fn main() { if event::poll(Duration::from_millis(100)).unwrap() { let ev = event::read().unwrap(); match ev { - Event::Key(key) if key.code == KeyCode::Char('c') && key.modifiers == KeyModifiers::CONTROL => { + Event::Key(key) + if key.code == KeyCode::Char('c') && key.modifiers == KeyModifiers::CONTROL => + { ratatui::restore(); exit(0); } _ => {} - } + } } - } ratatui::restore();