aboutsummaryrefslogtreecommitdiffstats
path: root/worker/imap
diff options
context:
space:
mode:
Diffstat (limited to 'worker/imap')
-rw-r--r--worker/imap/list.go6
-rw-r--r--worker/imap/open.go23
-rw-r--r--worker/imap/search.go115
3 files changed, 41 insertions, 103 deletions
diff --git a/worker/imap/list.go b/worker/imap/list.go
index fc1d7e94..5a97d5e2 100644
--- a/worker/imap/list.go
+++ b/worker/imap/list.go
@@ -115,11 +115,7 @@ func (imapw *IMAPWorker) handleSearchDirectory(msg *types.SearchDirectory) {
}
imapw.worker.Tracef("Executing search")
- criteria, err := parseSearch(msg.Argv)
- if err != nil {
- emitError(err)
- return
- }
+ criteria := translateSearch(msg.Criteria)
if msg.Context.Err() != nil {
imapw.worker.PostMessage(&types.Cancelled{
diff --git a/worker/imap/open.go b/worker/imap/open.go
index 693d93a9..355709a7 100644
--- a/worker/imap/open.go
+++ b/worker/imap/open.go
@@ -39,17 +39,11 @@ func (imapw *IMAPWorker) handleFetchDirectoryContents(
}
imapw.worker.Tracef("Fetching UID list")
- searchCriteria, err := parseSearch(msg.FilterCriteria)
- if err != nil {
- imapw.worker.PostMessage(&types.Error{
- Message: types.RespondTo(msg),
- Error: err,
- }, nil)
- return
- }
+ searchCriteria := translateSearch(msg.Filter)
sortCriteria := translateSortCriterions(msg.SortCriteria)
hasSortCriteria := len(sortCriteria) > 0
+ var err error
var uids []uint32
// If the server supports the SORT extension, do the sorting server side
@@ -87,7 +81,7 @@ func (imapw *IMAPWorker) handleFetchDirectoryContents(
return
}
imapw.worker.Tracef("Found %d UIDs", len(uids))
- if len(msg.FilterCriteria) == 1 {
+ if msg.Filter == nil {
// Only initialize if we are not filtering
imapw.seqMap.Initialize(uids)
}
@@ -134,14 +128,7 @@ func (imapw *IMAPWorker) handleDirectoryThreaded(
}
imapw.worker.Tracef("Fetching threaded UID list")
- searchCriteria, err := parseSearch(msg.FilterCriteria)
- if err != nil {
- imapw.worker.PostMessage(&types.Error{
- Message: types.RespondTo(msg),
- Error: err,
- }, nil)
- return
- }
+ searchCriteria := translateSearch(msg.Filter)
threads, err := imapw.client.thread.UidThread(imapw.threadAlgorithm,
searchCriteria)
if err != nil {
@@ -154,7 +141,7 @@ func (imapw *IMAPWorker) handleDirectoryThreaded(
aercThreads, count := convertThreads(threads, nil)
sort.Sort(types.ByUID(aercThreads))
imapw.worker.Tracef("Found %d threaded messages", count)
- if len(msg.FilterCriteria) == 1 {
+ if msg.Filter == nil {
// Only initialize if we are not filtering
var uids []uint32
for i := len(aercThreads) - 1; i >= 0; i-- {
diff --git a/worker/imap/search.go b/worker/imap/search.go
index e9238190..0305a80f 100644
--- a/worker/imap/search.go
+++ b/worker/imap/search.go
@@ -1,95 +1,50 @@
package imap
import (
- "errors"
- "strings"
-
"github.com/emersion/go-imap"
- "git.sr.ht/~rjarry/aerc/lib/parse"
- "git.sr.ht/~rjarry/aerc/log"
- "git.sr.ht/~sircmpwn/getopt"
+ "git.sr.ht/~rjarry/aerc/worker/types"
+ "git.sr.ht/~rjarry/go-opt"
)
-func parseSearch(args []string) (*imap.SearchCriteria, error) {
+func translateSearch(c *types.SearchCriteria) *imap.SearchCriteria {
criteria := imap.NewSearchCriteria()
- if len(args) == 0 {
- return criteria, nil
+ if c == nil {
+ return criteria
}
+ criteria.WithFlags = translateFlags(c.WithFlags)
+ criteria.WithoutFlags = translateFlags(c.WithoutFlags)
- opts, optind, err := getopt.Getopts(args, "rubax:X:t:H:f:c:d:")
- if err != nil {
- return nil, err
+ if !c.StartDate.IsZero() {
+ criteria.SentSince = c.StartDate
}
- body := false
- text := false
- for _, opt := range opts {
- switch opt.Option {
- case 'r':
- criteria.WithFlags = append(criteria.WithFlags, imap.SeenFlag)
- case 'u':
- criteria.WithoutFlags = append(criteria.WithoutFlags, imap.SeenFlag)
- case 'x':
- if f, err := getParsedFlag(opt.Value); err == nil {
- criteria.WithFlags = append(criteria.WithFlags, f)
- }
- case 'X':
- if f, err := getParsedFlag(opt.Value); err == nil {
- criteria.WithoutFlags = append(criteria.WithoutFlags, f)
- }
- case 'H':
- if strings.Contains(opt.Value, ": ") {
- HeaderValue := strings.SplitN(opt.Value, ": ", 2)
- criteria.Header.Add(HeaderValue[0], HeaderValue[1])
- } else {
- log.Errorf("Header is not given properly, must be given in format `Header: Value`")
- continue
- }
- case 'f':
- criteria.Header.Add("From", opt.Value)
- case 't':
- criteria.Header.Add("To", opt.Value)
- case 'c':
- criteria.Header.Add("Cc", opt.Value)
- case 'b':
- body = true
- case 'a':
- text = true
- case 'd':
- start, end, err := parse.DateRange(opt.Value)
- if err != nil {
- log.Errorf("failed to parse start date: %v", err)
- continue
- }
- if !start.IsZero() {
- criteria.SentSince = start
- }
- if !end.IsZero() {
- criteria.SentBefore = end
- }
- }
+ if !c.StartDate.IsZero() {
+ criteria.SentBefore = c.EndDate
}
- switch {
- case text:
- criteria.Text = args[optind:]
- case body:
- criteria.Body = args[optind:]
- default:
- for _, arg := range args[optind:] {
- criteria.Header.Add("Subject", arg)
- }
+ for k, v := range c.Headers {
+ criteria.Header[k] = v
}
- return criteria, nil
-}
-
-func getParsedFlag(name string) (string, error) {
- switch strings.ToLower(name) {
- case "seen":
- return imap.SeenFlag, nil
- case "flagged":
- return imap.FlaggedFlag, nil
- case "answered":
- return imap.AnsweredFlag, nil
+ for _, f := range c.From {
+ criteria.Header.Add("From", f)
+ }
+ for _, t := range c.To {
+ criteria.Header.Add("To", t)
+ }
+ for _, c := range c.Cc {
+ criteria.Header.Add("Cc", c)
+ }
+ terms := opt.LexArgs(c.Terms)
+ if terms.Count() > 0 {
+ switch {
+ case c.SearchAll:
+ criteria.Text = terms.Args()
+ case c.SearchBody:
+ criteria.Body = terms.Args()
+ default:
+ for _, term := range terms.Args() {
+ criteria.Header.Add("Subject", term)
+ }
+ }
}
- return imap.FlaggedFlag, errors.New("Flag not suppored")
+ return criteria
}