diff options
Diffstat (limited to 'worker/jmap/fetch.go')
-rw-r--r-- | worker/jmap/fetch.go | 183 |
1 files changed, 32 insertions, 151 deletions
diff --git a/worker/jmap/fetch.go b/worker/jmap/fetch.go index 3c422cbf..17b3fb2f 100644 --- a/worker/jmap/fetch.go +++ b/worker/jmap/fetch.go @@ -10,14 +10,12 @@ import ( "git.sr.ht/~rjarry/aerc/worker/types" "git.sr.ht/~rockorager/go-jmap" "git.sr.ht/~rockorager/go-jmap/mail/email" - "git.sr.ht/~rockorager/go-jmap/mail/thread" "github.com/emersion/go-message/charset" ) var headersProperties = []string{ "id", "blobId", - "threadId", "mailboxIds", "keywords", "size", @@ -35,90 +33,10 @@ var headersProperties = []string{ "bodyStructure", } -func (w *JMAPWorker) fetchEmailIdsFromThreads(threadIds []jmap.ID) ([]jmap.ID, error) { - currentThreadState, err := w.getThreadState() - if err != nil { - return nil, err - } - - // If we can't get the cached mailbox state, at worst, we will just - // query information we might already know - cachedThreadState, err := w.cache.GetThreadState() - if err != nil { - w.w.Warnf("GetThreadState: %s", err) - } - - consistentThreadState := currentThreadState == cachedThreadState - - mailIds := make([]jmap.ID, 0) - getMailIds := func(threadIds []jmap.ID) error { - var req jmap.Request - var realIds []jmap.ID - - if len(threadIds) > 0 { - realIds = threadIds - } else { - realIds = []jmap.ID{jmap.ID("00")} - } - - req.Invoke(&thread.Get{ - Account: w.accountId, - IDs: realIds, - }) - - resp, err := w.Do(&req) - if err != nil { - return err - } - - for _, inv := range resp.Responses { - switch r := inv.Args.(type) { - case *thread.GetResponse: - for _, t := range r.List { - mailIds = append(mailIds, t.EmailIDs...) - } - case *jmap.MethodError: - return wrapMethodError(r) - } - } - - return nil - } - - // If we have a consistent state, check the cache - if consistentThreadState { - missingThreadIds := make([]jmap.ID, 0, len(threadIds)) - for _, threadId := range threadIds { - t, err := w.cache.GetThread(threadId) - if err != nil { - w.w.Warnf("GetThread: %s", err) - missingThreadIds = append(missingThreadIds, threadId) - continue - } - mailIds = append(mailIds, t.EmailIDs...) - } - - if len(missingThreadIds) > 0 { - if err := getMailIds(missingThreadIds); err != nil { - return nil, err - } - } - } else { - if err := getMailIds(threadIds); err != nil { - return nil, err - } - } - - if err := w.cache.PutThreadState(currentThreadState); err != nil { - w.w.Warnf("GetThreadState: %s", err) - } - - return mailIds, nil -} - func (w *JMAPWorker) handleFetchMessageHeaders(msg *types.FetchMessageHeaders) error { - mailIds := make([]jmap.ID, 0) - threadIds := make([]jmap.ID, 0, len(msg.Uids)) + var req jmap.Request + + ids := make([]jmap.ID, 0, len(msg.Uids)) for _, uid := range msg.Uids { id, ok := w.uidStore.GetKey(uid) if !ok { @@ -126,89 +44,52 @@ func (w *JMAPWorker) handleFetchMessageHeaders(msg *types.FetchMessageHeaders) e } jid := jmap.ID(id) m, err := w.cache.GetEmail(jid) - // TODO: use ID.Valid() when my patch is merged - if err == nil && len(m.ThreadID) > 0 && len(m.ThreadID) < 256 { - threadIds = append(threadIds, m.ThreadID) + if err == nil { w.w.PostMessage(&types.MessageInfo{ Message: types.RespondTo(msg), Info: w.translateMsgInfo(m), }, nil) continue } - mailIds = append(mailIds, jid) + ids = append(ids, jid) + } + + if len(ids) == 0 { + return nil } - postMessages := func(mailIds []jmap.ID, collectThreadIds bool) error { - missing := make([]jmap.ID, 0, len(mailIds)) - for _, id := range mailIds { - m, err := w.cache.GetEmail(id) - // TODO: use ID.Valid() when my patch is merged - if err == nil && len(m.ThreadID) > 0 && len(m.ThreadID) < 256 { - threadIds = append(threadIds, m.ThreadID) + req.Invoke(&email.Get{ + Account: w.accountId, + IDs: ids, + Properties: headersProperties, + }) + + resp, err := w.Do(&req) + if err != nil { + return err + } + + for _, inv := range resp.Responses { + switch r := inv.Args.(type) { + case *email.GetResponse: + for _, m := range r.List { w.w.PostMessage(&types.MessageInfo{ Message: types.RespondTo(msg), Info: w.translateMsgInfo(m), }, nil) - continue - } - missing = append(missing, id) - } - - if len(missing) == 0 { - return nil - } - - var req jmap.Request - req.Invoke(&email.Get{ - Account: w.accountId, - IDs: missing, - Properties: headersProperties, - }) - - resp, err := w.Do(&req) - if err != nil { - return err - } - - for _, inv := range resp.Responses { - switch r := inv.Args.(type) { - case *email.GetResponse: - for _, m := range r.List { - w.w.PostMessage(&types.MessageInfo{ - Message: types.RespondTo(msg), - Info: w.translateMsgInfo(m), - }, nil) - if err := w.cache.PutEmail(m.ID, m); err != nil { - w.w.Warnf("PutEmail: %s", err) - } - - if collectThreadIds { - threadIds = append(threadIds, m.ThreadID) - } - } - if err = w.cache.PutEmailState(r.State); err != nil { - w.w.Warnf("PutEmailState: %s", err) + if err := w.cache.PutEmail(m.ID, m); err != nil { + w.w.Warnf("PutEmail: %s", err) } - case *jmap.MethodError: - return wrapMethodError(r) } + if err = w.cache.PutEmailState(r.State); err != nil { + w.w.Warnf("PutEmailState: %s", err) + } + case *jmap.MethodError: + return wrapMethodError(r) } - - return nil - } - - if len(mailIds) > 0 { - if err := postMessages(mailIds, true); err != nil { - return err - } - } - - additionalMailIds, err := w.fetchEmailIdsFromThreads(threadIds) - if err != nil { - return err } - return postMessages(additionalMailIds, false) + return nil } func (w *JMAPWorker) handleFetchMessageBodyPart(msg *types.FetchMessageBodyPart) error { |