diff options
author | Kevin Kuehler <keur@xcf.berkeley.edu> | 2019-10-10 15:27:08 -0700 |
---|---|---|
committer | Ben Burwell <ben@benburwell.com> | 2019-10-12 20:57:49 -0400 |
commit | 41f3bb3bc16b5d7bef7ffe29a8f4b493be7d79fd (patch) | |
tree | 305a13933b785a659b10756a06e499a2e8a28ba4 /worker | |
parent | 8cb4a9d751d1497e1059fedb03964bc9e56e5c06 (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.go | 45 | ||||
-rw-r--r-- | worker/imap/worker.go | 6 |
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: |