fix: not all files directory are trash
This commit is contained in:
parent
a93fc1d9ee
commit
8ef1082a4c
2 changed files with 41 additions and 6 deletions
22
src/tab.rs
22
src/tab.rs
|
|
@ -939,11 +939,24 @@ fn item_from_trash_child(
|
||||||
metadata: fs::Metadata,
|
metadata: fs::Metadata,
|
||||||
sizes: IconSizes,
|
sizes: IconSizes,
|
||||||
) -> Option<Item> {
|
) -> Option<Item> {
|
||||||
let original_path = crate::trash::original_path_for_trash_child(&path)?;
|
let Some(original_path) = crate::trash::original_path_for_trash_child(&path) else {
|
||||||
|
log::warn!(
|
||||||
|
"failed to resolve original path for trash item {}, skipping entry",
|
||||||
|
path.display()
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let Some(original_parent) = original_path.parent() else {
|
||||||
|
log::warn!(
|
||||||
|
"trash item {} has no original parent, skipping entry",
|
||||||
|
path.display()
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
};
|
||||||
let entry = trash::TrashItem {
|
let entry = trash::TrashItem {
|
||||||
id: path.as_os_str().to_os_string(),
|
id: path.as_os_str().to_os_string(),
|
||||||
name: std::ffi::OsString::from(&name),
|
name: std::ffi::OsString::from(&name),
|
||||||
original_parent: original_path.parent()?.to_path_buf(),
|
original_parent: original_parent.to_path_buf(),
|
||||||
time_deleted: 0,
|
time_deleted: 0,
|
||||||
};
|
};
|
||||||
let size = if metadata.is_dir() {
|
let size = if metadata.is_dir() {
|
||||||
|
|
@ -1033,6 +1046,7 @@ pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec<Item> {
|
||||||
if !remote_scannable {
|
if !remote_scannable {
|
||||||
match fs::read_dir(tab_path) {
|
match fs::read_dir(tab_path) {
|
||||||
Ok(entries) => {
|
Ok(entries) => {
|
||||||
|
let trash = crate::trash::is_trash_path(tab_path);
|
||||||
items = entries
|
items = entries
|
||||||
.filter_map(|entry_res| {
|
.filter_map(|entry_res| {
|
||||||
let entry = entry_res
|
let entry = entry_res
|
||||||
|
|
@ -1073,7 +1087,6 @@ pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec<Item> {
|
||||||
})
|
})
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
let trash = crate::trash::is_trash_path(tab_path);
|
|
||||||
if trash {
|
if trash {
|
||||||
item_from_trash_child(path, name, metadata, sizes)
|
item_from_trash_child(path, name, metadata, sizes)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -7003,7 +7016,8 @@ impl Tab {
|
||||||
let path = path.clone();
|
let path = path.clone();
|
||||||
|
|
||||||
// Acquire semaphore permit
|
// Acquire semaphore permit
|
||||||
_ = THUMB_SEMAPHORE.acquire().await;
|
let _permit =
|
||||||
|
THUMB_SEMAPHORE.acquire().await.unwrap();
|
||||||
|
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
|
||||||
25
src/trash.rs
25
src/trash.rs
|
|
@ -2,6 +2,7 @@ use cosmic::widget;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
use crate::config::IconSizes;
|
use crate::config::IconSizes;
|
||||||
use crate::tab::{Item, SearchItem};
|
use crate::tab::{Item, SearchItem};
|
||||||
|
|
@ -89,7 +90,7 @@ pub fn trash_item_path(item: &trash::TrashItem) -> Option<PathBuf> {
|
||||||
/// - Read `~/.local/share/Trash/info/folder.trashinfo` to get the original path
|
/// - Read `~/.local/share/Trash/info/folder.trashinfo` to get the original path
|
||||||
/// - Compute: `<original_path>/sub/file.txt`
|
/// - Compute: `<original_path>/sub/file.txt`
|
||||||
pub fn original_path_for_trash_child(p: &Path) -> Option<PathBuf> {
|
pub fn original_path_for_trash_child(p: &Path) -> Option<PathBuf> {
|
||||||
let files = p.ancestors().find(|a| a.ends_with("files"))?;
|
let files = trash_files_dir(p)?;
|
||||||
let root = files.parent()?;
|
let root = files.parent()?;
|
||||||
let top = p.strip_prefix(files).ok()?.components().next()?;
|
let top = p.strip_prefix(files).ok()?.components().next()?;
|
||||||
let info =
|
let info =
|
||||||
|
|
@ -103,9 +104,29 @@ pub fn original_path_for_trash_child(p: &Path) -> Option<PathBuf> {
|
||||||
Some(result)
|
Some(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TRASH_FOLDERS: LazyLock<HashSet<PathBuf>> = LazyLock::new(|| {
|
||||||
|
Trash::folders().unwrap_or_else(|e| {
|
||||||
|
log::warn!("failed to list trash folders: {}", e);
|
||||||
|
HashSet::new()
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
fn is_trash_root(root: &Path) -> bool {
|
||||||
|
if TRASH_FOLDERS.is_empty() {
|
||||||
|
root.join("info").is_dir()
|
||||||
|
} else {
|
||||||
|
TRASH_FOLDERS.contains(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trash_files_dir(path: &Path) -> Option<&Path> {
|
||||||
|
path.ancestors()
|
||||||
|
.find(|a| a.ends_with("files") && a.parent().is_some_and(is_trash_root))
|
||||||
|
}
|
||||||
|
|
||||||
/// Check whether a path is inside any trash `files/` directory.
|
/// Check whether a path is inside any trash `files/` directory.
|
||||||
pub fn is_trash_path(path: &Path) -> bool {
|
pub fn is_trash_path(path: &Path) -> bool {
|
||||||
path.ancestors().any(|a| a.ends_with("files"))
|
trash_files_dir(path).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Trash;
|
pub struct Trash;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue