From fad17adfefce95234856fb558becd73fb61c830b Mon Sep 17 00:00:00 2001 From: Kevin Kuehler Date: Mon, 28 Oct 2019 12:07:01 -0700 Subject: 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 --- go.mod | 3 ++- go.sum | 4 ++++ worker/imap/open.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ worker/imap/worker.go | 6 +++++- 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index aeb7f8c..52a0309 100644 --- a/go.mod +++ b/go.mod @@ -9,9 +9,10 @@ require ( github.com/ddevault/go-libvterm v0.0.0-20190526194226-b7d861da3810 github.com/emersion/go-imap v1.0.0 github.com/emersion/go-imap-idle v0.0.0-20190519112320-2704abd7050e + github.com/emersion/go-imap-sortthread v1.0.1-0.20191002194849-97d602f80823 github.com/emersion/go-maildir v0.0.0-20190727102040-941194b0ac70 github.com/emersion/go-message v0.10.7 - github.com/emersion/go-sasl v0.0.0-20190704090222-36b50694675c + github.com/emersion/go-sasl v0.0.0-20190817083125-240c8404624e github.com/emersion/go-smtp v0.11.2 github.com/fsnotify/fsnotify v1.4.7 github.com/gdamore/tcell v1.1.5-0.20190724020331-84b54971b46c diff --git a/go.sum b/go.sum index 2749ac5..8f08a7a 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/emersion/go-imap v1.0.0 h1:/7HHNiSOk13DErenBZaQfTBmUy+quc6X7s3RNnuVtU github.com/emersion/go-imap v1.0.0/go.mod h1:MEiDDwwQFcZ+L45Pa68jNGv0qU9kbW+SJzwDpvSfX1s= github.com/emersion/go-imap-idle v0.0.0-20190519112320-2704abd7050e h1:L7bswVJZcf2YHofgom49oFRwVqmBj/qZqDy9/SJpZMY= github.com/emersion/go-imap-idle v0.0.0-20190519112320-2704abd7050e/go.mod h1:o14zPKCmEH5WC1vU5SdPoZGgNvQx7zzKSnxPQlobo78= +github.com/emersion/go-imap-sortthread v1.0.1-0.20191002194849-97d602f80823 h1:E0Uc67DpLgG/nt8NhEqQ77TNGq3zDH1uvi4obW3SAyU= +github.com/emersion/go-imap-sortthread v1.0.1-0.20191002194849-97d602f80823/go.mod h1:opHOzblOHZKQM1JEy+GPk1217giNLa7kleyWTN06qnc= github.com/emersion/go-maildir v0.0.0-20190727102040-941194b0ac70 h1:aUiPu6/iCjcsnNe/WkhsnMOq7vPmkYo9kFaMX5FiNZU= github.com/emersion/go-maildir v0.0.0-20190727102040-941194b0ac70/go.mod h1:I2j27lND/SRLgxROe50Vam81MSaqPFvJ0OHNnDZ7n84= github.com/emersion/go-message v0.10.4-0.20190609165112-592ace5bc1ca/go.mod h1:3h+HsGTCFHmk4ngJ2IV/YPhdlaOcR6hcgqM3yca9v7c= @@ -28,6 +30,8 @@ github.com/emersion/go-sasl v0.0.0-20190520160400-47d427600317 h1:tYZxAY8nu3JJQK github.com/emersion/go-sasl v0.0.0-20190520160400-47d427600317/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k= github.com/emersion/go-sasl v0.0.0-20190704090222-36b50694675c h1:Spm8jy+jWYG/Dn6ygbq/LBW/6M27kg59GK+FkKjexuw= github.com/emersion/go-sasl v0.0.0-20190704090222-36b50694675c/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k= +github.com/emersion/go-sasl v0.0.0-20190817083125-240c8404624e h1:ba7YsgX5OV8FjGi5ZWml8Jng6oBrJAb3ahqWMJ5Ce8Q= +github.com/emersion/go-sasl v0.0.0-20190817083125-240c8404624e/go.mod h1:G/dpzLu16WtQpBfQ/z3LYiYJn3ZhKSGWn83fyoyQe/k= github.com/emersion/go-smtp v0.11.2 h1:5PO2Kwsx+HXuytntCfMvcworC/iq45TPGkwjnaBZFSg= github.com/emersion/go-smtp v0.11.2/go.mod h1:byi9Y32SuKwjTJt9DO2tTWYjtF3lEh154tE1AcaJQSY= github.com/emersion/go-textwrapper v0.0.0-20160606182133-d0e65e56babe h1:40SWqY0zE3qCi6ZrtTf5OUdNm5lDnGnjRSq9GgmeTrg= 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 4d3e51c..1ba3774 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 } @@ -153,7 +155,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) @@ -161,6 +163,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: -- cgit v1.2.3