From 921191340516038a3152769444aa6963eefce75c Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Wed, 18 Dec 2019 15:44:44 +0200 Subject: [PATCH] meli/backends: honor mailbox subscriptions in IMAP/JMAP --- melib/src/backends/imap.rs | 18 ++++++++ melib/src/backends/imap/protocol_parser.rs | 3 +- melib/src/backends/jmap.rs | 22 ++++----- ui/src/components/mail/status.rs | 53 ++++++++++++++++++++++ 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/melib/src/backends/imap.rs b/melib/src/backends/imap.rs index 2ec7589e..0329887e 100644 --- a/melib/src/backends/imap.rs +++ b/melib/src/backends/imap.rs @@ -378,6 +378,7 @@ impl MailBackend for ImapType { drop(uid_lock); Ok(folders .iter() + .filter(|(_, f)| f.is_subscribed) .map(|(h, f)| (*h, Box::new(Clone::clone(f)) as Folder)) .collect()) } @@ -644,6 +645,23 @@ impl ImapType { debug!("parse error for {:?}", l); } } + conn.send_command(b"LSUB \"\" \"*\"")?; + conn.read_response(&mut res)?; + debug!("out: {}", &res); + for l in res.lines().map(|l| l.trim()) { + if let Ok(subscription) = + protocol_parser::list_folder_result(l.as_bytes()).to_full_result() + { + if let Some(f) = folders.get_mut(&subscription.hash()) { + if subscription.no_select { + continue; + } + f.is_subscribed = true; + } + } else { + debug!("parse error for {:?}", l); + } + } Ok(debug!(folders)) } diff --git a/melib/src/backends/imap/protocol_parser.rs b/melib/src/backends/imap/protocol_parser.rs index 7250a4c5..472e0fe7 100644 --- a/melib/src/backends/imap/protocol_parser.rs +++ b/melib/src/backends/imap/protocol_parser.rs @@ -78,7 +78,7 @@ macro_rules! get_path_hash { named!( pub list_folder_result, do_parse!( - ws!(tag!("* LIST (")) + ws!(alt_complete!(tag!("* LIST (") | tag!("* LSUB ("))) >> properties: take_until!(&b")"[0..]) >> tag!(b") ") >> separator: delimited!(tag!(b"\""), take!(1), tag!(b"\"")) @@ -88,6 +88,7 @@ named!( let separator: u8 = separator[0]; let mut f = ImapFolder::default(); f.no_select = false; + f.is_subscribed = false; for p in properties.split(|&b| b == b' ') { use crate::backends::SpecialUsageMailbox; if p.eq_ignore_ascii_case(b"\\NoSelect") { diff --git a/melib/src/backends/jmap.rs b/melib/src/backends/jmap.rs index 7257c66a..aa63a307 100644 --- a/melib/src/backends/jmap.rs +++ b/melib/src/backends/jmap.rs @@ -242,21 +242,17 @@ impl MailBackend for JmapType { fn folders(&self) -> Result> { if self.folders.read().unwrap().is_empty() { let folders = std::dbg!(protocol::get_mailboxes(&self.connection))?; - let ret = Ok(folders - .iter() - .map(|(&h, f)| (h, BackendFolder::clone(f) as Folder)) - .collect()); *self.folders.write().unwrap() = folders; - ret - } else { - Ok(self - .folders - .read() - .unwrap() - .iter() - .map(|(&h, f)| (h, BackendFolder::clone(f) as Folder)) - .collect()) } + + Ok(self + .folders + .read() + .unwrap() + .iter() + .filter(|(_, f)| f.is_subscribed) + .map(|(&h, f)| (h, BackendFolder::clone(f) as Folder)) + .collect()) } fn operation(&self, hash: EnvelopeHash) -> Box { diff --git a/ui/src/components/mail/status.rs b/ui/src/components/mail/status.rs index d0734614..0917957f 100644 --- a/ui/src/components/mail/status.rs +++ b/ui/src/components/mail/status.rs @@ -446,6 +446,59 @@ impl Component for AccountStatus { ((_x, _y), (width - 1, height - 1)), None, ); + line += 1; + + write_string_to_grid( + "Special Mailboxes:", + &mut self.content, + Color::Default, + Color::Default, + Attr::Bold, + ((1, line), (width - 1, height - 1)), + None, + ); + for (i, f) in a + .ref_folders + .values() + .filter(|f| f.special_usage() != SpecialUsageMailbox::Normal) + .enumerate() + { + line += 1; + write_string_to_grid( + &format!("{}: {}", f.path(), f.special_usage()), + &mut self.content, + Color::Default, + Color::Default, + Attr::Default, + ((1, line), (width - 1, height - 1)), + None, + ); + } + line += 2; + write_string_to_grid( + "Subscribed folders:", + &mut self.content, + Color::Default, + Color::Default, + Attr::Bold, + ((1, line), (width - 1, height - 1)), + None, + ); + line += 2; + for f in a.list_folders() { + if f.is_subscribed() { + write_string_to_grid( + f.path(), + &mut self.content, + Color::Default, + Color::Default, + Attr::Default, + ((1, line), (width - 1, height - 1)), + None, + ); + line += 1; + } + } line += 1; if a.settings.account().format() == "imap" {