From fcac4c9e29ac572c904f6c1ad308fc2261e4cfd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Bellegarde?= Date: Mon, 2 Oct 2023 22:12:51 +0200 Subject: [PATCH] engine: Filter duplicated mailboxes on LIST When using virtual namespaces in Dovecot, a LIST command will return mulitple entries for virtual folder. Always use flags from last entry. ``` a005 LIST "" "*" * LIST (\HasChildren) "." virtual * LIST (\HasNoChildren \UnMarked) "." Templates * LIST (\HasNoChildren \UnMarked \Trash) "." Trash * LIST (\HasNoChildren \UnMarked \Junk) "." Junk * LIST (\HasNoChildren \UnMarked \Drafts) "." Drafts * LIST (\HasNoChildren \UnMarked) "." Archive * LIST (\HasNoChildren \UnMarked \Sent) "." Sent * LIST (\HasNoChildren \Flagged) "." virtual.Favoris * LIST (\Noselect \HasChildren) "." virtual * LIST (\HasNoChildren \Flagged) "." virtual.Favoris * LIST (\HasNoChildren) "." INBOX ``` Fix errors like: `Unable to get STATUS of virtual: a008 NO Mailbox doesn't exist: virtual` --- src/engine/imap/api/imap-account-session.vala | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/engine/imap/api/imap-account-session.vala b/src/engine/imap/api/imap-account-session.vala index 813d9e5e..0258ef54 100644 --- a/src/engine/imap/api/imap-account-session.vala +++ b/src/engine/imap/api/imap-account-session.vala @@ -357,23 +357,26 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject { (folder != null) ? folder.to_string() : "root", response.to_string()); } - // See note at ListCommand about some servers returning the - // parent's name alongside their children ... this filters - // this out - if (folder != null && list_children) { - Gee.Iterator iter = list_results.iterator(); - while (iter.next()) { + // We use a hash to filter duplicated mailboxes + Gee.HashMap filtered = + new Gee.HashMap(); + foreach (MailboxInformation information in list_results) { + // See note at ListCommand about some servers returning the + // parent's name alongside their children ... this filters + // this out + if (folder != null && list_children) { FolderPath list_path = session.get_path_for_mailbox( - this.root, iter.get().mailbox + this.root, information.mailbox ); if (list_path.equal_to(folder)) { debug("Removing parent from LIST results: %s", list_path.to_string()); - iter.remove(); + continue; } } + filtered.set(information.mailbox.name, information); } - return list_results; + return Geary.traverse(filtered.values).to_array_list(); } private async StatusData send_status_async(ClientSession session,