From b503d87a23c90fc0f705a79bce34944e7e20b28b Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 10 Feb 2021 18:57:58 -0100 Subject: search: use git approxidate in WWW and "lei q --stdin" This greatly improves the usability of d:, dt:, and rt: search prefixes for users already familiar git's "approxidate" feature. That is, users familiar with the --(since|after|until|before)= options in git-log(1) and similar commands will be able to use those dates in the WWW UI. --- lib/PublicInbox/Search.pm | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) (limited to 'lib/PublicInbox/Search.pm') diff --git a/lib/PublicInbox/Search.pm b/lib/PublicInbox/Search.pm index b3fd532d..8e4cce33 100644 --- a/lib/PublicInbox/Search.pm +++ b/lib/PublicInbox/Search.pm @@ -321,6 +321,16 @@ sub date_parse_prepare { "$pfx:".join('..', @r).$end; } +sub date_parse_finalize { + my ($git, $to_parse) = @_; + # git-rev-parse can handle any number of args up to system + # limits (around (4096*32) bytes on Linux). + my @r = $git->date_parse(@$to_parse); + my $i; + $_[2] =~ s/\0(%[%YmdHMSs]+)([0-9\+]+)\0/strftime($1, + gmtime($2 eq '+' ? ($r[$i]+86400) : $r[$i=$2+0]))/sge; +} + # n.b. argv never has NUL, though we'll need to filter it out # if this $argv isn't from a command execution sub query_argv_to_string { @@ -336,17 +346,26 @@ sub query_argv_to_string { $_ } } @$argv); - # git-rev-parse can handle any number of args up to system - # limits (around (4096*32) bytes on Linux). - if ($to_parse) { - my @r = $git->date_parse(@$to_parse); - my $i; - $tmp =~ s/\0(%[%YmdHMSs]+)([0-9\+]+)\0/strftime($1, - gmtime($2 eq '+' ? ($r[$i]+86400) : $r[$i=$2+0]))/sge; - } + date_parse_finalize($git, $to_parse, $tmp) if $to_parse; $tmp } +# this is for the WWW "q=" query parameter and "lei q --stdin" +# it can't do d:"5 days ago", but it will do d:5.days.ago +sub query_approxidate { + my (undef, $git) = @_; # $_[2] = $query_string (modified in-place) + my $DQ = qq<"\x{201c}\x{201d}>; # Xapian can use curly quotes + $_[2] =~ tr/\x00/ /; # Xapian doesn't do NUL, we use it as a placeholder + my ($terms, $phrase, $to_parse); + $_[2] =~ s{([^$DQ]*)([${DQ}][^\"]*[$DQ])?}{ + ($terms, $phrase) = ($1, $2); + $terms =~ s!\b(d|rt|dt):(\S+)! + date_parse_prepare($to_parse //= [], $1, $2)!sge; + $terms.($phrase // ''); + }sge; + date_parse_finalize($git, $to_parse, $_[2]) if $to_parse; +} + # read-only sub mset { my ($self, $query_string, $opts) = @_; -- cgit v1.2.3-24-ge0c7