[notmuch] [PATCH] Make the date parser nicer
authorSebastian Spaeth <Sebastian@SSpaeth.de>
Sun, 24 Jan 2010 14:13:53 +0000 (15:13 +0100)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:36:02 +0000 (09:36 -0800)
fb/b50ab0668462c0c48c34f5a83ca61cb555cea1 [new file with mode: 0644]

diff --git a/fb/b50ab0668462c0c48c34f5a83ca61cb555cea1 b/fb/b50ab0668462c0c48c34f5a83ca61cb555cea1
new file mode 100644 (file)
index 0000000..07edab9
--- /dev/null
@@ -0,0 +1,169 @@
+Return-Path: <Sebastian@SSpaeth.de>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 02209431FBC\r
+       for <notmuch@notmuchmail.org>; Sun, 24 Jan 2010 06:14:05 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -1.285\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-1.285 tagged_above=-999 required=5 tests=[AWL=1.314,\r
+       BAYES_00=-2.599] autolearn=ham\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id x+uuuMQxkli2 for <notmuch@notmuchmail.org>;\r
+       Sun, 24 Jan 2010 06:14:04 -0800 (PST)\r
+Received: from homiemail-a21.g.dreamhost.com (caiajhbdcbbj.dreamhost.com\r
+       [208.97.132.119])\r
+       by olra.theworths.org (Postfix) with ESMTP id 20F96431FAE\r
+       for <notmuch@notmuchmail.org>; Sun, 24 Jan 2010 06:14:04 -0800 (PST)\r
+Received: from localhost.localdomain (unknown [84.55.198.58])\r
+       by homiemail-a21.g.dreamhost.com (Postfix) with ESMTPA id 5B1FD300059; \r
+       Sun, 24 Jan 2010 06:14:02 -0800 (PST)\r
+From: Sebastian Spaeth <Sebastian@SSpaeth.de>\r
+To: notmuch@notmuchmail.org\r
+Date: Sun, 24 Jan 2010 15:13:53 +0100\r
+Message-Id: <1264342433-15663-1-git-send-email-Sebastian@SSpaeth.de>\r
+X-Mailer: git-send-email 1.6.3.3\r
+In-Reply-To: <1264173971-11879-1-git-send-email-Sebastian@SSpaeth.de>\r
+References: <1264173971-11879-1-git-send-email-Sebastian@SSpaeth.de>\r
+Subject: [notmuch] [PATCH] Make the date parser nicer\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Sun, 24 Jan 2010 14:14:05 -0000\r
+\r
+Currently we have to enter mail dates as timestamps. This approach does 2 things: 1) it requires the prefix 'date:'\r
+2) it allows dates to be specified in some formats. So a notmuch show date:2005..2006-05-12 will find all mails from 2005-01-01 until 2006-05-12.\r
+The code is probably not in a proper location yet and needs to be shoved around by someone more knowledgable than me.\r
+My C++ skills are somewhat,... lacking...\r
+\r
+Possible time formats: YYYY-MM-DD,YYYY-MM (in that month) , YYYY (in that year)\r
+MM-DD (month-day in current year), DD (day in current month)\r
+\r
+Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>\r
+---\r
+ lib/database.cc |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-\r
+ 1 files changed, 89 insertions(+), 1 deletions(-)\r
+\r
+diff --git a/lib/database.cc b/lib/database.cc\r
+index 5b12320..9c2842d 100644\r
+--- a/lib/database.cc\r
++++ b/lib/database.cc\r
+@@ -494,6 +494,94 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)\r
+     return NOTMUCH_STATUS_SUCCESS;\r
+ }\r
\r
++struct MaildateValueRangeProcessor : public Xapian::ValueRangeProcessor {\r
++    MaildateValueRangeProcessor() {}\r
++\r
++  time_t\r
++  parsedate(std::string &str, bool early) {\r
++      // Parse the begin date to time_t\r
++      // possible time formats:\r
++      // YYYY-MM-DD (size 10)\r
++      // YYYY-MM    (size 7)\r
++      // YYYY       (size 4)\r
++      //      MM-DD (size 5)\r
++      //         DD (size 2)\r
++        // begin of time unit when 'early', end of when not\r
++      struct tm *timeinfo;\r
++      time_t timet;\r
++      //const char * startptr;\r
++      int year = 0, month = 0, day = 0;\r
++\r
++      if (str.size() == 2) {\r
++        // parse day, then remove it from the string\r
++        day = atoi(str.c_str());\r
++        str.erase(0,2);\r
++      }\r
++\r
++      if (str.size() == 4 or str.size() == 7 or str.size() == 10) {\r
++        // parse year, then remove it from the string\r
++        year = atoi(str.c_str());\r
++        str.erase(0,5);\r
++      }\r
++      \r
++      month = atoi(str.c_str());\r
++      str.erase(0,3);\r
++\r
++      // Do we have a day component left?\r
++      if (str.size())\r
++                 day = atoi(str.c_str());     \r
++\r
++      if (year == 0 && month == 0 && day == 0)\r
++        // no expected time format\r
++        return NULL ;\r
++\r
++      timet = time(NULL);\r
++      timeinfo = gmtime( &timet );\r
++      timeinfo -> tm_isdst = 0;\r
++      if (!early && !month) ++year; \r
++      if (year)  timeinfo -> tm_year = year - 1900;\r
++\r
++      if (month) timeinfo -> tm_mon = month - 1;\r
++      //else if (year) timeinfo -> tm_mon = (early ? 0: 12);\r
++\r
++      if (day) timeinfo -> tm_mday = (early ? day : ++day);\r
++      else timeinfo -> tm_mday = 1;\r
++\r
++      timeinfo -> tm_hour = 0;\r
++      timeinfo -> tm_min  = 0;\r
++      timeinfo -> tm_sec  = 0;\r
++      timet = mktime ( timeinfo );\r
++\r
++        if (!early) --timet;\r
++      if (timet == -1)\r
++        return NULL;\r
++      return timet;\r
++  }\r
++\r
++    Xapian::valueno operator()(std::string &begin, std::string &end) {\r
++      time_t begintime, endtime;\r
++\r
++      if (begin.substr(0, 5) != "date:")\r
++       return Xapian::BAD_VALUENO;\r
++      begin.erase(0, 5);\r
++\r
++      begintime = parsedate ( begin, true);\r
++      if (begintime == -1)\r
++      // no valid time format\r
++      return Xapian::BAD_VALUENO;\r
++\r
++      endtime = parsedate ( end, false);\r
++      if (endtime == -1)\r
++      // no valid time format\r
++      return Xapian::BAD_VALUENO;\r
++\r
++      begin.assign(Xapian::sortable_serialise(begintime));\r
++      end.assign(Xapian::sortable_serialise(endtime));\r
++\r
++      return NOTMUCH_VALUE_TIMESTAMP;\r
++    }\r
++};\r
++\r
+ notmuch_database_t *\r
+ notmuch_database_open (const char *path,\r
+                      notmuch_database_mode_t mode)\r
+@@ -570,7 +658,7 @@ notmuch_database_open (const char *path,\r
+       notmuch->query_parser = new Xapian::QueryParser;\r
+       notmuch->term_gen = new Xapian::TermGenerator;\r
+       notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));\r
+-      notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP, "date:", true);\r
++      notmuch->value_range_processor = new MaildateValueRangeProcessor();\r
\r
+       notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);\r
+       notmuch->query_parser->set_database (*notmuch->xapian_db);\r
+-- \r
+1.6.3.3\r
+\r