feat: add background mail polling option for all workers

Check for new mail (recent, unseen, exists counts) with an external
command, or for imap with the STATUS command, at start or on
reconnection and every X time duration

IMAP:
The selected folder is skipped, per specification. Additional config
options are included for including/excluding folders explicitly.

Maildir/Notmuch:
An external command will be run in the background to check for new mail.
An optional timeout can be used with maildir/notmuch. Default is 10s

New account options:
check-mail
check-mail-cmd (maildir/notmuch only)
check-mail-timeout (maildir/notmuch only), default 10s
check-mail-include (IMAP only)
check-mail-exclude (IMAP only)

If unset, or set less than or equal to 0, check-mail will be ignored

Signed-off-by: Tim Culverhouse <tim@timculverhouse.com>
Tested-by: Moritz Poldrack <moritz@poldrack.dev>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Tim Culverhouse 2022-05-30 07:34:18 -05:00 committed by Robin Jarry
parent 30d5788974
commit 2551dd1bfa
14 changed files with 267 additions and 42 deletions
worker/imap

40
worker/imap/checkmail.go Normal file
View file

@ -0,0 +1,40 @@
package imap
import (
"git.sr.ht/~rjarry/aerc/models"
"git.sr.ht/~rjarry/aerc/worker/types"
"github.com/emersion/go-imap"
)
func (w *IMAPWorker) handleCheckMailMessage(msg *types.CheckMail) {
items := []imap.StatusItem{
imap.StatusMessages,
imap.StatusRecent,
imap.StatusUnseen,
}
for _, dir := range msg.Directories {
w.worker.Logger.Printf("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)
} 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),
},
SkipSort: true,
}, nil)
}
}
w.worker.PostMessage(&types.Done{Message: types.RespondTo(msg)}, nil)
}