papero/imaputils/fetch_messages.go
2021-04-05 19:49:39 +02:00

92 lines
2 KiB
Go

package imaputils
import (
"fmt"
"git.sr.ht/~blallo/papero/config"
"github.com/emersion/go-imap"
)
type FetchOpts struct {
Mailbox string
IdList []uint32
WithHeaders bool
WithBody bool
WithFlags bool
Peek bool
}
func (o *FetchOpts) String() string {
return fmt.Sprintf(
"FetchOpts{Mailbox: %s, IdList: %v, WithHeaders: %t, WithBody: %t, Peek: %t}",
o.Mailbox,
o.IdList,
o.WithHeaders,
o.WithBody,
o.Peek,
)
}
func FetchMessages(conf *config.AccountData, opts *FetchOpts, debug bool) ([]*imap.Message, error) {
var empty []*imap.Message
conn := NewConnection(conf)
err := conn.Start(debug)
if err != nil {
return empty, err
}
defer conn.Close()
return FetchMessagesInSession(conn, opts)
}
func FetchMessagesInSession(conn *IMAPConnection, opts *FetchOpts) ([]*imap.Message, error) {
var empty []*imap.Message
mbox, err := conn.client.Select(opts.Mailbox, true)
if err != nil {
return empty, err
}
return fetchMessage(mbox, conn, opts)
}
func fetchMessage(mbox *imap.MailboxStatus, conn *IMAPConnection, opts *FetchOpts) ([]*imap.Message, error) {
var messageAcc []*imap.Message
messages := make(chan *imap.Message, len(opts.IdList))
done := make(chan error, 1)
seqset := new(imap.SeqSet)
for _, id := range opts.IdList {
seqset.AddNum(id)
}
var items []imap.FetchItem
if opts.WithHeaders {
section := &imap.BodySectionName{Peek: opts.Peek, BodyPartName: imap.BodyPartName{Specifier: imap.HeaderSpecifier}}
items = append(items, section.FetchItem())
}
items = append(items, imap.FetchEnvelope)
if opts.WithBody {
section := &imap.BodySectionName{Peek: opts.Peek, BodyPartName: imap.BodyPartName{Specifier: imap.TextSpecifier}}
items = append(items, section.FetchItem())
}
if opts.WithFlags {
items = append(items, imap.FetchFlags)
}
go func() {
done <- conn.client.Fetch(seqset, items, messages)
}()
for m := range messages {
messageAcc = append(messageAcc, m)
}
if err := <-done; err != nil {
return []*imap.Message{}, err
}
return messageAcc, nil
}