diff options
Diffstat (limited to 'worker/imap')
-rw-r--r-- | worker/imap/list.go | 6 | ||||
-rw-r--r-- | worker/imap/open.go | 23 | ||||
-rw-r--r-- | worker/imap/search.go | 115 |
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 } |