newbie questions

Jesse Rosenthal jrosenthal at jhu.edu
Mon Feb 6 10:29:05 PST 2012


On Mon, 06 Feb 2012 08:51:15 +0200, Tomi Ollila <tomi.ollila at iki.fi> wrote:
> On Fri, 3 Feb 2012 12:59:34 +0100, Tamas Papp <tkpapp at gmail.com> wrote:
> > 
> > 1. How can I restrict searches (eg of my inbox) to the last few
> > messages (eg 50-100) or some date (eg last 2 weeks)?  I am using the
> > Emacs interface.
> 
> Currently, if you have GNU date you can run from command line:
> 
> date +%s.. --date '2 weeks ago'
> 
> Then paste the string 1327300096.. to the search field.

FWIW, I actually have a hacky date parser baked into my
remote-usage-and-other-stuff script (a more idiosyncratc python
version of the bash script on the wiki). I found that I needed
date-searching pretty frequently, since language and senders seem to be
repeated pretty often in my world. It just parses a "date:" term, passes
it to GNU date, and proceeds with a term in notmuch language. It also
does some day-rounding, since by "date:'2 days ago'..yesterday", I mean
"beginning of day before yesterday to end of yesterday," not "48 hours
ago until 24 hours ago."

I'm not swearing by its efficiency, or even its correctness, but it has
made my life easier. The basics are as follows:

    DATE_PATTERN = re.compile(r'^date:([^.]+)(\.\.)?([^.]+)?')
    
    def replace_date_args(st):
        out = subprocess.check_output([GNU_DATE, "+%s", "-d", st])
        return out.strip()
    
    def round_day_down(timestamp):
        tup = datetime.fromtimestamp(int(timestamp)).date().timetuple()
        return time.mktime(tup)
    
    def round_day_up(timestamp):
        date = datetime.fromtimestamp(int(timestamp)).date()
        date += timedelta(days=1)
        tup = date.timetuple()
        return time.mktime(tup)
    
    def parse_date_args(st):
        re_match = DATE_PATTERN.match(st)
        if re_match:
            grps = re_match.groups()
            start_term = grps[0]
            if not (grps[1] or grps[2]):
                stop_term = start_term
            elif not grps[2]:
                stop_term = "now"
            else:
                stop_term = grps[2]
    
            try:
                start = round_day_down(replace_date_args(start_term))
                stop = round_day_up(replace_date_args(stop_term))
                return "%d..%d" % (start, stop)
            except OSError:
                return st
        else:
            return st

And then in the main routine, I have a parse-and-replace step:

    args = sys.argv[1:]
    try:
        if args[-1] == ")'":
            args = args[:-2] + shlex.split(sys.argv[-2]) + [")'"]
        else:
            args = args[:-1] + shlex.split(sys.argv[-1])
    except IndexError, ValueError:
        pass

    args = [parse_date_args(a) for a in args] 

I'm only giving the relevant parts here, of course.

Best,
Jesse
    



More information about the notmuch mailing list