unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* date parser branch updated and rebased
@ 2010-02-08  9:41 Sebastian Spaeth
  2010-02-08 11:14 ` [PATCH 1/4] add date parser file from Keith Sebastian Spaeth
  0 siblings, 1 reply; 6+ messages in thread
From: Sebastian Spaeth @ 2010-02-08  9:41 UTC (permalink / raw)
  To: Notmuch development list

In order to not let this bitrot, I just rebased my dateparser branch to
current cworth master and split up the patches in a nicer way.
I made sure that every commit compiles. Let me know if there are things
that should be handled in a different way.

find the git branch here:
http://github.com/spaetz/notmuch-all-feature/commits/dateparser5

All 4 patches are going to be send as a reply to this mail in a second.

Sebastian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] add date parser file from Keith
  2010-02-08  9:41 date parser branch updated and rebased Sebastian Spaeth
@ 2010-02-08 11:14 ` Sebastian Spaeth
  2010-02-08 11:14   ` [PATCH 2/4] Introduce new notmuch return status NOTMUCH_STATUS_INVALID_DATE Sebastian Spaeth
  0 siblings, 1 reply; 6+ messages in thread
From: Sebastian Spaeth @ 2010-02-08 11:14 UTC (permalink / raw)
  To: notmuch

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 9550 bytes --]

From: Keith Packard <keithp@keithp.com>

Here's some code which further improves date parsing by allowing lots of
date formats, including things like "today", "thisweek", ISO and US date
formats and month names. You can separate two dates with .. to make a
range, or you can just use the default range ("lastmonth" is everything
From the 1st of the previous month to the 1st of the current month).

Sebastian Spaeth removed 2 unneeded functions and silenced some unused variable warnings, but left the code otherwise as-is.
---
 lib/date.c |  414 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 414 insertions(+), 0 deletions(-)
 create mode 100644 lib/date.c

diff --git a/lib/date.c b/lib/date.c
new file mode 100644
index 0000000..805a1d9
--- /dev/null
+++ b/lib/date.c
@@ -0,0 +1,414 @@
+/*
+ * Copyright © 2009 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include "notmuch.h"
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define DAY	(24 * 60 * 60)
+
+static void
+today(struct tm *result, time_t after) {
+    time_t	t;
+
+    if (after)
+	t = after;
+    else
+	time(&t);
+    localtime_r(&t, result);
+    result->tm_sec = result->tm_min = result->tm_hour = 0;
+}
+
+static int parse_today(const char *text, time_t *first, time_t *last, time_t after) {
+    (void)after; /*disable unused paramter warning*/
+    if (strcasecmp(text, "today") == 0) {
+	struct tm n;
+	today(&n, 0);
+	*first = mktime(&n);
+	*last = *first + DAY;
+	return 0;
+    }
+    return 1;
+}
+
+static int parse_yesterday(const char *text, time_t *first, time_t *last, time_t after) {
+    if (strcasecmp(text, "yesterday") == 0) {
+	struct tm n;
+	today(&n, 0);
+	*last = mktime(&n);
+	*first = *last - DAY;
+	return 0;
+    }
+    return 1;
+    (void)after; /*disable unused paramter warning*/
+}
+
+static int parse_thisweek(const char *text, time_t *first, time_t *last, time_t after) {
+    if (strcasecmp(text, "thisweek") == 0) {
+	struct tm n;
+	today(&n, 0);
+	*first = mktime(&n) - (n.tm_wday * DAY);
+	*last = *first + DAY * 7;
+	return 0;
+    }
+    return 1;
+    (void)after; /*disable unused paramter warning*/
+}
+
+static int parse_lastweek(const char *text, time_t *first, time_t *last, time_t after) {
+    if (strcasecmp(text, "lastweek") == 0) {
+	struct tm n;
+	today(&n, 0);
+	*last = mktime(&n) - (n.tm_wday * DAY);
+	*first = *last - DAY * 7;
+	return 0;
+    }
+    return 1;
+    (void)after; /*disable unused paramter warning*/
+}
+
+static int parse_thismonth(const char *text, time_t *first, time_t *last, time_t after) {
+    if (strcasecmp(text, "thismonth") == 0) {
+	struct tm n;
+	today(&n, 0);
+	n.tm_mday = 1;
+	*first = mktime(&n);
+	if (n.tm_mon++ == 12) {
+	    n.tm_mon = 0;
+	    n.tm_year++;
+	}
+	*last = mktime(&n);
+	return 0;
+    }
+    return 1;
+    (void)after; /*disable unused paramter warning*/
+}
+
+static int parse_lastmonth(const char *text, time_t *first, time_t *last, time_t after) {
+    if (strcasecmp(text, "lastmonth") == 0) {
+	struct tm n;
+	today(&n, 0);
+	n.tm_mday = 1;
+	if (n.tm_mon == 0) {
+	    n.tm_year--;
+	    n.tm_mon = 11;
+	} else
+	    n.tm_mon--;
+	*first = mktime(&n);
+	if (n.tm_mon++ == 12) {
+	    n.tm_mon = 0;
+	    n.tm_year++;
+	}
+	*last = mktime(&n);
+	return 0;
+    }
+    return 1;
+    (void)after; /*disable unused paramter warning*/
+}
+
+static const char *months[12][2] = {
+    { "January", "Jan" },
+    { "February", "Feb" },
+    { "March", "Mar" },
+    { "April", "Apr" },
+    { "May", "May" },
+    { "June", "Jun" },
+    { "July", "Jul" },
+    { "August", "Aug" },
+    { "September", "Sep" },
+    { "October", "Oct" },
+    { "November", "Nov" },
+    { "December", "Dec" },
+};
+
+static int year(const char *text, int *y) {
+    char *end;
+    *y = strtol(text, &end, 10);
+    if (end == text)
+	return 1;
+    if (*end != '\0')
+	return 1;
+    if (*y < 1970 || *y > 2038)
+	return 1;
+    *y -= 1900;
+    return 0;
+}
+
+static int month(const char *text, int *m) {
+    char *end;
+    int i;
+    for (i = 0; i < 12; i++) {
+	if (strcasecmp(text, months[i][0]) == 0 ||
+	    strcasecmp(text, months[i][1]) == 0)
+	{
+	    *m = i;
+	    return 0;
+	}
+    }
+    *m = strtol(text, &end, 10);
+    if (end == text)
+	return 1;
+    if (*end != '\0')
+	return 1;
+    if (*m < 1 || *m > 12)
+	return 1;
+    *m -= 1;
+    return 0;
+}
+
+static int day(const char *text, int *d) {
+    char *end;
+    *d = strtol(text, &end, 10);
+    if (end == text)
+	return 1;
+    if (*end != '\0')
+	return 1;
+    if (*d < 1 || *d > 31)
+	return 1;
+    return 0;
+}
+
+/* month[-day] */
+static int parse_month(const char *text, time_t *first, time_t *last, time_t after) {
+    int		m = 0, d = 0;
+    int		i;
+    struct tm	n;
+    char	tmp[80];
+    char	*t;
+    char	*save;
+    char	*token;
+
+    if(strlen (text) >= sizeof (tmp))
+	return 1;
+    strcpy(tmp, text);
+
+    t = tmp;
+    save = NULL;
+    i = 0;
+    while ((token = strtok_r(t, "-", &save)) != NULL) {
+	i++;
+	switch(i) {
+	case 1:
+	    if (month(token, &m) != 0)
+		return 1;
+	    break;
+	case 2:
+	    if (day(token, &d) != 0)
+		return 1;
+	    break;
+	default:
+	    return 1;
+	}
+	t = NULL;
+    }
+    today(&n, after);
+    if (after) {
+	if (m < n.tm_mon)
+	    n.tm_year++;
+    } else {
+	if (m > n.tm_mon)
+	    n.tm_year--;
+    }
+    switch (i) {
+    case 1:
+	n.tm_mday = 1;
+	n.tm_mon = m;
+	*first = mktime(&n);
+	if (++n.tm_mon > 11) {
+	    n.tm_mon = 0;
+	    n.tm_year++;
+	}
+	*last = mktime(&n);
+	return 0;
+    case 2:
+	n.tm_mday = d;
+	n.tm_mon = m;
+	*first = mktime(&n);
+	*last = *first + DAY;
+	return 0;
+    }
+    return 1;
+}
+
+/* year[-month[-day]] */
+static int parse_iso(const char *text, time_t *first, time_t *last, time_t after) {
+    int		y = 0, m = 0, d = 0;
+    int		i;
+    struct tm	n;
+    char	tmp[80];
+    char	*t;
+    char	*save;
+    char	*token;
+
+    if(strlen (text) >= sizeof (tmp))
+	return 1;
+    strcpy(tmp, text);
+
+    t = tmp;
+    save = NULL;
+    i = 0;
+    while ((token = strtok_r(t, "-", &save)) != NULL) {
+	i++;
+	switch(i) {
+	case 1:
+	    if (year(token, &y) != 0)
+		return 1;
+	    break;
+	case 2:
+	    if (month(token, &m) != 0)
+		return 1;
+	    break;
+	case 3:
+	    if (day(token, &d) != 0)
+		return 1;
+	    break;
+	default:
+	    return 1;
+	}
+	t = NULL;
+    }
+    today(&n, 0);
+    switch (i) {
+    case 1:
+	n.tm_mday = 1;
+	n.tm_mon = 0;
+	n.tm_year = y;
+	*first = mktime(&n);
+	n.tm_year = y + 1;
+	*last = mktime(&n);
+	return 0;
+    case 2:
+	n.tm_mday = 1;
+	n.tm_mon = m;
+	n.tm_year = y;
+	*first = mktime(&n);
+	if (++n.tm_mon > 11) {
+	    n.tm_mon = 0;
+	    n.tm_year++;
+	}
+	*last = mktime(&n);
+	return 0;
+    case 3:
+	n.tm_mday = d;
+	n.tm_mon = m;
+	n.tm_year = y;
+	*first = mktime(&n);
+	*last = *first + DAY;
+	return 0;
+    }
+    return 1;
+    (void)after; /*disable unused paramter warning*/
+}
+
+/* month[/day[/year]] */
+static int parse_us(const char *text, time_t *first, time_t *last, time_t after) {
+    int		y = 0, m = 0, d = 0;
+    int		i;
+    struct tm	n;
+    char	tmp[80];
+    char	*t;
+    char	*save;
+    char	*token;
+
+    if(strlen (text) >= sizeof (tmp))
+	return 1;
+    strcpy(tmp, text);
+
+    t = tmp;
+    save = NULL;
+    i = 0;
+    while ((token = strtok_r(t, "/", &save)) != NULL) {
+	i++;
+	switch(i) {
+	case 1:
+	    if (month(token, &m) != 0)
+		return 1;
+	    break;
+	case 2:
+	    if (day(token, &d) != 0)
+		return 1;
+	    break;
+	case 3:
+	    if (year(token, &y) != 0)
+		return 1;
+	    break;
+	default:
+	    return 1;
+	}
+	t = NULL;
+    }
+    today(&n, after);
+    if (after) {
+	if (m < n.tm_mon)
+	    n.tm_year++;
+    } else {
+	if (m > n.tm_mon)
+	    n.tm_year--;
+    }
+    switch (i) {
+    case 1:
+	n.tm_mday = 1;
+	n.tm_mon = m;
+	*first = mktime(&n);
+	if (++n.tm_mon > 11) {
+	    n.tm_mon = 0;
+	    n.tm_year++;
+	}
+	*last = mktime(&n);
+	return 0;
+    case 2:
+	n.tm_mday = d;
+	n.tm_mon = m;
+	*first = mktime(&n);
+	*last = *first + DAY;
+	return 0;
+    case 3:
+	n.tm_mday = d;
+	n.tm_mon = m;
+	n.tm_year = y;
+	*first = mktime(&n);
+	*last = *first + DAY;
+	return 0;
+    }
+    return 1;
+}
+
+static int (*parsers[])(const char *text, time_t *first, time_t *last, time_t after) = {
+    parse_today,
+    parse_yesterday,
+    parse_thisweek,
+    parse_lastweek,
+    parse_thismonth,
+    parse_lastmonth,
+    parse_month,
+    parse_iso,
+    parse_us,
+    0,
+};
+
+notmuch_status_t
+notmuch_parse_date(const char *text, time_t *first, time_t *last, time_t after)
+{
+    int		i;
+    for (i = 0; parsers[i]; i++)
+	if (parsers[i](text, first, last, after) == 0)
+	    return NOTMUCH_STATUS_SUCCESS;
+    return NOTMUCH_STATUS_INVALID_DATE;
+}
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] Introduce new notmuch return status NOTMUCH_STATUS_INVALID_DATE
  2010-02-08 11:14 ` [PATCH 1/4] add date parser file from Keith Sebastian Spaeth
@ 2010-02-08 11:14   ` Sebastian Spaeth
  2010-02-08 11:14     ` [PATCH 3/4] integrate date parser Sebastian Spaeth
  0 siblings, 1 reply; 6+ messages in thread
From: Sebastian Spaeth @ 2010-02-08 11:14 UTC (permalink / raw)
  To: notmuch

This is not used yet in this commit but will be the return value in case the date parser gets handed invalid dates.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
---
 lib/database.cc |    2 ++
 lib/notmuch.h   |    3 +++
 notmuch-new.c   |    1 +
 3 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/lib/database.cc b/lib/database.cc
index cce7847..ddda933 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -219,6 +219,8 @@ notmuch_status_to_string (notmuch_status_t status)
 	return "Erroneous NULL pointer";
     case NOTMUCH_STATUS_TAG_TOO_LONG:
 	return "Tag value is too long (exceeds NOTMUCH_TAG_MAX)";
+    case NOTMUCH_STATUS_INVALID_DATE:
+	return "Date value did not parse to a valid date";
     case NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW:
 	return "Unbalanced number of calls to notmuch_message_freeze/thaw";
     default:
diff --git a/lib/notmuch.h b/lib/notmuch.h
index d3e50a7..56a76d1 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -78,6 +78,8 @@ typedef int notmuch_bool_t;
  * NOTMUCH_STATUS_TAG_TOO_LONG: A tag value is too long (exceeds
  *	NOTMUCH_TAG_MAX)
  *
