diff options
author | Koni Marti <koni.marti@gmail.com> | 2022-11-15 21:24:50 +0100 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-12-02 22:59:40 +0100 |
commit | 739ec7933b0b4a6aa13761759b90a33e34f24a7c (patch) | |
tree | 8a5c01709d4664f4061f6aabcca57087e557ce44 | |
parent | ff101bda430dda18e6f150ce6915891139ecccd9 (diff) | |
download | aerc-739ec7933b0b4a6aa13761759b90a33e34f24a7c.tar.gz |
maildir: filter and search with a date range
Filter and search with a date range in the maildir backend.
Signed-off-by: Koni Marti <koni.marti@gmail.com>
Acked-by: Robin Jarry <robin@jarry.cc>
-rw-r--r-- | doc/aerc-search.1.scd | 6 | ||||
-rw-r--r-- | worker/maildir/search.go | 44 |
2 files changed, 43 insertions, 7 deletions
diff --git a/doc/aerc-search.1.scd b/doc/aerc-search.1.scd index 119e222d..51e93ade 100644 --- a/doc/aerc-search.1.scd +++ b/doc/aerc-search.1.scd @@ -6,7 +6,7 @@ aerc-search - search and filter patterns and options for *aerc*(1) # MAILDIR & IMAP -*search* [*-ruba*] [*-x* _<flag>_] [*-X* _<flag>_] [*-f* _<from>_] [*-t* _<to>_] [*-c* _<cc>_] [_<terms>_...] +*search* [*-ruba*] [*-x* _<flag>_] [*-X* _<flag>_] [*-f* _<from>_] [*-t* _<to>_] [*-c* _<cc>_] [*-d* _<start[,end]>_] [_<terms>_...] Searches the current folder for messages matching the given set of conditions. @@ -40,6 +40,10 @@ aerc-search - search and filter patterns and options for *aerc*(1) *-c* _<cc>_: Search for messages cc'ed to _<cc>_ + *-d* _<start[..end]>_: + Search for messages within a particular date range defined as + \[start, end) where the dates are in the YYYY-MM-DD format. + # NOTMUCH *search* _query_... diff --git a/worker/maildir/search.go b/worker/maildir/search.go index 3a78937d..e70282e2 100644 --- a/worker/maildir/search.go +++ b/worker/maildir/search.go @@ -6,6 +6,7 @@ import ( "runtime" "strings" "sync" + "time" "unicode" "github.com/emersion/go-maildir" @@ -15,6 +16,7 @@ import ( "git.sr.ht/~rjarry/aerc/lib" "git.sr.ht/~rjarry/aerc/log" "git.sr.ht/~rjarry/aerc/models" + wlib "git.sr.ht/~rjarry/aerc/worker/lib" ) type searchCriteria struct { @@ -24,16 +26,14 @@ type searchCriteria struct { WithFlags []maildir.Flag WithoutFlags []maildir.Flag -} -func newSearchCriteria() *searchCriteria { - return &searchCriteria{Header: make(textproto.MIMEHeader)} + startDate, endDate time.Time } func parseSearch(args []string) (*searchCriteria, error) { - criteria := newSearchCriteria() + criteria := &searchCriteria{Header: make(textproto.MIMEHeader)} - opts, optind, err := getopt.Getopts(args, "rux:X:bat:H:f:c:") + opts, optind, err := getopt.Getopts(args, "rux:X:bat:H:f:c:d:") if err != nil { return nil, err } @@ -61,6 +61,18 @@ func parseSearch(args []string) (*searchCriteria, error) { body = true case 'a': text = true + case 'd': + start, end, err := wlib.ParseDateRange(opt.Value) + if err != nil { + log.Errorf("failed to parse start date: %v", err) + continue + } + if !start.IsZero() { + criteria.startDate = start + } + if !end.IsZero() { + criteria.endDate = end + } } } switch { @@ -149,7 +161,7 @@ func (w *Worker) searchKey(key uint32, criteria *searchCriteria, return false, err } } - if parts&HEADER > 0 { + if parts&HEADER > 0 || parts&DATE > 0 { header, err = message.MessageInfo() if err != nil { return false, err @@ -225,6 +237,22 @@ func (w *Worker) searchKey(key uint32, criteria *searchCriteria, } } } + if parts&DATE > 0 { + if date, err := header.RFC822Headers.Date(); err != nil { + log.Errorf("Failed to get date from header: %v", err) + } else { + if !criteria.startDate.IsZero() { + if date.Before(criteria.startDate) { + return false, nil + } + } + if !criteria.endDate.IsZero() { + if date.After(criteria.endDate) { + return false, nil + } + } + } + } return true, nil } @@ -264,6 +292,7 @@ const NONE MsgParts = 0 const ( FLAGS MsgParts = 1 << iota HEADER + DATE BODY ALL ) @@ -275,6 +304,9 @@ func getRequiredParts(criteria *searchCriteria) MsgParts { if len(criteria.Header) > 0 { required |= HEADER } + if !criteria.startDate.IsZero() || !criteria.endDate.IsZero() { + required |= DATE + } if criteria.Body != nil && len(criteria.Body) > 0 { required |= BODY } |