mirror of
https://github.com/Dummi26/tuifile.git
synced 2025-04-28 09:16:03 +02:00
124 lines
3.9 KiB
Rust
Executable File
124 lines
3.9 KiB
Rust
Executable File
use std::{
|
|
collections::HashSet,
|
|
fs, io,
|
|
os::unix::prelude::PermissionsExt,
|
|
path::{Path, PathBuf},
|
|
time::Duration,
|
|
};
|
|
|
|
use crate::{BackgroundTask, Share};
|
|
|
|
pub(crate) fn task_copy(
|
|
src: Vec<(PathBuf, Vec<(PathBuf, bool)>)>,
|
|
target: PathBuf,
|
|
share: &mut Share,
|
|
) {
|
|
share.tasks.push(BackgroundTask::new(
|
|
"cp".to_string(),
|
|
move |status| {
|
|
let mut total: usize = src.iter().map(|v| v.1.len()).sum();
|
|
for (parent, rel_paths) in src {
|
|
let mut created: HashSet<PathBuf> = HashSet::new();
|
|
for (rel_path, copy_recursive) in rel_paths {
|
|
total = total.saturating_sub(1);
|
|
{
|
|
let s = format!("cp {total}");
|
|
*status.lock().unwrap() = s;
|
|
}
|
|
let file_from = parent.join(&rel_path);
|
|
let file_to = target.join(&rel_path);
|
|
let is_dir = file_from.is_dir();
|
|
let parent_created = if let Some(parent) = rel_path.parent() {
|
|
parent.as_os_str().is_empty() || created.contains(parent)
|
|
} else {
|
|
true
|
|
};
|
|
if parent_created {
|
|
if is_dir {
|
|
copy_dir(file_from, file_to, copy_recursive);
|
|
created.insert(rel_path);
|
|
} else {
|
|
fs::copy(&file_from, &file_to);
|
|
}
|
|
} else {
|
|
let rel_path = rel_path.file_name().unwrap();
|
|
let file_to = target.join(&rel_path);
|
|
if is_dir {
|
|
copy_dir(file_from, file_to, copy_recursive);
|
|
created.insert(rel_path.into());
|
|
} else {
|
|
fs::copy(&file_from, &file_to);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
},
|
|
true,
|
|
));
|
|
}
|
|
fn copy_dir(
|
|
file_from: impl AsRef<Path>,
|
|
file_to: impl AsRef<Path>,
|
|
recursive: bool,
|
|
) -> io::Result<()> {
|
|
fs::create_dir(&file_to)?;
|
|
if recursive {
|
|
if let Ok(e) = fs::read_dir(file_from) {
|
|
for e in e {
|
|
if let Ok(e) = e {
|
|
let p = e.path();
|
|
let t = file_to.as_ref().join(e.file_name());
|
|
if p.is_dir() {
|
|
copy_dir(p, t, recursive);
|
|
} else {
|
|
fs::copy(&p, &t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) fn task_del(paths: Vec<PathBuf>, share: &mut Share) {
|
|
let mut total: usize = paths.len();
|
|
share.tasks.push(BackgroundTask::new(
|
|
format!("rm {total}"),
|
|
move |status| {
|
|
for path in paths {
|
|
{
|
|
total -= 1;
|
|
let s = format!("rm {total}");
|
|
*status.lock().unwrap() = s;
|
|
}
|
|
if path.is_dir() {
|
|
fs::remove_dir(path);
|
|
} else {
|
|
fs::remove_file(path);
|
|
}
|
|
}
|
|
Ok(())
|
|
},
|
|
true,
|
|
));
|
|
}
|
|
pub(crate) fn task_chmod(paths: Vec<PathBuf>, mode: u32, share: &mut Share) {
|
|
let mut total = paths.len();
|
|
share.tasks.push(BackgroundTask::new(
|
|
format!("chmod {total}"),
|
|
move |status| {
|
|
for path in paths {
|
|
{
|
|
total -= 1;
|
|
let s = format!("chmod {total}");
|
|
*status.lock().unwrap() = s;
|
|
}
|
|
fs::set_permissions(path, fs::Permissions::from_mode(mode));
|
|
}
|
|
Ok(())
|
|
},
|
|
true,
|
|
));
|
|
}
|