From a38d98d27880c8fc0f4d98646e318ecc1d39884f Mon Sep 17 00:00:00 2001 From: Frank Lichtenheld Date: Fri, 3 Mar 2006 03:24:32 +0000 Subject: [PATCH] Support multiple keywords --- cgi-bin/dispatcher.pl | 3 ++- lib/Packages/DoSearch.pm | 27 ++++++++++++------------ lib/Packages/Search.pm | 44 +++++++++++++++++++++++++++------------- 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/cgi-bin/dispatcher.pl b/cgi-bin/dispatcher.pl index 6235cc5..86bb489 100755 --- a/cgi-bin/dispatcher.pl +++ b/cgi-bin/dispatcher.pl @@ -167,7 +167,8 @@ if (my $path = $input->path_info() || $input->param('PATH_INFO')) { my ( $pkg, @suites, @sections, @subsections, @archives, @archs ); my %params_def = ( keywords => { default => undef, - match => '^\s*([-+\@\s\w\/.:]+)\s*$', + array => '\s+', + match => '^([-+\@\w\/.:]+)$', }, package => { default => undef, match => '^([\w.+-]+)$', diff --git a/lib/Packages/DoSearch.pm b/lib/Packages/DoSearch.pm index 35ee88f..1a5cf2e 100644 --- a/lib/Packages/DoSearch.pm +++ b/lib/Packages/DoSearch.pm @@ -34,15 +34,15 @@ sub do_search { $$menu = ""; - my $keyword = $opts->{keywords}; + my @keywords = @{$opts->{keywords}}; my $searchon = $opts->{searchon}; # for URL construction - my $keyword_esc = uri_escape( $keyword ); + my $keyword_esc = uri_escape( "@keywords" ); $opts->{keywords_esc} = $keyword_esc; # for output - my $keyword_enc = encode_entities $keyword || ''; + my $keyword_enc = encode_entities "@keywords" || ''; my $searchon_enc = encode_entities $searchon; my $suites_enc = encode_entities( join( ', ', @{$params->{values}{suite}{no_replace}} ) ); my $sections_enc = encode_entities( join( ', ', @{$params->{values}{section}{no_replace}} ) ); @@ -55,22 +55,19 @@ sub do_search { if ($searchon eq 'names') { if ($opts->{source}) { - do_names_search( $keyword, \%sources, $sp_obj, + do_names_search( \@keywords, \%sources, $sp_obj, \&read_src_entry_all, $opts, \@results, \@non_results ); } else { - do_names_search( $keyword, \%packages, $p_obj, + do_names_search( \@keywords, \%packages, $p_obj, \&read_entry_all, $opts, \@results, \@non_results ); } -# } elsif ($searchon eq 'contents') { -# require "./search_contents.pl"; -# &contents($input); } else { - do_names_search( $keyword, \%packages, $p_obj, + do_names_search( \@keywords, \%packages, $p_obj, \&read_entry_all, $opts, \@results, \@non_results ); - do_fulltext_search( $keyword, "$DBDIR/descriptions.txt", + do_fulltext_search( \@keywords, "$DBDIR/descriptions.txt", \%did2pkg, \%packages, \&read_entry_all, $opts, \@results, \@non_results ); @@ -179,7 +176,7 @@ sub do_search { my %uniq_pkgs = map { $_ => 1 } (keys %pkgs, keys %provided_by); my @pkgs = sort keys %uniq_pkgs; - $$page_content .= print_packages( \%pkgs, \@pkgs, $opts, $keyword, + $$page_content .= print_packages( \%pkgs, \@pkgs, $opts, \@keywords, \&print_package, \%provided_by, \%archives, \%sect, \%subsect, \%desc ); @@ -210,7 +207,7 @@ sub do_search { } my @pkgs = sort keys %pkgs; - $$page_content .= print_packages( \%pkgs, \@pkgs, $opts, $keyword, + $$page_content .= print_packages( \%pkgs, \@pkgs, $opts, \@keywords, \&print_src_package, \%archives, \%sect, \%subsect, \%binaries ); } # else unless $opts->{source} @@ -218,16 +215,18 @@ sub do_search { } # sub do_search sub print_packages { - my ($pkgs, $pkgs_list, $opts, $keyword, $print_func, @func_args) = @_; + my ($pkgs, $pkgs_list, $opts, $keywords, $print_func, @func_args) = @_; #my ($start, $end) = multipageheader( $input, scalar @pkgs, \%opts ); my $str = '
'; $str .= "

".sprintf( _g( "Found %s matching packages." ), scalar @$pkgs_list )."

"; #my $count = 0; + my $keyword; + $keyword = $keywords->[0] if @$keywords == 1; my $have_exact; - if (grep { $_ eq $keyword } @$pkgs_list) { + if ($keyword && grep { $_ eq $keyword } @$pkgs_list) { $have_exact = 1; $str .= '

'._g( "Exact hits" ).'

'; $str .= &$print_func( $keyword, $pkgs->{$keyword}||{}, diff --git a/lib/Packages/Search.pm b/lib/Packages/Search.pm index 0bc157d..c6a521a 100644 --- a/lib/Packages/Search.pm +++ b/lib/Packages/Search.pm @@ -154,23 +154,29 @@ sub read_src_entry { read_src_entry_all( $hash, $key, $results, \@non_results, $opts ); } sub do_names_search { - my ($keyword, $packages, $postfixes, $read_entry, $opts, + my ($keywords, $packages, $postfixes, $read_entry, $opts, $results, $non_results) = @_; - $keyword = lc $keyword; + my $first_keyword = lc shift @$keywords; + @$keywords = map { lc $_ } @$keywords; - my ($key, $prefixes) = ($keyword, ''); + my ($key, $prefixes) = ($first_keyword, ''); my %pkgs; $postfixes->seq( $key, $prefixes, R_CURSOR ); - while (index($key, $keyword) >= 0) { + while (index($key, $first_keyword) >= 0) { if ($prefixes =~ /^\001(\d+)/o) { debug( "$key has too many hits", 2 ) if DEBUG; $too_many_hits += $1; } else { + PREFIX: foreach (split /\000/o, $prefixes) { $_ = '' if $_ eq '^'; - debug( "add word $_$key", 2) if DEBUG; - $pkgs{$_.$key}++; + my $word = "$_$key"; + foreach my $k (@$keywords) { + next PREFIX unless $word =~ /\Q$k\E/; + } + debug( "add word $word", 2) if DEBUG; + $pkgs{$word}++; } } last if $postfixes->seq( $key, $prefixes, R_NEXT ) != 0; @@ -180,30 +186,40 @@ sub do_names_search { my $no_results = keys %pkgs; if ($too_many_hits || ($no_results >= 100)) { $too_many_hits += $no_results; - %pkgs = ( $keyword => 1 ); + %pkgs = ( $first_keyword => 1 ) unless @$keywords; } foreach my $pkg (sort keys %pkgs) { &$read_entry( $packages, $pkg, $results, $non_results, $opts ); } } sub do_fulltext_search { - my ($keyword, $file, $did2pkg, $packages, $read_entry, $opts, + my ($keywords, $file, $did2pkg, $packages, $read_entry, $opts, $results, $non_results) = @_; # NOTE: this needs to correspond with parse-packages! - $keyword =~ tr [A-Z] [a-z]; - if ($opts->{exact}) { - $keyword = " $keyword "; + my @tmp; + foreach my $keyword (@$keywords) { + $keyword =~ tr [A-Z] [a-z]; + if ($opts->{exact}) { + $keyword = " $keyword "; + } + $keyword =~ s/[(),.-]+//og; + $keyword =~ s;[^a-z0-9_/+]+; ;og; + push @tmp, $keyword; } - $keyword =~ s/[(),.-]+//og; - $keyword =~ s#[^a-z0-9_/+]+# #og; + my $first_keyword = shift @tmp; + @$keywords = @tmp; my $numres = 0; my %tmp_results; # fgrep is seriously faster than using perl - open DESC, '-|', 'fgrep', '-n', '--', $keyword, $file + open DESC, '-|', 'fgrep', '-n', '--', $first_keyword, $file or die "couldn't open $file: $!"; + LINE: while () { + foreach my $k (@$keywords) { + next LINE unless /\Q$k\E/; + } /^(\d+)/; my $nr = $1; debug( "Matched line $_", 2) if DEBUG; -- 2.39.2