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`
This commit is contained in:
Cédric Bellegarde 2023-10-02 22:12:51 +02:00 committed by Niels De Graef
parent 80fa9beab8
commit fcac4c9e29

View file

@ -357,23 +357,26 @@ internal class Geary.Imap.AccountSession : Geary.Imap.SessionObject {
(folder != null) ? folder.to_string() : "root", response.to_string());
}
// We use a hash to filter duplicated mailboxes
Gee.HashMap<string, MailboxInformation> filtered =
new Gee.HashMap<string, MailboxInformation>();
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) {
Gee.Iterator<MailboxInformation> iter = list_results.iterator();
while (iter.next()) {
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,