aboutsummaryrefslogtreecommitdiff
path: root/worker
diff options
context:
space:
mode:
authorKevin Kuehler <keur@xcf.berkeley.edu>2019-10-10 15:27:08 -0700
committerBen Burwell <ben@benburwell.com>2019-10-12 20:57:49 -0400
commit41f3bb3bc16b5d7bef7ffe29a8f4b493be7d79fd (patch)
tree305a13933b785a659b10756a06e499a2e8a28ba4 /worker
parent8cb4a9d751d1497e1059fedb03964bc9e56e5c06 (diff)
worker/imap: Add threading extension
* Import the go-imap-sortthread library * Add sortthread client to imapClient in worker * Add handleDirectoryThreaded, which uses the go-imap-sortthread, and converts the results to the aerc thread type Signed-off-by: Kevin Kuehler <keur@xcf.berkeley.edu>
Diffstat (limited to 'worker')
-rw-r--r--worker/imap/open.go45
-rw-r--r--worker/imap/worker.go6
2 files changed, 50 insertions, 1 deletions
diff --git a/worker/imap/open.go b/worker/imap/open.go
index 452c309..bdb794b 100644
--- a/worker/imap/open.go
+++ b/worker/imap/open.go
@@ -2,6 +2,7 @@ package imap
import (
"github.com/emersion/go-imap"
+ sortthread "github.com/emersion/go-imap-sortthread"
"git.sr.ht/~sircmpwn/aerc/worker/types"
)
@@ -48,3 +49,47 @@ func (imapw *IMAPWorker) handleFetchDirectoryContents(
imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
}
}
+
+func (imapw *IMAPWorker) handleDirectoryThreaded(
+ msg *types.FetchDirectoryThreaded) {
+ imapw.worker.Logger.Printf("Fetching threaded UID list")
+
+ seqSet := &imap.SeqSet{}
+ seqSet.AddRange(1, imapw.selected.Messages)
+ threads, err := imapw.client.tc.UidThread(sortthread.References,
+ &imap.SearchCriteria{SeqNum: seqSet})
+ if err != nil {
+ imapw.worker.PostMessage(&types.Error{
+ Message: types.RespondTo(msg),
+ Error: err,
+ }, nil)
+ } else {
+ aercThreads, count := convertThreads(threads)
+ imapw.seqMap = make([]uint32, count)
+ imapw.worker.PostMessage(&types.DirectoryThreaded{
+ Message: types.RespondTo(msg),
+ Threads: aercThreads,
+ }, nil)
+ imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
+ }
+}
+
+// This sucks... TODO: find a better way to do this.
+func convertThreads(threads []*sortthread.Thread) ([]*types.Thread, int) {
+ if threads == nil {
+ return nil, 0
+ }
+ conv := make([]*types.Thread, len(threads))
+ count := 0
+
+ for i := 0; i < len(threads); i++ {
+ t := threads[i]
+ children, childCount := convertThreads(t.Children)
+ conv[i] = &types.Thread{
+ Uid: t.Id,
+ Children: children,
+ }
+ count += childCount + 1
+ }
+ return conv, count
+}
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index cd63c39..afc7289 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -8,6 +8,7 @@ import (
"github.com/emersion/go-imap"
idle "github.com/emersion/go-imap-idle"
+ sortthread "github.com/emersion/go-imap-sortthread"
"github.com/emersion/go-imap/client"
"golang.org/x/oauth2"
@@ -26,6 +27,7 @@ var errUnsupported = fmt.Errorf("unsupported command")
type imapClient struct {
*client.Client
+ tc *sortthread.ThreadClient
idle *idle.IdleClient
}
@@ -152,7 +154,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
}
c.Updates = w.updates
- w.client = &imapClient{c, idle.NewClient(c)}
+ w.client = &imapClient{c, sortthread.NewThreadClient(c), idle.NewClient(c)}
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.ListDirectories:
w.handleListDirectories(msg)
@@ -160,6 +162,8 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
w.handleOpenDirectory(msg)
case *types.FetchDirectoryContents:
w.handleFetchDirectoryContents(msg)
+ case *types.FetchDirectoryThreaded:
+ w.handleDirectoryThreaded(msg)
case *types.CreateDirectory:
w.handleCreateDirectory(msg)
case *types.FetchMessageHeaders: