summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJannis M. Hoffmann <jannis@fehcom.de>2024-11-11 21:22:38 +0100
committerJannis M. Hoffmann <jannis@fehcom.de>2024-11-11 21:22:38 +0100
commit4406d97de9ce88a1f36bc4a33aed6cbd8ba74b44 (patch)
treece0172e1ef2320392c24ebf149ff071b1366b0f7
parentd0e91b16a59e9f706ed63407af27c2e03a757d87 (diff)
detect subfolder more reliably and relax parsing rules for time stamps in file names
-rw-r--r--src/cmd/folders.rs55
-rw-r--r--src/cmd/list.rs5
2 files changed, 31 insertions, 29 deletions
diff --git a/src/cmd/folders.rs b/src/cmd/folders.rs
index b50daa9..417203c 100644
--- a/src/cmd/folders.rs
+++ b/src/cmd/folders.rs
@@ -1,50 +1,49 @@
-use std::collections::BTreeSet;
-use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
-use std::sync::LazyLock;
use protobuf::Message as _;
use crate::error::Result;
use crate::pb3::jwebmail::{FoldersReq, FoldersResp};
-static REQUIRED_MAILDIR_DIRS: LazyLock<BTreeSet<OsString>> = LazyLock::new(|| {
- [
- OsString::from("cur"),
- "new".into(),
- "tmp".into(),
- "maildirfolder".into(),
- ]
- .into()
-});
-
fn is_mailsubdir(p: &Path) -> bool {
- p.is_dir()
- && p.file_name()
- .map_or(false, |fname| fname.to_string_lossy().starts_with('.'))
- && p.read_dir()
- .map(|dir| {
- dir.filter_map(|child| {
- child
- .ok()
- .and_then(|dir_entry| dir_entry.path().file_name().map(OsStr::to_owned))
- })
- .collect::<BTreeSet<_>>()
- .is_superset(&*REQUIRED_MAILDIR_DIRS)
- })
- .unwrap_or_default()
+ if !p.is_dir() {
+ return false;
+ }
+ if !p.file_name().map_or(false, |fname| {
+ fname.len() > 1 && fname.to_string_lossy().starts_with('.')
+ }) {
+ return false;
+ }
+ let mut buf = p.to_owned();
+ buf.push("cur");
+ if !buf.is_dir() {
+ return false;
+ }
+ buf.pop();
+ buf.push("new");
+ if !buf.is_dir() {
+ return false;
+ }
+ buf.pop();
+ buf.push("tmp");
+ if !buf.is_dir() {
+ return false;
+ }
+ true
}
pub fn folders(path: PathBuf, req: &[u8]) -> Result<Vec<u8>> {
let _ = FoldersReq::parse_from_bytes(req)?;
- let subdirs = path
+ let mut subdirs: Vec<_> = path
.read_dir()?
.filter_map(|d| d.ok())
.filter(|d| is_mailsubdir(&d.path()))
.filter_map(|d| Some(d.path().file_name()?.to_string_lossy()[1..].to_owned()))
.collect();
+ subdirs.sort();
+
let mut res = FoldersResp::new();
res.folders = subdirs;
res.write_to_bytes().map_err(|e| e.into())
diff --git a/src/cmd/list.rs b/src/cmd/list.rs
index f34c333..3c2d42a 100644
--- a/src/cmd/list.rs
+++ b/src/cmd/list.rs
@@ -29,7 +29,10 @@ fn mid_to_rec_time(mid: &str) -> f64 {
let Some(sep) = mid[dec + 1..].find('.') else {
return 0.0;
};
- mid[..dec + 1 + sep].parse().unwrap()
+ mid[..dec + 1 + sep]
+ .parse()
+ .or_else(|_| mid[..dec].parse())
+ .unwrap_or(0.0)
}
fn sort_by_and_take(