aboutsummaryrefslogtreecommitdiffstats
path: root/worker/jmap/threads.go
diff options
context:
space:
mode:
authorTristan Partin <tristan@partin.io>2024-07-08 20:17:11 -0500
committerRobin Jarry <robin@jarry.cc>2024-08-03 20:16:01 +0200
commitcd92da0e893ab6741bb6d411434edbb03a570c7d (patch)
tree62c75704995a45de5acb0b3761881dd3ca771bc7 /worker/jmap/threads.go
parentd20c578de4267ab23ad2deb579bc841ec23d734b (diff)
downloadaerc-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.go82
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
+}