diff options
author | Robin Jarry <robin@jarry.cc> | 2024-06-28 23:49:20 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2024-06-29 00:18:18 +0200 |
commit | 446d5303b9c7e7100261fe444bf42319e25e228e (patch) | |
tree | 11f65d83bed2fd503d8eeedb30ce023cb0409d82 /worker/jmap | |
parent | 7f833baa90bf6521997c70557a1534dc7528ce0d (diff) | |
download | aerc-446d5303b9c7e7100261fe444bf42319e25e228e.tar.gz |
jmap: revert fetch threads support
This reverts commits:
9e93d9efdb88 ("jmap: fix go static check failure")
0465509eedad ("jmap: skip Email/get call if no emails to get")
9f97c698e3dd ("jmap: fetch entire threads")
Issues have been reported about disappearing sent messages.
Reported-by: Tristan Partin <tristan@partin.io>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Tristan Partin <tristan@partin.io>
Diffstat (limited to 'worker/jmap')
-rw-r--r-- | worker/jmap/cache/gob.go | 2 | ||||
-rw-r--r-- | worker/jmap/cache/state.go | 13 | ||||
-rw-r--r-- | worker/jmap/cache/thread.go | 35 | ||||
-rw-r--r-- | worker/jmap/fetch.go | 183 | ||||
-rw-r--r-- | worker/jmap/state.go | 26 |
5 files changed, 32 insertions, 227 deletions
diff --git a/worker/jmap/cache/gob.go b/worker/jmap/cache/gob.go index 8b153c50..f1b8be33 100644 --- a/worker/jmap/cache/gob.go +++ b/worker/jmap/cache/gob.go @@ -6,12 +6,10 @@ import ( "git.sr.ht/~rockorager/go-jmap/mail/email" "git.sr.ht/~rockorager/go-jmap/mail/mailbox" - "git.sr.ht/~rockorager/go-jmap/mail/thread" ) type jmapObject interface { *email.Email | - *thread.Thread | *email.QueryResponse | *mailbox.Mailbox | *FolderContents | diff --git a/worker/jmap/cache/state.go b/worker/jmap/cache/state.go index 6538ccad..5fec5034 100644 --- a/worker/jmap/cache/state.go +++ b/worker/jmap/cache/state.go @@ -12,18 +12,6 @@ func (c *JMAPCache) PutMailboxState(state string) error { return c.put(mailboxStateKey, []byte(state)) } -func (c *JMAPCache) GetThreadState() (string, error) { - buf, err := c.get(threadStateKey) - if err != nil { - return "", err - } - return string(buf), nil -} - -func (c *JMAPCache) PutThreadState(state string) error { - return c.put(threadStateKey, []byte(state)) -} - func (c *JMAPCache) GetEmailState() (string, error) { buf, err := c.get(emailStateKey) if err != nil { @@ -39,5 +27,4 @@ func (c *JMAPCache) PutEmailState(state string) error { const ( mailboxStateKey = "state/mailbox" emailStateKey = "state/email" - threadStateKey = "state/thread" ) diff --git a/worker/jmap/cache/thread.go b/worker/jmap/cache/thread.go deleted file mode 100644 index ca91a4d9..00000000 --- a/worker/jmap/cache/thread.go +++ /dev/null @@ -1,35 +0,0 @@ -package cache - -import ( - "git.sr.ht/~rockorager/go-jmap" - "git.sr.ht/~rockorager/go-jmap/mail/thread" -) - -func (c *JMAPCache) GetThread(id jmap.ID) (*thread.Thread, error) { - buf, err := c.get(threadKey(id)) - if err != nil { - return nil, err - } - e := new(thread.Thread) - err = unmarshal(buf, e) - if err != nil { - return nil, err - } - return e, nil -} - -func (c *JMAPCache) PutThread(id jmap.ID, e *thread.Thread) error { - buf, err := marshal(e) - if err != nil { - return err - } - return c.put(threadKey(id), buf) -} - -func (c *JMAPCache) DeleteThread(id jmap.ID) error { - return c.delete(threadKey(id)) -} - -func threadKey(id jmap.ID) string { - return "thread/" + string(id) -} 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 { diff --git a/worker/jmap/state.go b/worker/jmap/state.go index 833bd151..3dbab3fb 100644 --- a/worker/jmap/state.go +++ b/worker/jmap/state.go @@ -3,7 +3,6 @@ package jmap import ( "git.sr.ht/~rockorager/go-jmap" "git.sr.ht/~rockorager/go-jmap/mail/mailbox" - "git.sr.ht/~rockorager/go-jmap/mail/thread" ) func (w *JMAPWorker) getMailboxState() (string, error) { @@ -28,28 +27,3 @@ func (w *JMAPWorker) getMailboxState() (string, error) { // This should be an impossibility return "", nil } - -func (w *JMAPWorker) getThreadState() (string, error) { - var req jmap.Request - - // TODO: This is a junk JMAP ID because Go's JSON serialization doesn't - // send empty slices as arrays, WTF. - req.Invoke(&thread.Get{Account: w.accountId, IDs: []jmap.ID{jmap.ID("00")}}) - resp, err := w.Do(&req) - if err != nil { - return "", err - } - - for _, inv := range resp.Responses { - switch r := inv.Args.(type) { - case *thread.GetResponse: - return r.State, nil - case *jmap.MethodError: - return "", wrapMethodError(r) - - } - } - - // This should be an impossibility - return "", nil -} |