diff --git a/TODO b/TODO index d3406e01..b41eceff 100644 --- a/TODO +++ b/TODO @@ -11,15 +11,15 @@ - [ ] completion for zsh - [ ] don't make test mail files executable -** release 0.9 [86%] +** release 0.9 [100%] - [X] bookmarks - [X] gtk-ui for searching - [X] clean up mu-msg-field, add formatting(?) - [X] normalize search fields - - [ ] cleanup version check + - [X] cleanup version check - [X] propagate errors to ui - [X] update mug for Gerrors feedback - - [ ] improve date ranges + - [X] improve date ranges - [X] improve spacing in mug - [X] fix flag searches + synonyms - [X] unbreak cc10/line33 diff --git a/src/mu-query.cc b/src/mu-query.cc index 242dbc79..4e42b406 100644 --- a/src/mu-query.cc +++ b/src/mu-query.cc @@ -50,8 +50,8 @@ public: if (!clear_prefix (begin)) return Xapian::BAD_VALUENO; - substitute_date (begin, true); - substitute_date (end, false); + substitute_date (begin); + substitute_date (end); normalize_date (begin); normalize_date (end); @@ -65,7 +65,8 @@ private: bool clear_prefix (std::string& begin) { const std::string colon (":"); - const std::string name (mu_msg_field_name (MU_MSG_FIELD_ID_DATE) + colon); + const std::string name (mu_msg_field_name + (MU_MSG_FIELD_ID_DATE) + colon); const std::string shortcut ( std::string(1, mu_msg_field_shortcut (MU_MSG_FIELD_ID_DATE)) + colon); @@ -80,23 +81,27 @@ private: return false; } - void substitute_date (std::string& date, bool is_begin) { + void substitute_date (std::string& date) { char datebuf[13]; time_t now = time(NULL); - if (is_begin) { - if (date == "today") { - strftime(datebuf, sizeof(datebuf), "%Y%m%d0000", - localtime(&now)); - date = datebuf; - } else if (date == "epoch") - date = "197001010000"; - } else { /* end */ - if (date == "now") { + + if (date == "today") { + strftime(datebuf, sizeof(datebuf), "%Y%m%d0000", + localtime(&now)); + date = datebuf; + } else if (date == "now") { + strftime(datebuf, sizeof(datebuf), "%Y%m%d%H%M", + localtime(&now)); + date = datebuf; + } else { + time_t t; + t = mu_date_parse_hdwmy (date.c_str()); + if (t != (time_t)-1) { strftime(datebuf, sizeof(datebuf), "%Y%m%d%H%M", - localtime(&now)); + localtime(&t)); date = datebuf; } - } + } } void normalize_date (std::string& date) { @@ -118,10 +123,11 @@ private: const std::string esuffix ("99991231235959"); if (is_begin) - date = std::string (date + bsuffix.substr (date.length()), len); + date = std::string (date + bsuffix.substr (date.length())); else - date = std::string (date + esuffix.substr (date.length()), len); + date = std::string (date + esuffix.substr (date.length())); + date = date.substr (0, len); } }; diff --git a/src/mu-str.c b/src/mu-str.c index 0411cf34..fd134af4 100644 --- a/src/mu-str.c +++ b/src/mu-str.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "mu-str.h" #include "mu-msg-flags.h" @@ -189,3 +190,39 @@ mu_str_display_contact (const char *str) +time_t +mu_date_parse_hdwmy (const char* str) +{ + long int num; + char *end; + time_t now, delta; + time_t never = (time_t)-1; + + g_return_val_if_fail (str, never); + + num = strtol (str, &end, 10); + if (num <= 0 || num > 9999) + return never; + + if (!end || end[1] != '\0') + return never; + + switch (end[0]) { + case 'h': /* hour */ + delta = num * 24 * 60; break; + case 'd': /* day */ + delta = num * 24 * 60 * 60; break; + case 'w': /* week */ + delta = num * 7 * 24 * 60 * 60; break; + case 'm': + delta = num * 30 * 24 * 60 * 60; break; + case 'y': + delta = num * 365 * 24 * 60 * 60; break; + default: + return never; + } + + now = time(NULL); + return delta <= now ? now - delta : never; +} + diff --git a/src/mu-str.h b/src/mu-str.h index 78a1d7ba..e1a0c32f 100644 --- a/src/mu-str.h +++ b/src/mu-str.h @@ -157,6 +157,26 @@ char* mu_str_normalize (const char *str, gboolean downcase); */ char* mu_str_normalize_in_place (char *str, gboolean downcase); + +/** + * + * parse strings like 1h, 3w, 2m to mean '1 hour before now', '3 weeks + * before now' and '2 * 30 days before now' + * + * the format is (h|d|w|m|y), where is an integer > 0, and + * h=hour, d=day, w=week, m=30 days, year=365 days. function returns + * *now* minus this value as time_t (UTC) + * + * if the number cannot be parsed, return (time_t)-1 + * + * @param str a str + * + * @return the time_t of the point in time indicated by 'now' minus + * the value, or (time_t)-1 otherwise + */ +time_t mu_date_parse_hdwmy (const char* str); + + G_END_DECLS #endif /*__MU_STR_H__*/