Removing some unnecessary clones and other small fixes

This commit is contained in:
Ericson Fogo Soares 2023-01-20 18:22:17 -03:00
parent bfe14c5668
commit 7aa644c7a2
5 changed files with 72 additions and 70 deletions

View File

@ -1,8 +1,12 @@
use super::{context_menu_fs_info, get_path_from_location_id, osstr_to_string, FsInfo, ObjectType};
use crate::job::{JobError, JobReportUpdate, JobResult, JobState, StatefulJob, WorkerContext};
use std::{hash::Hash, path::PathBuf};
use serde::{Deserialize, Serialize};
use specta::Type;
use std::{collections::VecDeque, hash::Hash, path::PathBuf};
use tracing::trace;
use super::{context_menu_fs_info, get_path_from_location_id, osstr_to_string, FsInfo, ObjectType};
pub struct FileCopierJob {}
@ -31,8 +35,8 @@ const JOB_NAME: &str = "file_copier";
#[async_trait::async_trait]
impl StatefulJob for FileCopierJob {
type Data = FileCopierJobState;
type Init = FileCopierJobInit;
type Data = FileCopierJobState;
type Step = FileCopierJobStep;
fn name(&self) -> &'static str {
@ -51,25 +55,23 @@ impl StatefulJob for FileCopierJob {
get_path_from_location_id(&ctx.library_ctx.db, state.init.target_location_id).await?;
// add the currently viewed subdirectory to the location root
full_target_path.push(state.init.target_path.clone());
full_target_path.push(&state.init.target_path);
// extension wizardry for cloning and such
// if no suffix has been selected, just use the file name
// if a suffix is provided and it's a directory, use the directory name + suffix
// if a suffix is provided and it's a file, use the (file name + suffix).extension
let file_name = osstr_to_string(source_fs_info.obj_path.clone().file_name())?;
let file_name = osstr_to_string(source_fs_info.obj_path.file_name())?;
let target_file_name = state.init.target_file_name_suffix.as_ref().map_or(
Ok::<_, JobError>(file_name.clone()),
let target_file_name = state.init.target_file_name_suffix.as_ref().map_or_else(
|| Ok::<_, JobError>(file_name.clone()),
|s| match source_fs_info.obj_type {
ObjectType::Directory => Ok(file_name.clone() + s),
ObjectType::Directory => Ok(format!("{file_name}{s}")),
ObjectType::File => Ok(osstr_to_string(source_fs_info.obj_path.file_stem())?
+ s + &source_fs_info
.obj_path
.extension()
.map_or(Ok::<_, JobError>("".to_string()), |x| {
Ok(".".to_string() + x.to_str().ok_or(JobError::OsStr)?)
})?),
+ s + &source_fs_info.obj_path.extension().map_or_else(
|| Ok::<_, JobError>(String::new()),
|x| Ok(format!(".{}", x.to_str().ok_or(JobError::OsStr)?)),
)?),
},
)?;
@ -81,8 +83,7 @@ impl StatefulJob for FileCopierJob {
root_type: source_fs_info.obj_type.clone(),
});
state.steps = VecDeque::new();
state.steps.push_back(FileCopierJobStep { source_fs_info });
state.steps = [FileCopierJobStep { source_fs_info }].into_iter().collect();
ctx.progress(vec![JobReportUpdate::TaskCount(state.steps.len())]);
@ -94,10 +95,10 @@ impl StatefulJob for FileCopierJob {
ctx: WorkerContext,
state: &mut JobState<Self>,
) -> Result<(), JobError> {
let step = state.steps[0].clone();
let step = &state.steps[0];
let info = &step.source_fs_info;
let job_state = state.data.clone().ok_or(JobError::MissingData {
let job_state = state.data.as_ref().ok_or(JobError::MissingData {
value: String::from("job state"),
})?;
@ -114,6 +115,8 @@ impl StatefulJob for FileCopierJob {
);
}
trace!("Copying from {:?} to {:?}", info.obj_path, path);
tokio::fs::copy(&info.obj_path, &path).await?;
}
ObjectType::Directory => {
@ -137,15 +140,15 @@ impl StatefulJob for FileCopierJob {
},
});
let mut path = job_state.target_path.clone();
path.push(
entry
.path()
.strip_prefix(&job_state.source_path)
.map_err(|_| JobError::Path)?,
);
tokio::fs::create_dir_all(path).await?;
tokio::fs::create_dir_all(
job_state.target_path.join(
entry
.path()
.strip_prefix(&job_state.source_path)
.map_err(|_| JobError::Path)?,
),
)
.await?;
} else {
state.steps.push_back(FileCopierJobStep {
source_fs_info: FsInfo {

View File

@ -1,8 +1,12 @@
use super::{context_menu_fs_info, get_path_from_location_id, FsInfo};
use crate::job::{JobError, JobReportUpdate, JobResult, JobState, StatefulJob, WorkerContext};
use std::{hash::Hash, path::PathBuf};
use serde::{Deserialize, Serialize};
use specta::Type;
use std::{collections::VecDeque, hash::Hash, path::PathBuf};
use tracing::trace;
use super::{context_menu_fs_info, get_path_from_location_id, FsInfo};
pub struct FileCutterJob {}
@ -27,8 +31,8 @@ const JOB_NAME: &str = "file_cutter";
#[async_trait::async_trait]
impl StatefulJob for FileCutterJob {
type Data = FileCutterJobState;
type Init = FileCutterJobInit;
type Data = FileCutterJobState;
type Step = FileCutterJobStep;
fn name(&self) -> &'static str {
@ -45,13 +49,14 @@ impl StatefulJob for FileCutterJob {
let mut full_target_path =
get_path_from_location_id(&ctx.library_ctx.db, state.init.target_location_id).await?;
full_target_path.push(state.init.target_path.clone());
full_target_path.push(&state.init.target_path);
state.steps = VecDeque::new();
state.steps.push_back(FileCutterJobStep {
state.steps = [FileCutterJobStep {
source_fs_info,
target_directory: full_target_path,
});
}]
.into_iter()
.collect();
ctx.progress(vec![JobReportUpdate::TaskCount(state.steps.len())]);
@ -66,19 +71,13 @@ impl StatefulJob for FileCutterJob {
let step = &state.steps[0];
let source_info = &step.source_fs_info;
let mut full_output = step.target_directory.clone();
full_output.push(
source_info
.obj_path
.clone()
.file_name()
.ok_or(JobError::OsStr)?,
);
let full_output = step
.target_directory
.join(source_info.obj_path.file_name().ok_or(JobError::OsStr)?);
dbg!(source_info.obj_path.clone());
dbg!(full_output.clone());
trace!("Cutting {:?} to {:?}", source_info.obj_path, full_output);
tokio::fs::rename(source_info.obj_path.clone(), full_output.clone()).await?;
tokio::fs::rename(&source_info.obj_path, &full_output).await?;
ctx.progress(vec![JobReportUpdate::CompletedTaskCount(
state.step_number + 1,

View File

@ -1,10 +1,13 @@
use super::{context_menu_fs_info, osstr_to_string, FsInfo, ObjectType};
use crate::job::{JobError, JobReportUpdate, JobResult, JobState, StatefulJob, WorkerContext};
use std::{hash::Hash, path::PathBuf};
use serde::{Deserialize, Serialize};
use specta::Type;
use std::{collections::VecDeque, hash::Hash, path::PathBuf};
use tokio::{fs::OpenOptions, io::AsyncWriteExt};
use tracing::warn;
use tracing::{trace, warn};
use super::{context_menu_fs_info, osstr_to_string, FsInfo, ObjectType};
pub struct FileEraserJob {}
@ -30,8 +33,8 @@ const JOB_NAME: &str = "file_eraser";
#[async_trait::async_trait]
impl StatefulJob for FileEraserJob {
type Data = FileEraserJobState;
type Init = FileEraserJobInit;
type Data = FileEraserJobState;
type Step = FileEraserJobStep;
fn name(&self) -> &'static str {
@ -51,8 +54,7 @@ impl StatefulJob for FileEraserJob {
root_type: fs_info.obj_type.clone(),
});
state.steps = VecDeque::new();
state.steps.push_back(FileEraserJobStep { fs_info });
state.steps = [FileEraserJobStep { fs_info }].into_iter().collect();
ctx.progress(vec![JobReportUpdate::TaskCount(state.steps.len())]);
@ -64,7 +66,7 @@ impl StatefulJob for FileEraserJob {
ctx: WorkerContext,
state: &mut JobState<Self>,
) -> Result<(), JobError> {
let step = state.steps[0].clone();
let step = &state.steps[0];
let info = &step.fs_info;
// need to handle stuff such as querying prisma for all paths of a file, and deleting all of those if requested (with a checkbox in the ui)
@ -75,7 +77,7 @@ impl StatefulJob for FileEraserJob {
let mut file = OpenOptions::new()
.read(true)
.write(true)
.open(info.obj_path.clone())
.open(&info.obj_path)
.await?;
let file_len = file.metadata().await?.len();
@ -85,29 +87,29 @@ impl StatefulJob for FileEraserJob {
file.flush().await?;
drop(file);
tokio::fs::remove_file(info.obj_path.clone()).await?;
trace!("Erasing file: {:?}", info.obj_path);
tokio::fs::remove_file(&info.obj_path).await?;
}
ObjectType::Directory => {
let mut dir = tokio::fs::read_dir(&info.obj_path).await?;
while let Some(entry) = dir.next_entry().await? {
if entry.metadata().await?.is_dir() {
let obj_type = ObjectType::Directory;
state.steps.push_back(FileEraserJobStep {
fs_info: FsInfo {
obj_id: None,
obj_name: String::new(),
obj_path: entry.path(),
obj_type,
obj_type: ObjectType::Directory,
},
});
} else {
let obj_type = ObjectType::File;
state.steps.push_back(FileEraserJobStep {
fs_info: FsInfo {
obj_id: None,
obj_name: osstr_to_string(Some(&entry.file_name()))?,
obj_path: entry.path(),
obj_type,
obj_type: ObjectType::File,
},
});
};
@ -124,9 +126,9 @@ impl StatefulJob for FileEraserJob {
}
async fn finalize(&self, _ctx: WorkerContext, state: &mut JobState<Self>) -> JobResult {
if let Some(info) = state.data.clone() {
if let Some(ref info) = state.data {
if info.root_type == ObjectType::Directory {
tokio::fs::remove_dir_all(info.root_path).await?;
tokio::fs::remove_dir_all(&info.root_path).await?;
}
} else {
warn!("missing job state, unable to fully finalise erase job");

View File

@ -1,12 +1,12 @@
use std::{ffi::OsStr, path::PathBuf};
use serde::{Deserialize, Serialize};
use crate::{
job::JobError,
prisma::{file_path, location, PrismaClient},
};
use std::{ffi::OsStr, path::PathBuf};
use serde::{Deserialize, Serialize};
pub mod copy;
pub mod cut;
pub mod decrypt;
@ -76,9 +76,7 @@ pub async fn context_menu_fs_info(
value: String::from("file_path that matches both location id and path id"),
})?;
let obj_path = [location_path, item.materialized_path.clone().into()]
.iter()
.collect();
let obj_path = location_path.join(&item.materialized_path);
// i don't know if this covers symlinks
let obj_type = if item.is_dir {

View File

@ -1,8 +1,8 @@
use crate::{primitives::BLOCK_SIZE, Result};
use rand::{RngCore, SeedableRng};
use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt};
use crate::{primitives::BLOCK_SIZE, Result};
/// This is used for erasing a file.
///
/// It requires the file size, a stream and the amount of passes (to overwrite the entire stream with random data)
@ -16,7 +16,7 @@ use crate::{primitives::BLOCK_SIZE, Result};
/// This also does not factor in temporary files, caching, thumbnails, etc.
pub async fn erase<RW>(stream: &mut RW, size: usize, passes: usize) -> Result<()>
where
RW: AsyncReadExt + AsyncWriteExt + AsyncSeekExt + Unpin,
RW: AsyncReadExt + AsyncWriteExt + AsyncSeekExt + Unpin + Send,
{
let block_count = size / BLOCK_SIZE;
let additional = size % BLOCK_SIZE;