diff options
Diffstat (limited to 'worker/middleware')
-rw-r--r-- | worker/middleware/foldermapper.go | 4 | ||||
-rw-r--r-- | worker/middleware/gmailworker.go | 78 |
2 files changed, 82 insertions, 0 deletions
diff --git a/worker/middleware/foldermapper.go b/worker/middleware/foldermapper.go index ee57b9c8..ba098191 100644 --- a/worker/middleware/foldermapper.go +++ b/worker/middleware/foldermapper.go @@ -26,6 +26,10 @@ func NewFolderMapper(base types.WorkerInteractor, mapping map[string]string, } } +func (f *folderMapper) Unwrap() types.WorkerInteractor { + return f.WorkerInteractor +} + func (f *folderMapper) incoming(msg types.WorkerMessage, dir string) string { f.Lock() defer f.Unlock() diff --git a/worker/middleware/gmailworker.go b/worker/middleware/gmailworker.go new file mode 100644 index 00000000..807f7bff --- /dev/null +++ b/worker/middleware/gmailworker.go @@ -0,0 +1,78 @@ +package middleware + +import ( + "sync" + + "git.sr.ht/~rjarry/aerc/worker/imap/extensions/xgmext" + "git.sr.ht/~rjarry/aerc/worker/types" + "github.com/emersion/go-imap/client" +) + +type idler interface { + Start() + Stop() error +} + +type gmailWorker struct { + types.WorkerInteractor + mu sync.Mutex + client *client.Client + idler idler +} + +// NewGmailWorker returns an IMAP middleware for the X-GM-EXT-1 extension +func NewGmailWorker(base types.WorkerInteractor, c *client.Client, i idler, +) types.WorkerInteractor { + base.Infof("loading worker middleware: X-GM-EXT-1") + + // avoid double wrapping; unwrap and check for another gmail handler + for iter := base; iter != nil; iter = iter.Unwrap() { + if g, ok := iter.(*gmailWorker); ok { + base.Infof("already loaded; resetting") + err := g.reset(c, i) + if err != nil { + base.Errorf("reset failed: %v", err) + } + return base + } + } + return &gmailWorker{WorkerInteractor: base, client: c, idler: i} +} + +func (g *gmailWorker) Unwrap() types.WorkerInteractor { + return g.WorkerInteractor +} + +func (g *gmailWorker) reset(c *client.Client, i idler) error { + g.mu.Lock() + defer g.mu.Unlock() + g.client = c + g.idler = i + return nil +} + +func (g *gmailWorker) ProcessAction(msg types.WorkerMessage) types.WorkerMessage { + switch msg := msg.(type) { + case *types.FetchMessageHeaders: + g.mu.Lock() + err := g.idler.Stop() + if err != nil { + g.Errorf("idler reported an error: %v", err) + break + } + + handler := xgmext.NewHandler(g.client) + uids, err := handler.FetchEntireThreads(msg.Uids) + if err != nil { + g.Errorf("failed to fetch entire threads: %v", err) + } + + if len(uids) > 0 { + msg.Uids = uids + } + + g.idler.Start() + g.mu.Unlock() + } + return g.WorkerInteractor.ProcessAction(msg) +} |