diff options
author | Reto Brunner <reto@labrat.space> | 2020-09-12 15:05:02 +0200 |
---|---|---|
committer | Reto Brunner <reto@labrat.space> | 2020-10-11 09:18:45 +0200 |
commit | b6bcf89784605aa8baa982677de9d8d8ddbaa404 (patch) | |
tree | 532a17d2c5fbf67b1576ca718596e271b631b384 /worker | |
parent | d8a75a5159eb9bf18e629be0598aaef5f90da7e4 (diff) | |
download | aerc-b6bcf89784605aa8baa982677de9d8d8ddbaa404.tar.gz |
imap: add sort support
Diffstat (limited to 'worker')
-rw-r--r-- | worker/imap/open.go | 49 | ||||
-rw-r--r-- | worker/imap/worker.go | 4 |
2 files changed, 50 insertions, 3 deletions
diff --git a/worker/imap/open.go b/worker/imap/open.go index 0602a7fa..891b8a23 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" ) @@ -30,9 +31,29 @@ func (imapw *IMAPWorker) handleFetchDirectoryContents( seqSet := &imap.SeqSet{} seqSet.AddRange(1, imapw.selected.Messages) - uids, err := imapw.client.UidSearch(&imap.SearchCriteria{ + + searchCriteria := &imap.SearchCriteria{ SeqNum: seqSet, - }) + } + sortCriteria := translateSortCriterions(msg.SortCriteria) + + var uids []uint32 + + // If the server supports the SORT extension, do the sorting server side + ok, err := imapw.client.sort.SupportSort() + if err == nil && ok && len(sortCriteria) > 0 { + uids, err = imapw.client.sort.UidSort(sortCriteria, searchCriteria) + // copy in reverse as msgList displays backwards + for i, j := 0, len(uids)-1; i < j; i, j = i+1, j-1 { + uids[i], uids[j] = uids[j], uids[i] + } + } else { + if err != nil { + // Non fatal, but we do want to print to get some debug info + imapw.worker.Logger.Printf("can't check for SORT support: %v", err) + } + uids, err = imapw.client.UidSearch(searchCriteria) + } if err != nil { imapw.worker.PostMessage(&types.Error{ Message: types.RespondTo(msg), @@ -50,3 +71,27 @@ func (imapw *IMAPWorker) handleFetchDirectoryContents( imapw.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) } } + +type sortFieldMapT map[types.SortField]sortthread.SortField + +// caution, incomplete mapping +var sortFieldMap sortFieldMapT = sortFieldMapT{ + types.SortArrival: sortthread.SortArrival, + types.SortCc: sortthread.SortCc, + types.SortDate: sortthread.SortDate, + types.SortFrom: sortthread.SortFrom, + types.SortSize: sortthread.SortSize, + types.SortSubject: sortthread.SortSubject, + types.SortTo: sortthread.SortTo, +} + +func translateSortCriterions( + cs []*types.SortCriterion) []sortthread.SortCriterion { + result := make([]sortthread.SortCriterion, 0, len(cs)) + for _, c := range cs { + if f, ok := sortFieldMap[c.Field]; ok { + result = append(result, sortthread.SortCriterion{f, c.Reverse}) + } + } + return result +} diff --git a/worker/imap/worker.go b/worker/imap/worker.go index c016af66..dab0afb5 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" @@ -27,6 +28,7 @@ var errUnsupported = fmt.Errorf("unsupported command") type imapClient struct { *client.Client idle *idle.IdleClient + sort *sortthread.SortClient } type IMAPWorker struct { @@ -155,7 +157,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error { } c.Updates = w.updates - w.client = &imapClient{c, idle.NewClient(c)} + w.client = &imapClient{c, idle.NewClient(c), sortthread.NewSortClient(c)} w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) case *types.ListDirectories: w.handleListDirectories(msg) |