use our own trash folder instead of using the system trash
the trash crate was invoking external commands on Macs and Linux which is slow and likely to fall over if a large number of files need to be deleted at once.
This commit is contained in:
parent
660a9bf7ad
commit
e9f51a694c
@ -27,8 +27,8 @@ env_logger = "0.7.1"
|
||||
zip = "0.5.4"
|
||||
log = "0.4.8"
|
||||
serde_tuple = "0.4.0"
|
||||
trash = "1.0.0"
|
||||
coarsetime = "0.1.12"
|
||||
utime = "0.2.1"
|
||||
|
||||
[target.'cfg(target_vendor="apple")'.dependencies]
|
||||
rusqlite = { version = "0.21.0", features = ["trace"] }
|
||||
@ -45,6 +45,3 @@ reqwest = { version = "0.10.1", features = ["json"] }
|
||||
[build-dependencies]
|
||||
prost-build = "0.5.0"
|
||||
|
||||
[dev-dependencies]
|
||||
utime = "0.2.1"
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
|
||||
use crate::err::{AnkiError, Result};
|
||||
use crate::err::Result;
|
||||
use lazy_static::lazy_static;
|
||||
use log::debug;
|
||||
use regex::Regex;
|
||||
use sha1::Sha1;
|
||||
use std::borrow::Cow;
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{fs, io, time};
|
||||
use trash::remove_all;
|
||||
use unicode_normalization::{is_nfc, UnicodeNormalization};
|
||||
use utime;
|
||||
|
||||
/// The maximum length we allow a filename to be. When combined
|
||||
/// with the rest of the path, the full path needs to be under ~240 chars
|
||||
@ -282,12 +282,38 @@ where
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let paths = files.iter().map(|f| media_folder.join(f.as_ref()));
|
||||
let trash_folder = trash_folder(media_folder)?;
|
||||
|
||||
debug!("removing {:?}", files);
|
||||
remove_all(paths).map_err(|e| AnkiError::IOError {
|
||||
info: format!("removing files failed: {:?}", e),
|
||||
})
|
||||
for file in files {
|
||||
let src_path = media_folder.join(file.as_ref());
|
||||
let dst_path = trash_folder.join(file.as_ref());
|
||||
|
||||
// move file to trash, clobbering any existing file with the same name
|
||||
fs::rename(&src_path, &dst_path)?;
|
||||
|
||||
// mark it as modified, so we can expire it in the future
|
||||
let secs = time::SystemTime::now()
|
||||
.duration_since(time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs();
|
||||
utime::set_file_times(&dst_path, secs, secs)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn trash_folder(media_folder: &Path) -> Result<PathBuf> {
|
||||
let trash_folder = media_folder.with_file_name("media.trash");
|
||||
match fs::create_dir(&trash_folder) {
|
||||
Ok(()) => Ok(trash_folder),
|
||||
Err(e) => {
|
||||
if e.kind() == io::ErrorKind::AlreadyExists {
|
||||
Ok(trash_folder)
|
||||
} else {
|
||||
Err(e.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct AddedFile {
|
||||
|
Loading…
Reference in New Issue
Block a user