]> git.deb.at Git - deb/packages.git/blobdiff - lib/Packages/DoSearchContents.pm
We welcome DoSearchContents.pm to the "multiple keywords" age
[deb/packages.git] / lib / Packages / DoSearchContents.pm
index 3079f92de025aedd126746745b47f8fe6a1a40a2..b8698cc3b592830a0add06d4e3284ba5ba4c67a2 100644 (file)
@@ -24,7 +24,7 @@ sub do_search_contents {
 
     if ($params->{errors}{keywords}) {
        fatal_error( _g( "keyword not valid or missing" ) );
-    } elsif (length($opts->{keywords}) < 2) {
+    } elsif (grep { length($_) < 2 } @{$opts->{keywords}}) {
        fatal_error( _g( "keyword too short (keywords need to have at least two characters)" ) );
     }
     if ($params->{errors}{suite}) {
@@ -43,22 +43,20 @@ sub do_search_contents {
 
     $$menu = "";
     
-    my $keyword = $opts->{keywords};
-    my $searchon = $opts->{searchon};
-    my $exact = $opts->{exact};
+    my @keywords = @{$opts->{keywords}};
+    my $mode = $opts->{mode} || '';
     my $suite = $opts->{suite}[0];
     my $archive = $opts->{archive}[0] ||'';
     $Packages::Search::too_many_hits = 0;
 
     # for URL construction
-    my $keyword_esc = uri_escape( $keyword );
+    my $keyword_esc = uri_escape( "@keywords" );
     my $suites_param = join ',', @{$params->{values}{suite}{no_replace}};
     my $sections_param = join ',', @{$params->{values}{section}{no_replace}};
     my $archs_param = join ',', @{$params->{values}{arch}{no_replace}};
 
     # for output
-    my $keyword_enc = encode_entities $keyword || '';
-    my $searchon_enc = encode_entities $searchon;
+    my $keyword_enc = encode_entities "@keywords" || '';
     my $suites_enc = encode_entities( join( ', ', @{$params->{values}{suite}{no_replace}} ), '&<>"' );
     my $sections_enc = encode_entities( join( ', ', @{$params->{values}{section}{no_replace}} ), '&<>"' );
     my $archs_enc = encode_entities( join( ', ',  @{$params->{values}{arch}{no_replace}} ), '&<>"' );
@@ -70,33 +68,37 @@ sub do_search_contents {
 
        my $nres = 0;
 
-       my $kw = lc $keyword;
+       my $first_kw = lc shift @keywords;
        # full filename search is tricky
-       my $ffn = $searchon eq 'filenames';
+       my $ffn = $mode eq 'filename';
 
        my $reverses = tie my %reverses, 'DB_File', "$DBDIR/contents/reverse_$suite.db",
            O_RDONLY, 0666, $DB_BTREE
            or die "Failed opening reverse DB: $!";
 
        if ($ffn) {
-           open FILENAMES, '-|', 'fgrep', '--', $kw, "$DBDIR/contents/filenames_$suite.txt"
+           open FILENAMES, '-|', 'fgrep', '--', $first_kw, "$DBDIR/contents/filenames_$suite.txt"
                or die "Failed opening filename table: $!";
 
-           error( _g( "Exact and fullfilenamesearch don't go along" ) )
-               if $ffn and $exact;
-
+         FILENAME:
            while (<FILENAMES>) {
                chomp;
+               foreach my $kw (@keywords) {
+                   next FILENAME unless /\Q$kw\E/;
+               }
                &searchfile(\@results, reverse($_)."/", \$nres, $reverses);
                last if $Packages::Search::too_many_hits;
            }
            close FILENAMES or warn "fgrep error: $!\n";
        } else {
 
-           $kw = reverse $kw;
+           error(_g("The search mode you selected doesn't support more than one keyword."))
+               if @keywords;
+
+           my $kw = reverse $first_kw;
            
            # exact filename searching follows trivially:
-           $kw = "$kw/" if $exact;
+           $kw = "$kw/" if $mode eq 'exactfilename';
 
            &searchfile(\@results, $kw, \$nres, $reverses);
        }
@@ -114,18 +116,29 @@ sub do_search_contents {
        : sprintf(_g("section(s) <em>%s</em>"), $sections_enc );
     my $arch_wording = $archs_enc eq 'any' ? _g("all architectures")
        : sprintf(_g("architecture(s) <em>%s</em>"), $archs_enc );
-    my $wording = _g("filenames that contain");
-    if ($searchon eq 'contents') {
-       if ($opts->{exact}) {
-           $wording =  _g("files named");
-       } else {
-           $wording = _g("paths that end with");
-       }
+    my $wording = _g("paths that end with");
+    if ($mode eq 'filename') {
+       $wording =  _g("files named");
+    } elsif ($mode eq 'exactfilename') {
+       $wording = _g("filenames that contain");
     }
     msg( sprintf( _g("You have searched for %s <em>%s</em> in %s, %s, and %s." ),
                  $wording, $keyword_enc,
                  $suite_wording, $section_wording, $arch_wording ) );
 
+    if ($mode ne 'filename') {
+       msg( '<a href="'.make_search_url('',"keywords=$keyword_esc",{mode=>'filename'}).
+             "\">"._g("Search within filenames")."</a>");
+    }
+    if ($mode ne 'exactfilename') {
+       msg( '<a href="'.make_search_url('',"keywords=$keyword_esc",{mode=>'exactfilename'}).
+             "\">"._g("Search exact filename")."</a>");
+    }
+    if ($mode eq 'exactfilename' || $mode eq 'filename') {
+       msg( '<a href="'.make_search_url('',"keywords=$keyword_esc",{mode=>undef}).
+             "\">"._g("Search for paths ending with")."</a>");
+    }
+
     msg( _g("Search in other suite:")." ".
         join( ' ', map { '[<a href="'.make_search_url('',"keywords=$keyword_esc",{suite=>$_}).
                              "\">$_</a>]" } @SUITES ) );
@@ -184,9 +197,14 @@ sub do_search_contents {
                                         scalar keys %results )."</p>";
        $$page_content .= '<div
        id="pcontentsres"><table><colgroup><col><col></colgroup><tr><th>'._g('File').'</th><th>'._g('Packages')
-           .'</th></tr>';
+           ."</th></tr>\n";
        foreach my $file (sort keys %results) {
-           $$page_content .= "<tr><td class=\"file\">/$file</td><td>";
+               my $file_enc = encode_entities($file);
+               foreach my $kw (@{$opts->{keywords}}) {
+                   my $kw_enc = encode_entities($kw);
+                   $file_enc =~ s#(\Q$kw_enc\E)#<span class="keyword">$1</span>#g;
+               }
+           $$page_content .= "<tr><td class=\"file\">/$file_enc</td><td>";
            my @pkgs;
            foreach my $pkg (sort keys %{$results{$file}}) {
                my $arch_str = '';
@@ -203,9 +221,9 @@ sub do_search_contents {
                push @pkgs, "<a href=\"".make_url($pkg,'',{suite=>$suite})."\">$pkg</a>$arch_str";
            }
            $$page_content .= join( ", ", @pkgs);
-           $$page_content .= '</td>';
+           $$page_content .= "</td></tr>\n";
        }
-       $$page_content .= '<tr><th>'._g('File').'</th><th>'._g('Packages').'</th></tr>' if @results > 20;
+       $$page_content .= '<tr><th>'._g('File').'</th><th>'._g('Packages')."</th></tr>\n" if @results > 20;
        $$page_content .= '</table></div>';
     }
 } # sub do_search_contents