92 lines
2 KiB
Go
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
|
|
}
|