Checks if folder is a destination folder
This commit is contained in:
82
src/main.rs
82
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<Mutex<Status>> {
|
||||
fn run(self, folder: &PathBuf, config: Config) -> Arc<Mutex<Status>> {
|
||||
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<Mutex<Status>>) {
|
||||
fn read_folder(&self, folder: PathBuf, status: Arc<Mutex<Status>>, 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<Mutex<Status>> {
|
||||
fn run(self, config: Config) -> Arc<Mutex<Status>> {
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user