Re: notmuch-search-toggle-order and notmuch-tree
[notmuch-archives.git] / fb / b50ab0668462c0c48c34f5a83ca61cb555cea1
1 Return-Path: <Sebastian@SSpaeth.de>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5         by olra.theworths.org (Postfix) with ESMTP id 02209431FBC\r
6         for <notmuch@notmuchmail.org>; Sun, 24 Jan 2010 06:14:05 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -1.285\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-1.285 tagged_above=-999 required=5 tests=[AWL=1.314,\r
12         BAYES_00=-2.599] autolearn=ham\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id x+uuuMQxkli2 for <notmuch@notmuchmail.org>;\r
16         Sun, 24 Jan 2010 06:14:04 -0800 (PST)\r
17 Received: from homiemail-a21.g.dreamhost.com (caiajhbdcbbj.dreamhost.com\r
18         [208.97.132.119])\r
19         by olra.theworths.org (Postfix) with ESMTP id 20F96431FAE\r
20         for <notmuch@notmuchmail.org>; Sun, 24 Jan 2010 06:14:04 -0800 (PST)\r
21 Received: from localhost.localdomain (unknown [84.55.198.58])\r
22         by homiemail-a21.g.dreamhost.com (Postfix) with ESMTPA id 5B1FD300059; \r
23         Sun, 24 Jan 2010 06:14:02 -0800 (PST)\r
24 From: Sebastian Spaeth <Sebastian@SSpaeth.de>\r
25 To: notmuch@notmuchmail.org\r
26 Date: Sun, 24 Jan 2010 15:13:53 +0100\r
27 Message-Id: <1264342433-15663-1-git-send-email-Sebastian@SSpaeth.de>\r
28 X-Mailer: git-send-email 1.6.3.3\r
29 In-Reply-To: <1264173971-11879-1-git-send-email-Sebastian@SSpaeth.de>\r
30 References: <1264173971-11879-1-git-send-email-Sebastian@SSpaeth.de>\r
31 Subject: [notmuch] [PATCH] Make the date parser nicer\r
32 X-BeenThere: notmuch@notmuchmail.org\r
33 X-Mailman-Version: 2.1.13\r
34 Precedence: list\r
35 List-Id: "Use and development of the notmuch mail system."\r
36         <notmuch.notmuchmail.org>\r
37 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
38         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
39 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
40 List-Post: <mailto:notmuch@notmuchmail.org>\r
41 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
42 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
43         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
44 X-List-Received-Date: Sun, 24 Jan 2010 14:14:05 -0000\r
45 \r
46 Currently we have to enter mail dates as timestamps. This approach does 2 things: 1) it requires the prefix 'date:'\r
47 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
48 The code is probably not in a proper location yet and needs to be shoved around by someone more knowledgable than me.\r
49 My C++ skills are somewhat,... lacking...\r
50 \r
51 Possible time formats: YYYY-MM-DD,YYYY-MM (in that month) , YYYY (in that year)\r
52 MM-DD (month-day in current year), DD (day in current month)\r
53 \r
54 Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>\r
55 ---\r
56  lib/database.cc |   90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-\r
57  1 files changed, 89 insertions(+), 1 deletions(-)\r
58 \r
59 diff --git a/lib/database.cc b/lib/database.cc\r
60 index 5b12320..9c2842d 100644\r
61 --- a/lib/database.cc\r
62 +++ b/lib/database.cc\r
63 @@ -494,6 +494,94 @@ _notmuch_database_ensure_writable (notmuch_database_t *notmuch)\r
64      return NOTMUCH_STATUS_SUCCESS;\r
65  }\r
66  \r
67 +struct MaildateValueRangeProcessor : public Xapian::ValueRangeProcessor {\r
68 +    MaildateValueRangeProcessor() {}\r
69 +\r
70 +  time_t\r
71 +  parsedate(std::string &str, bool early) {\r
72 +       // Parse the begin date to time_t\r
73 +       // possible time formats:\r
74 +       // YYYY-MM-DD (size 10)\r
75 +       // YYYY-MM    (size 7)\r
76 +       // YYYY       (size 4)\r
77 +       //      MM-DD (size 5)\r
78 +       //         DD (size 2)\r
79 +        // begin of time unit when 'early', end of when not\r
80 +       struct tm *timeinfo;\r
81 +       time_t timet;\r
82 +       //const char * startptr;\r
83 +       int year = 0, month = 0, day = 0;\r
84 +\r
85 +       if (str.size() == 2) {\r
86 +         // parse day, then remove it from the string\r
87 +         day = atoi(str.c_str());\r
88 +         str.erase(0,2);\r
89 +       }\r
90 +\r
91 +       if (str.size() == 4 or str.size() == 7 or str.size() == 10) {\r
92 +         // parse year, then remove it from the string\r
93 +         year = atoi(str.c_str());\r
94 +         str.erase(0,5);\r
95 +       }\r
96 +       \r
97 +       month = atoi(str.c_str());\r
98 +       str.erase(0,3);\r
99 +\r
100 +       // Do we have a day component left?\r
101 +       if (str.size())\r
102 +                  day = atoi(str.c_str());     \r
103 +\r
104 +       if (year == 0 && month == 0 && day == 0)\r
105 +         // no expected time format\r
106 +         return NULL ;\r
107 +\r
108 +       timet = time(NULL);\r
109 +       timeinfo = gmtime( &timet );\r
110 +       timeinfo -> tm_isdst = 0;\r
111 +       if (!early && !month) ++year; \r
112 +       if (year)  timeinfo -> tm_year = year - 1900;\r
113 +\r
114 +       if (month) timeinfo -> tm_mon = month - 1;\r
115 +       //else if (year) timeinfo -> tm_mon = (early ? 0: 12);\r
116 +\r
117 +       if (day) timeinfo -> tm_mday = (early ? day : ++day);\r
118 +       else timeinfo -> tm_mday = 1;\r
119 +\r
120 +       timeinfo -> tm_hour = 0;\r
121 +       timeinfo -> tm_min  = 0;\r
122 +       timeinfo -> tm_sec  = 0;\r
123 +       timet = mktime ( timeinfo );\r
124 +\r
125 +        if (!early) --timet;\r
126 +       if (timet == -1)\r
127 +         return NULL;\r
128 +       return timet;\r
129 +  }\r
130 +\r
131 +    Xapian::valueno operator()(std::string &begin, std::string &end) {\r
132 +      time_t begintime, endtime;\r
133 +\r
134 +      if (begin.substr(0, 5) != "date:")\r
135 +        return Xapian::BAD_VALUENO;\r
136 +      begin.erase(0, 5);\r
137 +\r
138 +      begintime = parsedate ( begin, true);\r
139 +      if (begintime == -1)\r
140 +       // no valid time format\r
141 +       return Xapian::BAD_VALUENO;\r
142 +\r
143 +      endtime = parsedate ( end, false);\r
144 +      if (endtime == -1)\r
145 +       // no valid time format\r
146 +       return Xapian::BAD_VALUENO;\r
147 +\r
148 +      begin.assign(Xapian::sortable_serialise(begintime));\r
149 +      end.assign(Xapian::sortable_serialise(endtime));\r
150 +\r
151 +      return NOTMUCH_VALUE_TIMESTAMP;\r
152 +    }\r
153 +};\r
154 +\r
155  notmuch_database_t *\r
156  notmuch_database_open (const char *path,\r
157                        notmuch_database_mode_t mode)\r
158 @@ -570,7 +658,7 @@ notmuch_database_open (const char *path,\r
159         notmuch->query_parser = new Xapian::QueryParser;\r
160         notmuch->term_gen = new Xapian::TermGenerator;\r
161         notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));\r
162 -       notmuch->value_range_processor = new Xapian::NumberValueRangeProcessor (NOTMUCH_VALUE_TIMESTAMP, "date:", true);\r
163 +       notmuch->value_range_processor = new MaildateValueRangeProcessor();\r
164  \r
165         notmuch->query_parser->set_default_op (Xapian::Query::OP_AND);\r
166         notmuch->query_parser->set_database (*notmuch->xapian_db);\r
167 -- \r
168 1.6.3.3\r
169 \r