+ * NOTMUCH_STATUS_INVALID_DATE: Date parsing failed
+ *
  * NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW: The notmuch_message_thaw
  *	function has been called more times than notmuch_message_freeze.
  *
@@ -96,6 +98,7 @@ typedef enum _notmuch_status {
     NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID,
     NOTMUCH_STATUS_NULL_POINTER,
     NOTMUCH_STATUS_TAG_TOO_LONG,
+    NOTMUCH_STATUS_INVALID_DATE,
     NOTMUCH_STATUS_UNBALANCED_FREEZE_THAW,
 
     NOTMUCH_STATUS_LAST_STATUS
diff --git a/notmuch-new.c b/notmuch-new.c
index f25c71f..5da31c1 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -431,6 +431,7 @@ add_files_recursive (notmuch_database_t *notmuch,
 	    ret = status;
 	    goto DONE;
 	default:
+	case NOTMUCH_STATUS_INVALID_DATE:
 	case NOTMUCH_STATUS_FILE_ERROR:
 	case NOTMUCH_STATUS_NULL_POINTER:
 	case NOTMUCH_STATUS_TAG_TOO_LONG:
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] integrate date parser
  2010-02-08 11:14   ` [PATCH 2/4] Introduce new notmuch return status NOTMUCH_STATUS_INVALID_DATE Sebastian Spaeth
@ 2010-02-08 11:14     ` Sebastian Spaeth
  2010-02-08 11:14       ` [PATCH 4/4] add documentation for the new daterange parser and remove TODO list item Sebastian Spaeth
  0 siblings, 1 reply; 6+ messages in thread
From: Sebastian Spaeth @ 2010-02-08 11:14 UTC (permalink / raw)
  To: notmuch

Integrate and make use of the notmuch_parse_date() function in date.c that is being called by the new MaildateValueRangeProcessor in lib/database.cc
Thanks to keithp for donating the date parser for achieving this in a nice way.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
---
 lib/Makefile.local |    1 +
 lib/database.cc    |   33 ++++++++++++++++++++++++++++++++-
 lib/notmuch.h      |   17 +++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletions(-)

diff --git a/lib/Makefile.local b/lib/Makefile.local
index 70489e1..44deaf8 100644
--- a/lib/Makefile.local
+++ b/lib/Makefile.local
@@ -3,6 +3,7 @@ extra_cflags += -I$(dir)
 
 libnotmuch_c_srcs =		\
 	$(dir)/libsha1.c	\
+	$(dir)/date.c	\
 	$(dir)/message-file.c	\
 	$(dir)/messages.c	\
 	$(dir)/sha1.c		\
diff --git a/lib/database.cc b/lib/database.cc
index ddda933..78cd898 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -496,6 +496,37 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)
     return NOTMUCH_STATUS_SUCCESS;
 }
 
+struct MaildateValueRangeProcessor : public Xapian::ValueRangeProcessor {
+    MaildateValueRangeProcessor() {}
+
+    Xapian::valueno operator()(std::string &begin, std::string &end) {
+      time_t begin_first,begin_last, end_first, end_last;
+      int retval;
+
+      if (begin.substr(0, 5) != "date:")
+	 return Xapian::BAD_VALUENO;
+      begin.erase(0, 5);
+
+      retval = notmuch_parse_date(begin.c_str(), &begin_first, &begin_last, 0);
+
+      if (retval == NOTMUCH_STATUS_INVALID_DATE) {
+	fprintf(stderr,"Begin date failed to parse: %s",begin.c_str());
+	return Xapian::BAD_VALUENO;
+      }
+
+      retval = notmuch_parse_date(end.c_str(),&end_first,&end_last,begin_first);
+      if (retval == NOTMUCH_STATUS_INVALID_DATE) {
+	fprintf(stderr,"End date failed to parse: %s",end.c_str());
+	return Xapian::BAD_VALUENO;
+      }
+
+      begin.assign(Xapian::sortable_serialise(begin_first));
+      end.assign(Xapian::sortable_serialise(end_last));
+
+      return NOTMUCH_VALUE_TIMESTAMP;
+    }
+};
+
 notmuch_database_t *
 notmuch_database_open (const char *path,
 		       notmuch_database_mode_t mode)
@@ -572,7 +603,7 @@ notmuch_database_open (const char *path,
 	notmuch->query_parser = new Xapian::QueryParser;
 	notmuch->term_gen = new Xapian::TermGenerator;
 	notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));
-	notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP);
+	notmuch->value_range_processor = new MaildateValueRangeProcessor();
 
 	notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);
 	notmuch->query_parser->set_database (*notmuch->xapian_db);
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 56a76d1..fa8f41a 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -1089,6 +1089,23 @@ notmuch_filenames_advance (notmuch_filenames_t *filenames);
 void
 notmuch_filenames_destroy (notmuch_filenames_t *filenames);
 
+notmuch_status_t
+notmuch_parse_date(const char *text, time_t *first, time_t *last, time_t after);
+/* Parse a string into the first and last possible timestamps.
+ * It parses the possible formats and stops if one pattern matches.
+ * Keywords: 'today','yesterday','thisweek','lastweek','thismonth',
+ *           'lastmonth'
+ * Month-day : month[-day]] (month: January, Jan, or 1)\n"
+ * ISO format: year[-month[-day]]
+ * US format : month[/day[/year]]
+ *
+ * 'after' is used to fill in bits from context if left out, e.g. a
+ * 'date:2004..01' will find from 2004-01-01 through 2004-01-31
+ *
+ * Return values:
+ * NOTMUCH_STATUS_SUCCESS
+ * NOTMUCH_STATUS_INVALID_DATE: Error parsing the date string
+ */
 NOTMUCH_END_DECLS
 
 #endif
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] add documentation for the new daterange parser and remove TODO list item
  2010-02-08 11:14     ` [PATCH 3/4] integrate date parser Sebastian Spaeth
@ 2010-02-08 11:14       ` Sebastian Spaeth
  2010-02-08 12:57         ` [PATCH] notmuch-test: add tests for counting within absolute time ranges and 'today' Sebastian Spaeth
  0 siblings, 1 reply; 6+ messages in thread
From: Sebastian Spaeth @ 2010-02-08 11:14 UTC (permalink / raw)
  To: notmuch

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
---
 TODO      |    9 ---------
 notmuch.1 |   29 ++++++++++++++++++++---------
 notmuch.c |   24 +++++++++++++-----------
 3 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/TODO b/TODO
index bdfe64c..86cbf74 100644
--- a/TODO
+++ b/TODO
@@ -114,15 +114,6 @@ notmuch library
 ---------------
 Index content from citations, please.
 
-Provide a sane syntax for date ranges. First, we don't want to require
-both endpoints to be specified. For example it would be nice to be
-able to say things like "since:2009-01-1" or "until:2009-01-1" and
-have the other endpoint be implicit. Second we'd like to support
-relative specifications of time such as "since:'2 months ago'". To do
-any of this we're probably going to need to break down an write our
-own parser for the query string rather than using Xapian's QueryParser
-class.
-
 Make failure to read a file (such as a permissions problem) a warning
 rather than an error (should be similar to the existing warning for a
 non-mail file).
diff --git a/notmuch.1 b/notmuch.1
index 282ad98..19628f0 100644
--- a/notmuch.1
+++ b/notmuch.1
@@ -413,17 +413,28 @@ expression).
 Finally, results can be restricted to only messages within a
 particular time range, (based on the Date: header) with a syntax of:
 
