diff --git a/imaputils/info.go b/imaputils/fetch_messages.go similarity index 50% rename from imaputils/info.go rename to imaputils/fetch_messages.go index 2c77c4b..ad29c78 100644 --- a/imaputils/info.go +++ b/imaputils/fetch_messages.go @@ -7,87 +7,6 @@ import ( "github.com/emersion/go-imap" ) -func ListMailboxes(conf *config.AccountData, debug bool) ([]*imap.MailboxInfo, error) { - var mailboxes []*imap.MailboxInfo - conn := NewConnection(conf) - - err := conn.Start(debug) - if err != nil { - return mailboxes, err - } - defer conn.Close() - - mboxChan := make(chan *imap.MailboxInfo, 10) - done := make(chan error, 1) - go func() { - done <- conn.client.List("", "*", mboxChan) - }() - - for m := range mboxChan { - mailboxes = append(mailboxes, m) - } - - if err := <-done; err != nil { - return mailboxes, err - } - - return mailboxes, nil -} - -type ListMessagesOpts struct { - Mailbox string - Limit uint32 -} - -func ListMessages(conf *config.AccountData, opts *ListMessagesOpts, debug bool) ([]*imap.Message, error) { - var messages []*imap.Message - conn := NewConnection(conf) - - err := conn.Start(debug) - if err != nil { - return messages, err - } - defer conn.Close() - - mbox, err := conn.client.Select(opts.Mailbox, true) - if err != nil { - return messages, err - } - - return getMessages(mbox, conn, opts.Limit) -} - -func getMessages(mbox *imap.MailboxStatus, conn *IMAPConnection, limit uint32) ([]*imap.Message, error) { - var start uint32 - var msgs []*imap.Message - seqset := new(imap.SeqSet) - messages := make(chan *imap.Message, 10) - done := make(chan error, 1) - - switch { - case limit == 0: - start = 1 - case mbox.Messages > limit: - start = mbox.Messages - limit + 1 - default: - start = 1 - } - - seqset.AddRange(start, mbox.Messages) - go func() { - done <- conn.client.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope, imap.FetchFlags}, messages) - }() - - for msg := range messages { - msgs = append(msgs, msg) - } - - if err := <-done; err != nil { - return []*imap.Message{}, err - } - return msgs, nil -} - type FetchOpts struct { Mailbox string IdList []uint32 @@ -109,18 +28,23 @@ func (o *FetchOpts) String() string { } func FetchMessages(conf *config.AccountData, opts *FetchOpts, debug bool) ([]*imap.Message, error) { - var messages []*imap.Message + var empty []*imap.Message conn := NewConnection(conf) err := conn.Start(debug) if err != nil { - return messages, err + 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 messages, err + return empty, err } return fetchMessage(mbox, conn, opts) diff --git a/imaputils/list_mailboxes.go b/imaputils/list_mailboxes.go new file mode 100644 index 0000000..58efa5a --- /dev/null +++ b/imaputils/list_mailboxes.go @@ -0,0 +1,38 @@ +package imaputils + +import ( + "git.sr.ht/~blallo/papero/config" + "github.com/emersion/go-imap" +) + +func ListMailboxes(conf *config.AccountData, debug bool) ([]*imap.MailboxInfo, error) { + var empty []*imap.MailboxInfo + conn := NewConnection(conf) + + err := conn.Start(debug) + if err != nil { + return empty, err + } + defer conn.Close() + return ListMailboxesInSession(conn) +} + +func ListMailboxesInSession(conn *IMAPConnection) ([]*imap.MailboxInfo, error) { + var mailboxes []*imap.MailboxInfo + mboxChan := make(chan *imap.MailboxInfo, 10) + done := make(chan error, 1) + + go func() { + done <- conn.client.List("", "*", mboxChan) + }() + + for m := range mboxChan { + mailboxes = append(mailboxes, m) + } + + if err := <-done; err != nil { + return mailboxes, err + } + + return mailboxes, nil +} diff --git a/imaputils/list_messages.go b/imaputils/list_messages.go new file mode 100644 index 0000000..a9c591d --- /dev/null +++ b/imaputils/list_messages.go @@ -0,0 +1,65 @@ +package imaputils + +import ( + "git.sr.ht/~blallo/papero/config" + "github.com/emersion/go-imap" +) + +type ListMessagesOpts struct { + Mailbox string + Limit uint32 +} + +func ListMessages(conf *config.AccountData, opts *ListMessagesOpts, 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 ListMessagesInSession(conn, opts) +} + +func ListMessagesInSession(conn *IMAPConnection, opts *ListMessagesOpts) ([]*imap.Message, error) { + var messages []*imap.Message + mbox, err := conn.client.Select(opts.Mailbox, true) + if err != nil { + return messages, err + } + + return getMessages(mbox, conn, opts.Limit) +} + +func getMessages(mbox *imap.MailboxStatus, conn *IMAPConnection, limit uint32) ([]*imap.Message, error) { + var start uint32 + var msgs []*imap.Message + seqset := new(imap.SeqSet) + messages := make(chan *imap.Message, 10) + done := make(chan error, 1) + + switch { + case limit == 0: + start = 1 + case mbox.Messages > limit: + start = mbox.Messages - limit + 1 + default: + start = 1 + } + + seqset.AddRange(start, mbox.Messages) + go func() { + done <- conn.client.Fetch(seqset, []imap.FetchItem{imap.FetchEnvelope, imap.FetchFlags}, messages) + }() + + for msg := range messages { + msgs = append(msgs, msg) + } + + if err := <-done; err != nil { + return []*imap.Message{}, err + } + return msgs, nil +} diff --git a/imaputils/modify.go b/imaputils/set_flags.go similarity index 94% rename from imaputils/modify.go rename to imaputils/set_flags.go index 98c9bec..7532a1b 100644 --- a/imaputils/modify.go +++ b/imaputils/set_flags.go @@ -206,6 +206,14 @@ func SetFlags(conf *config.AccountData, opts *SetFlagsOpts) error { } defer conn.Close() + return SetFlagsInSession(conn, opts) +} + +// SetFlagsInSession does the same as SetFlags, but has to be provided +// with a started *IMAPConnection. +func SetFlagsInSession(conn *IMAPConnection, opts *SetFlagsOpts) error { + var err error + _, err = conn.client.Select(opts.Mailbox, false) if err != nil { return err