diff options
author | Eric Wong <e@80x24.org> | 2021-02-10 18:57:58 -0100 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2021-02-11 19:15:05 +0000 |
commit | b503d87a23c90fc0f705a79bce34944e7e20b28b (patch) | |
tree | 73077711675b7b844a031acd2537a585addfac50 /lib/PublicInbox/Search.pm | |
parent | f310a5054fb8e215885f0b48afac44ff32ca1d56 (diff) | |
download | public-inbox-b503d87a23c90fc0f705a79bce34944e7e20b28b.tar.gz |
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.
Diffstat (limited to 'lib/PublicInbox/Search.pm')
-rw-r--r-- | lib/PublicInbox/Search.pm | 35 |
1 files changed, 27 insertions, 8 deletions
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) = @_; |