aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Culverhouse <tim@timculverhouse.com>2022-11-28 21:15:38 -0600
committerRobin Jarry <robin@jarry.cc>2022-12-02 22:59:44 +0100
commit17718981c5d1db0775407d45f83dcd026758ab47 (patch)
tree4d44e7d7739feadfead8d2378e772dcf7c451cee
parentec04654bd52a24ea7c5c0a22a465d3244df1e511 (diff)
downloadaerc-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.md1
-rw-r--r--doc/aerc-imap.5.scd7
-rw-r--r--worker/imap/checkmail.go67
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{