-	<intial-timestamp>..<final-timestamp>
+	date:<startdate>..<enddate>
 
-Each timestamp is a number representing the number of seconds since
-1970-01-01 00:00:00 UTC. This is not the most convenient means of
-expressing date ranges, but until notmuch is fixed to accept a more
-convenient form, one can use the date program to construct
-timestamps. For example, with the bash shell the folowing syntax would
-specify a date range to return messages from 2009-10-01 until the
-current time:
+A
+.B date
+can be specified in various formats. It parses the formats in this order and stops if one pattern matches:
+
+	Keywords:
+.B today,
+.B yesterday,
+.B thisweek,
+.B lastweek,
+.B thismonth,
+.B lastmonth.
+
+	Month-day: month[-day]] (month: "January", "Jan", 1)
+
+	ISO format: year[-month[-day]]
+
+	US format : month[/day[/year]]
+
+The date parser will try to fill in bits in the enddate from context if left out, e.g. a 'date:2004..01' will find from 2004-01-01 through 2004-01-31.
 
-	$(date +%s -d 2009-10-01)..$(date +%s)
 .SH SEE ALSO
 The emacs-based interface to notmuch (available as
 .B notmuch.el
diff --git a/notmuch.c b/notmuch.c
index 87479f8..b8fe01a 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -92,19 +92,21 @@ static const char search_terms_help[] =
     "\t\tmarks around any parenthesized expression).\n"
     "\n"
     "\t\tFinally, results can be restricted to only messages within a\n"
-    "\t\tparticular time range, (based on the Date: header) with:\n"
+    "\t\tparticular time range, (based on the Date: header) with a\n"
+    "\t\tsyntax of: date:<startdate>..<enddate>\n"
     "\n"
-    "\t\t\t<intial-timestamp>..<final-timestamp>\n"
+    "\t\tIt can be specified in the following formats, parsing will \n"
+    "\t\tstop if the first pattern matches:\n"
+    "\t\tKeywords: 'today','yesterday','thisweek','lastweek',\n"
+    "\t\t'thismonth', 'lastmonth'. \n"
+    "\t\tmonth-day : month[-day]] (month: January, Jan, or 1)\n"
+    "\t\tISO format: year[-month[-day]] (month: January, Jan, or 1)\n"
+    "\t\tUS format : month[/day[/year]]\n"
     "\n"
-    "\t\tEach timestamp is a number representing the number of seconds\n"
-    "\t\tsince 1970-01-01 00:00:00 UTC. This is not the most convenient\n"
-    "\t\tmeans of expressing date ranges, but until notmuch is fixed to\n"
-    "\t\taccept a more convenient form, one can use the date program to\n"
-    "\t\tconstruct timestamps. For example, with the bash shell the\n"
-    "\t\tfollowing syntax would specify a date range to return messages\n"
-    "\t\tfrom 2009-10-01 until the current time:\n"
-    "\n"
-    "\t\t\t$(date +%%s -d 2009-10-01)..$(date +%%s)\n\n";
+    "\t\tThe parser will fill in bits in the enddate from context if\n"
+    "\t\tleft out, e.g. a 'date:2004..01' will find from 2004-01-01\n"
+    "\t\tthrough 2004-01-31\n"
+    "\n\n";
 
 command_t commands[] = {
     { "setup", notmuch_setup_command,
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH] notmuch-test: add tests for counting within absolute time ranges and 'today'
  2010-02-08 11:14       ` [PATCH 4/4] add documentation for the new daterange parser and remove TODO list item Sebastian Spaeth
@ 2010-02-08 12:57         ` Sebastian Spaeth
  0 siblings, 0 replies; 6+ messages in thread
From: Sebastian Spaeth @ 2010-02-08 12:57 UTC (permalink / raw)
  To: notmuch

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
---
 test/notmuch-test |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/test/notmuch-test b/test/notmuch-test
index 2e5eb24..adc9f24 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -534,6 +534,19 @@ printf " Restore with nothing to do...\t"
 $NOTMUCH restore dump.expected
 echo "	PASS"
 
+# Test daterange with absolute month---------------------------------------
+printf "\nTesting \"notmuch count\" in several variations:\n"
+printf " absolute date range..."
+#Find all messages from January 2010
+execute_expecting "count date:2010-01..01" "8"
+
+# Test daterange with today keyword-----------------------------------------
+printf " 'today' date range..."
+TODAY=`date -R`
+add_message '[date]="${TODAY}"'
+execute_expecting "count date:today..today" "1"
+# End Test daterange parser-------------------------------------------------
+
 cat <<EOF
 Notmuch test suite complete.
 
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-02-08 12:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-08  9:41 date parser branch updated and rebased Sebastian Spaeth
2010-02-08 11:14 ` [PATCH 1/4] add date parser file from Keith Sebastian Spaeth
2010-02-08 11:14   ` [PATCH 2/4] Introduce new notmuch return status NOTMUCH_STATUS_INVALID_DATE Sebastian Spaeth
2010-02-08 11:14     ` [PATCH 3/4] integrate date parser Sebastian Spaeth
2010-02-08 11:14       ` [PATCH 4/4] add documentation for the new daterange parser and remove TODO list item Sebastian Spaeth
2010-02-08 12:57         ` [PATCH] notmuch-test: add tests for counting within absolute time ranges and 'today' Sebastian Spaeth

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).