diff options
author | Tim Culverhouse <tim@timculverhouse.com> | 2022-11-28 21:15:38 -0600 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-12-02 22:59:44 +0100 |
commit | 17718981c5d1db0775407d45f83dcd026758ab47 (patch) | |
tree | 4d44e7d7739feadfead8d2378e772dcf7c451cee | |
parent | ec04654bd52a24ea7c5c0a22a465d3244df1e511 (diff) | |
download | aerc-17718981c5d1db0775407d45f83dcd026758ab47.tar.gz |
imap: use list-status for check-mail
Use list-status to perform check-mail commands, if it is available. This
provides a significant performance benefit by only requiring one IMAP
command vs one command for each mailbox.
Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | doc/aerc-imap.5.scd | 7 | ||||
-rw-r--r-- | worker/imap/checkmail.go | 67 |
3 files changed, 49 insertions, 26 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index f356122c..6931391c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Override the subject prefix prefix for replies pattern with `subject-re-pattern`. - Search/filter by absolute and relative date ranges with the `-d` flag. +- LIST-STATUS support for imap ### Fixed diff --git a/doc/aerc-imap.5.scd b/doc/aerc-imap.5.scd index 787730df..c00f784f 100644 --- a/doc/aerc-imap.5.scd +++ b/doc/aerc-imap.5.scd @@ -10,6 +10,7 @@ aerc implements the IMAP protocol as specified by RFC 3501, with the following IMAP extensions: - IDLE (RFC 2177) +- LIST-STATUS (RFC 5819) # CONFIGURATION @@ -104,14 +105,16 @@ are available: *check-mail-include* Specifies the comma separated list of folders to include when checking for new mail with *:check-mail*. Names prefixed with _~_ are interpreted as regular - expressions. + expressions. This setting is ignored if your IMAP server supports the + LIST-STATUS command, in which case all folders will be checked. By default, all folders are included. *check-mail-exclude* Specifies the comma separated list of folders to exclude when checking for new mail with *:check-mail*. Names prefixed with _~_ are interpreted as regular - expressions. + expressions. This setting is ignored if your IMAP server supports the + LIST-STATUS command, in which case all folders will be checked. Note that this overrides anything from *check-mail-include*. By default, no folders are excluded. diff --git a/worker/imap/checkmail.go b/worker/imap/checkmail.go index 34cf63d1..8f9e1b2b 100644 --- a/worker/imap/checkmail.go +++ b/worker/imap/checkmail.go @@ -13,36 +13,55 @@ func (w *IMAPWorker) handleCheckMailMessage(msg *types.CheckMail) { imap.StatusRecent, imap.StatusUnseen, } - var remaining []string - for _, dir := range msg.Directories { - if len(w.worker.Actions) > 0 { - remaining = append(remaining, dir) - continue - } - - log.Tracef("Getting status of directory %s", dir) - status, err := w.client.Status(dir, items) + var ( + statuses []*imap.MailboxStatus + err error + remaining []string + ) + switch { + case w.liststatus: + log.Tracef("Checking mail with LIST-STATUS") + statuses, err = w.client.liststatus.ListStatus("", "*", items, nil) if err != nil { w.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), Error: err, }, nil) - } else { - w.worker.PostMessage(&types.DirectoryInfo{ - Info: &models.DirectoryInfo{ - Flags: status.Flags, - Name: status.Name, - ReadOnly: status.ReadOnly, - AccurateCounts: true, - - Exists: int(status.Messages), - Recent: int(status.Recent), - Unseen: int(status.Unseen), - Caps: w.caps, - }, - SkipSort: true, - }, nil) + return } + default: + for _, dir := range msg.Directories { + if len(w.worker.Actions) > 0 { + remaining = append(remaining, dir) + continue + } + log.Tracef("Getting status of directory %s", dir) + status, err := w.client.Status(dir, items) + if err != nil { + w.worker.PostMessage(&types.Error{ + Message: types.RespondTo(msg), + Error: err, + }, nil) + continue + } + statuses = append(statuses, status) + } + } + for _, status := range statuses { + w.worker.PostMessage(&types.DirectoryInfo{ + Info: &models.DirectoryInfo{ + Flags: status.Flags, + Name: status.Name, + ReadOnly: status.ReadOnly, + AccurateCounts: true, + + Exists: int(status.Messages), + Recent: int(status.Recent), + Unseen: int(status.Unseen), + Caps: w.caps, + }, + SkipSort: true, + }, nil) } if len(remaining) > 0 { w.worker.PostMessage(&types.CheckMailDirectories{ |