list_messages.go 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. package imaputils
  2. import (
  3. "git.sr.ht/~blallo/papero/config"
  4. "github.com/emersion/go-imap"
  5. )
  6. type ListMessagesOpts struct {
  7. Mailbox string
  8. Limit uint32
  9. }
  10. func ListMessages(conf *config.AccountData, opts *ListMessagesOpts, debug bool) ([]*imap.Message, error) {
  11. var empty []*imap.Message
  12. conn := NewConnection(conf)
  13. err := conn.Start(debug)
  14. if err != nil {
  15. return empty, err
  16. }
  17. defer conn.Close()
  18. return ListMessagesInSession(conn, opts)
  19. }
  20. func ListMessagesInSession(conn *IMAPConnection, opts *ListMessagesOpts) ([]*imap.Message, error) {
  21. var messages []*imap.Message
  22. mbox, err := conn.client.Select(opts.Mailbox, true)
  23. if err != nil {
  24. return messages, err
  25. }
  26. return getMessages(mbox, conn, opts.Limit)
  27. }
  28. func getMessages(mbox *imap.MailboxStatus, conn *IMAPConnection, limit uint32) ([]*imap.Message, error) {
  29. var start uint32
  30. var msgs []*imap.Message
  31. seqset := new(imap.SeqSet)
  32. messages := make(chan *imap.Message, 10)
  33. done := make(chan error, 1)
  34. switch {
  35. case limit == 0:
  36. start = 1
  37. case mbox.Messages > limit:
  38. start = mbox.Messages - limit + 1
  39. default:
  40. start = 1
  41. }
  42. seqset.AddRange(start, mbox.Messages)
  43. go func() {
  44. done <- conn.client.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope, imap.FetchFlags}, messages)
  45. }()
  46. for msg := range messages {
  47. msgs = append(msgs, msg)
  48. }
  49. if err := <-done; err != nil {
  50. return []*imap.Message{}, err
  51. }
  52. return msgs, nil
  53. }