aboutsummaryrefslogtreecommitdiffstats
path: root/worker/middleware
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2024-07-04 22:41:34 +0200
committerRobin Jarry <robin@jarry.cc>2024-08-04 18:24:42 +0200
commit9ce6f71935945eb44a216d2efe37b1971f799c75 (patch)
tree492df53026be5b458d639d65e1182d78d015e943 /worker/middleware
parent6079239f341f2a6ff297c160697fe0c1c51aba7c (diff)
downloadaerc-9ce6f71935945eb44a216d2efe37b1971f799c75.tar.gz
imap: extend SEARCH with X-GM-RAW for full Gmail search syntax
Extend the IMAP SEARCH command with the X-GM-RAW attribute for full Gmail search syntax. It is based on the Gmail extension (X-GM-EXT-1). The search/filter command will be interpreted in the same manner as in the Gmail web interface. Link: https://support.google.com/mail/answer/7190?hl=en Signed-off-by: Koni Marti <koni.marti@gmail.com> Tested-by: Inwit <inwit@sindominio.net> Acked-by: Robin Jarry <robin@jarry.cc>
Diffstat (limited to 'worker/middleware')
-rw-r--r--worker/middleware/gmailworker.go77
1 files changed, 73 insertions, 4 deletions
diff --git a/worker/middleware/gmailworker.go b/worker/middleware/gmailworker.go
index f9924732..4f5f5456 100644
--- a/worker/middleware/gmailworker.go
+++ b/worker/middleware/gmailworker.go
@@ -1,6 +1,8 @@
package middleware
import (
+ "strconv"
+ "strings"
"sync"
"git.sr.ht/~rjarry/aerc/worker/imap/extensions/xgmext"
@@ -45,20 +47,87 @@ func (g *gmailWorker) reset(c *client.Client) error {
}
func (g *gmailWorker) ProcessAction(msg types.WorkerMessage) types.WorkerMessage {
- if msg, ok := msg.(*types.FetchMessageHeaders); ok && len(msg.Uids) > 0 {
- g.mu.Lock()
-
+ switch msg := msg.(type) {
+ case *types.FetchMessageHeaders:
handler := xgmext.NewHandler(g.client)
+
+ g.mu.Lock()
uids, err := handler.FetchEntireThreads(msg.Uids)
+ g.mu.Unlock()
if err != nil {
- g.Errorf("failed to fetch entire threads: %v", err)
+ g.Warnf("failed to fetch entire threads: %v", err)
}
if len(uids) > 0 {
msg.Uids = uids
}
+ case *types.FetchDirectoryContents:
+ if msg.Filter == nil || (msg.Filter != nil &&
+ len(msg.Filter.Terms) == 0) {
+ break
+ }
+ if !msg.Filter.UseExtension {
+ g.Debugf("use regular imap filter instead of X-GM-EXT1: " +
+ "extension flag not set")
+ break
+ }
+
+ search := strings.Join(msg.Filter.Terms, " ")
+ g.Debugf("X-GM-EXT1 filter term: '%s'", search)
+
+ handler := xgmext.NewHandler(g.client)
+
+ g.mu.Lock()
+ uids, err := handler.RawSearch(strconv.Quote(search))
+ g.mu.Unlock()
+ if err != nil {
+ g.Errorf("X-GM-EXT1 filter failed: %v", err)
+ g.Warnf("falling back to imap filtering")
+ break
+ }
+
+ g.PostMessage(&types.DirectoryContents{
+ Message: types.RespondTo(msg),
+ Uids: uids,
+ }, nil)
+
+ g.PostMessage(&types.Done{Message: types.RespondTo(msg)}, nil)
+
+ return &types.Unsupported{}
+
+ case *types.SearchDirectory:
+ if msg.Criteria == nil || (msg.Criteria != nil &&
+ len(msg.Criteria.Terms) == 0) {
+ break
+ }
+ if !msg.Criteria.UseExtension {
+ g.Debugf("use regular imap search instead of X-GM-EXT1: " +
+ "extension flag not set")
+ break
+ }
+
+ search := strings.Join(msg.Criteria.Terms, " ")
+ g.Debugf("X-GM-EXT1 search term: '%s'", search)
+ handler := xgmext.NewHandler(g.client)
+
+ g.mu.Lock()
+ uids, err := handler.RawSearch(strconv.Quote(search))
g.mu.Unlock()
+ if err != nil {
+ g.Errorf("X-GM-EXT1 search failed: %v", err)
+ g.Warnf("falling back to regular imap search.")
+ break
+ }
+
+ g.PostMessage(&types.SearchResults{
+ Message: types.RespondTo(msg),
+ Uids: uids,
+ }, nil)
+
+ g.PostMessage(&types.Done{Message: types.RespondTo(msg)}, nil)
+
+ return &types.Unsupported{}
}
return g.WorkerInteractor.ProcessAction(msg)
}