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 }