Checks if folder is a destination folder

This commit is contained in:
2025-01-24 00:12:25 +01:00
parent f04208669b
commit 5dc724035e

View File

@@ -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!(
let reader = vec![
Line::from(format!(
"Discovered: {:?}",
finder_status.lock().unwrap().path
)),
Line::from(finder_status.lock().unwrap().message.clone())];
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!(
let mover = vec![
Line::from(format!(
"Current file: {:?}",
mover_status.lock().unwrap().path
)),
Line::from(mover_status.lock().unwrap().message.clone())];
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();