diff options
author | Tristan Partin <tristan@partin.io> | 2024-07-08 20:17:11 -0500 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2024-08-03 20:16:01 +0200 |
commit | cd92da0e893ab6741bb6d411434edbb03a570c7d (patch) | |
tree | 62c75704995a45de5acb0b3761881dd3ca771bc7 /worker/jmap/threads.go | |
parent | d20c578de4267ab23ad2deb579bc841ec23d734b (diff) | |
download | aerc-cd92da0e893ab6741bb6d411434edbb03a570c7d.tar.gz |
jmap: fetch entire threads
Fetch an email's entire thread in the JMAP backend.
Changelog-added: Fetch entire threads in the JMAP backend.
Signed-off-by: Tristan Partin <tristan@partin.io>
Tested-by: Tim Culverhouse <tim@timculverhouse.com>
Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'worker/jmap/threads.go')
-rw-r--r-- | worker/jmap/threads.go | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/worker/jmap/threads.go b/worker/jmap/threads.go new file mode 100644 index 00000000..b967e8cd --- /dev/null +++ b/worker/jmap/threads.go @@ -0,0 +1,82 @@ +package jmap + +import ( + "git.sr.ht/~rockorager/go-jmap" + "git.sr.ht/~rockorager/go-jmap/mail/email" + "git.sr.ht/~rockorager/go-jmap/mail/thread" +) + +func (w *JMAPWorker) fetchEntireThreads(emailIds []*email.Email) ([]*email.Email, error) { + var req jmap.Request + + if len(emailIds) == 0 { + return emailIds, nil + } + + threadsToFetch := make([]jmap.ID, 0, len(emailIds)) + for _, m := range emailIds { + threadsToFetch = append(threadsToFetch, m.ThreadID) + } + + req.Invoke(&thread.Get{ + Account: w.AccountId(), + IDs: threadsToFetch, + }) + + resp, err := w.Do(&req) + if err != nil { + return nil, err + } + + emailsToFetch := make([]jmap.ID, 0) + emailsToReturn := make([]*email.Email, 0) + for _, inv := range resp.Responses { + switch r := inv.Args.(type) { + case *thread.GetResponse: + for _, t := range r.List { + for _, emailId := range t.EmailIDs { + m, err := w.cache.GetEmail(emailId) + if err == nil || m == nil { + emailsToFetch = append(emailsToFetch, emailId) + } else { + emailsToReturn = append(emailsToReturn, m) + } + } + } + if err = w.cache.PutThreadState(r.State); err != nil { + w.w.Warnf("PutThreadState: %s", err) + } + case *jmap.MethodError: + return nil, wrapMethodError(r) + } + } + + if len(emailsToFetch) == 0 { + return emailsToReturn, nil + } + + req.Invoke(&email.Get{ + Account: w.AccountId(), + IDs: emailsToFetch, + Properties: headersProperties, + }) + + resp, err = w.Do(&req) + if err != nil { + return nil, err + } + + for _, inv := range resp.Responses { + switch r := inv.Args.(type) { + case *email.GetResponse: + emailsToReturn = append(emailsToReturn, r.List...) + if err = w.cache.PutEmailState(r.State); err != nil { + w.w.Warnf("PutEmailState: %s", err) + } + case *jmap.MethodError: + return nil, wrapMethodError(r) + } + } + + return emailsToReturn, nil +} |