X-Git-Url: https://git.deb.at/?p=deb%2Fpackages.git;a=blobdiff_plain;f=cgi-bin%2Fsearch_packages.pl;h=9526bdd904fd903ac35c78381cebfe4d03cb11e1;hp=f54efbe213315c6af289d1378747300418b46692;hb=5df726a682c234f48e4569a7aeb27caf78b2de9a;hpb=d293eabeae6396dbf18640c6c25bb41c05e42349 diff --git a/cgi-bin/search_packages.pl b/cgi-bin/search_packages.pl index f54efbe..9526bdd 100755 --- a/cgi-bin/search_packages.pl +++ b/cgi-bin/search_packages.pl @@ -55,10 +55,10 @@ my $pet0 = new Benchmark; my $debug_allowed = 1; my $debug = $debug_allowed && $input->param("debug"); $debug = 0 if not defined($debug); -$Search::Param::debug = 1 if $debug > 1; +#$Packages::Search::debug = 1 if $debug > 1; # If you want, just print out a list of all of the variables and exit. -print $input->header if $debug; +#print $input->header if $debug; # print $input->dump; # exit; @@ -79,7 +79,7 @@ if (my $path = $input->param('path')) { } my ( $format, $keyword, $case, $subword, $exact, $searchon, - @suites, @sections, @archs ); + @suites, @sections, @archs ); my %params_def = ( keywords => { default => undef, match => '^\s*([-+\@\w\/.:]+)\s*$', @@ -124,13 +124,61 @@ if ($format eq 'html') { print $input->header( -type=>'text/plain' ); } +my (@errors, @debug, @msgs, @hints); +sub error { + push @errors, $_[0]; +} +sub hint { + push @hints, $_[0]; +} +sub debug { + my $lvl = $_[1] || 0; + push(@debug, $_[0]) if $debug > $lvl; +} +sub msg { + push @msgs, $_[0]; +} +sub print_errors { + return unless @errors; + print '
'; + foreach (@errors) { + print "

$_

"; + } + print '
'; +} +sub print_debug { + return unless $debug && @debug; + print '
'; + print '

Debugging:

';
+    foreach (@debug) {
+	print "$_\n";
+    }
+    print '
'; + +} +sub print_hints { + return unless @hints; + print '
'; + foreach (@hints) { + print "

$_

"; + } + print '
'; +} +sub print_msgs { + foreach (@msgs) { + print "

$_

"; + } +} + if ($params{errors}{keywords}) { - print "Error: keyword not valid or missing" if $format eq 'html'; - exit 0; + error( "Error: keyword not valid or missing" ); } my $case_bool = ( $case !~ /insensitive/ ); $exact = !$subword unless defined $exact; +$opts{h_suites} = { map { $_ => 1 } @suites }; +$opts{h_sections} = { map { $_ => 1 } @sections }; +$opts{h_archs} = { map { $_ => 1 } @archs }; # for URL construction my $suites_param = join ',', @{$params{values}{suite}{no_replace}}; @@ -145,36 +193,16 @@ my $sections_enc = encode_entities join ', ', @{$params{values}{section}{no_repl my $archs_enc = encode_entities join ', ', @{$params{values}{arch}{no_replace}}; my $pet1 = new Benchmark; my $petd = timediff($pet1, $pet0); -print "DEBUG: Parameter evaluation took ".timestr($petd)."
" if $debug; - -if ($format eq 'html') { -print Packages::HTML::header( title => 'Package Search Results' , - lang => 'en', - title_tag => 'Debian Package Search Results', - print_title_above => 1, - print_search_field => 'packages', - search_field_values => { - keywords => $keyword_enc, - searchon => $searchon, - arch => $archs_enc, - suite => $suites_enc, - section => $sections_enc, - subword => $subword, - exact => $exact, - case => $case, - }, - ); -} +debug( "Parameter evaluation took ".timestr($petd) ); # read the configuration my $topdir; if (!open (C, "../config.sh")) { - print "\nInternal Error: Cannot open configuration file.\n\n" -if $format eq 'html'; - exit 0; + error( "Internal Error: Cannot open configuration file." ); } while () { - $topdir = $1 if (/^\s*topdir="?(.*)"?\s*$/); + $topdir = $1 if /^\s*topdir="?(.*)"?\s*$/; + $ROOT = $1 if /^\s*root="?(.*)"?\s*$/; } close (C); @@ -188,35 +216,47 @@ if ($searchon eq 'sourcenames') { $search_on_sources = 1; } -my %suites = map { $_ => 1 } @suites; -my %sections = map { $_ => 1 } @sections; -my %archs = map { $_ => 1 } @archs; - -print "DEBUG: suites=@suites, sections=@sections, archs=@archs
" - if $debug > 2; +sub print_header { + print Packages::HTML::header( title => 'Package Search Results' , + lang => 'en', + title_tag => 'Debian Package Search Results', + print_title_above => 1, + print_search_field => 'packages', + search_field_values => { + keywords => $keyword_enc, + searchon => $searchon, + arch => $archs_enc, + suite => $suites_enc, + section => $sections_enc, + subword => $subword, + exact => $exact, + case => $case, + }, + ); +} sub read_entry { - my ($hash, $key, $results) = @_; - my $result = $hash->{$key}; + my ($hash, $key, $results, $opts) = @_; + my $result = $hash->{$key} || ''; foreach (split /\000/, $result) { my @data = split ( /\s/, $_, 7 ); - print "DEBUG: Considering entry ".join( ':', @data)."
" if $debug > 2; - if ($suites{$data[0]} && ($archs{$data[1]} || $data[1] eq 'all') - && $sections{$data[2]}) { - print "DEBUG: Using entry ".join( ':', @data)."
" if $debug > 2; + debug( "Considering entry ".join( ':', @data), 2); + if ($opts->{h_suites}{$data[0]} + && ($opts->{h_archs}{$data[1]} || $data[1] eq 'all') + && $opts->{h_sections}{$data[2]}) { + debug( "Using entry ".join( ':', @data), 2); push @$results, [ $key, @data ]; } } } sub read_src_entry { - my ($hash, $key, $results) = @_; - my $result = $hash->{$key}; - + my ($hash, $key, $results, $opts) = @_; + my $result = $hash->{$key} || ''; foreach (split /\000/, $result) { my @data = split ( /\s/, $_, 5 ); - print "DEBUG: Considering entry ".join( ':', @data)."
" if $debug > 2; - if ($suites{$data[0]} && $sections{$data[1]}) { - print "DEBUG: Using entry ".join( ':', @data)."
" if $debug > 2; + debug( "Considering entry ".join( ':', @data), 2); + if ($opts->{h_suites}{$data[0]} && $opts->{h_sections}{$data[1]}) { + debug( "Using entry ".join( ':', @data), 2); push @$results, [ $key, @data ]; } } @@ -231,7 +271,7 @@ sub do_names_search { or die "couldn't tie DB $DBDIR/$file: $!"; if ($opts->{exact}) { - &$read_entry( \%packages, $keyword, \@results ); + &$read_entry( \%packages, $keyword, \@results, $opts ); } else { my ($key, $prefixes) = ($keyword, ''); my %pkgs; @@ -244,7 +284,7 @@ sub do_names_search { } else { foreach (split /\000/o, $prefixes) { $_ = '' if $_ eq '^'; - print "DEBUG: add word $_$key
" if $debug > 2; + debug( "add word $_$key", 2); $pkgs{$_.$key}++; } } @@ -258,7 +298,7 @@ sub do_names_search { %pkgs = ( $keyword => 1 ); } foreach my $pkg (sort keys %pkgs) { - &$read_entry( \%packages, $pkg, \@results ); + &$read_entry( \%packages, $pkg, \@results, $opts ); } } return \@results; @@ -276,7 +316,7 @@ sub do_fulltext_search { $regex = qr/\Q$keyword\E/o; } } else { - if ($exact) { + if ($opts->{exact}) { $regex = qr/\b\Q$keyword\E\b/io; } else { $regex = qr/\Q$keyword\E/io; @@ -287,7 +327,7 @@ sub do_fulltext_search { or die "couldn't open $DBDIR/$file: $!"; while () { $_ =~ $regex or next; - print "DEBUG: Matched line $.
" if $debug > 2; + debug( "Matched line $.", 2); push @lines, $.; } close DESC; @@ -302,16 +342,35 @@ sub do_fulltext_search { my $result = $did2pkg{$l}; foreach (split /\000/o, $result) { my @data = split /\s/, $_, 3; - next unless $archs{$data[2]}; + next unless $opts->{h_archs}{$data[2]}; $tmp_results{$data[0]}++; } } foreach my $pkg (keys %tmp_results) { - &$read_entry( \%packages, $pkg, \@results ); + &$read_entry( \%packages, $pkg, \@results, $opts ); } return \@results; } +sub find_binaries { + my ($pkg, $suite) = @_; + + tie my %src2bin, 'DB_File', "$DBDIR/sources_packages.db", O_RDONLY, 0666, $DB_BTREE + or die "couldn't open $DBDIR/sources_packages.db: $!"; + + my $bins = $src2bin{$pkg} || ''; + my %bins; + foreach (split /\000/o, $bins) { + my @data = split /\s/, $_, 4; + + if ($data[0] eq $suite) { + $bins{$data[1]}++; + } + } + + return [ keys %bins ]; +} + if ($searchon eq 'names') { push @results, @{ do_names_search( $keyword, 'packages_small.db', 'package_postfixes.db', @@ -332,7 +391,7 @@ if ($searchon eq 'names') { my $st1 = new Benchmark; my $std = timediff($st1, $st0); -print "DEBUG: Search took ".timestr($std)."
" if $debug; +debug( "Search took ".timestr($std) ); if ($format eq 'html') { my $suite_wording = $suites_enc eq "all" ? "all suites" @@ -344,15 +403,15 @@ if ($format eq 'html') { if (($searchon eq "names") || ($searchon eq 'sourcenames')) { my $source_wording = $search_on_sources ? "source " : ""; my $exact_wording = $exact ? "named" : "that names contain"; - print "

You have searched for ${source_wording}packages $exact_wording $keyword_enc in $suite_wording, $section_wording, and $arch_wording.

"; + msg( "You have searched for ${source_wording}packages $exact_wording $keyword_enc in $suite_wording, $section_wording, and $arch_wording." ); } else { my $exact_wording = $exact ? "" : " (including subword matching)"; - print "

You have searched for $keyword_enc in packages names and descriptions in $suite_wording, $section_wording, and $arch_wording$exact_wording.

"; + msg( "You have searched for $keyword_enc in packages names and descriptions in $suite_wording, $section_wording, and $arch_wording$exact_wording." ); } } if ($too_many_hits) { -print "

Your search was too wide so we will only display exact matches. At least $too_many_hits results have been omitted and will not be displayed. Please consider using a longer keyword or more keywords.

"; + error( "Your search was too wide so we will only display exact matches. At least $too_many_hits results have been omitted and will not be displayed. Please consider using a longer keyword or more keywords." ); } if (!@results) { @@ -363,38 +422,39 @@ if (!@results) { if (($suites_enc eq 'all') && ($archs_enc eq 'any') && ($sections_enc eq 'all')) { - print "

Can't find that package.

\n"; + error( "Can't find that package." ); } else { - print "

Can't find that package, at least not in that suite ". - ( $search_on_sources ? "" : " and on that architecture" ). - ".

\n"; + error( "Can't find that package, at least not in that suite ". + ( $search_on_sources ? "" : " and on that architecture" ) ) } if ($exact) { - $printed = 1; - print "

You have searched only for exact matches of the package name. You can try to search for package names that contain your search string.

"; + hint( "You have searched only for exact matches of the package name. You can try to search for package names that contain your search string." ); } } else { if (($suites_enc eq 'all') && ($archs_enc eq 'any') && ($sections_enc eq 'all')) { - print "

Can't find that string.

\n"; + error( "Can't find that string." ); } else { - print "

Can't find that string, at least not in that suite ($suites_enc, section $sections_enc) and on that architecture ($archs_enc).

\n"; + error( "Can't find that string, at least not in that suite ($suites_enc, section $sections_enc) and on that architecture ($archs_enc)." ); } unless ($subword) { - $printed = 1; - print "

You have searched only for words exactly matching your keywords. You can try to search allowing subword matching.

"; + hint( "You have searched only for words exactly matching your keywords. You can try to search allowing subword matching." ); } } - print "

".( $printed ? "Or you" : "You" )." can try a different search on the Packages search page.

"; - - &printfooter; + hint( ( @hints ? "Or you" : "You" )." can try a different search on the Packages search page." ); + } - exit; } +print_header; +print_msgs; +print_errors; +print_hints; +print_debug; + my (%pkgs, %sect, %part, %desc, %binaries); unless ($search_on_sources) { @@ -408,7 +468,6 @@ unless ($search_on_sources) { $part{$package}{$suite}{$version} = $section unless $section eq 'main'; $desc{$package}{$suite}{$version} = $desc; - } if ($format eq 'html') { @@ -439,43 +498,17 @@ unless ($search_on_sources) { } print "\n"; } - } elsif ($format eq 'xml') { - require RDF::Simple::Serialiser; - my $rdf = new RDF::Simple::Serialiser; - $rdf->addns( debpkg => 'http://packages.debian.org/xml/01-debian-packages-rdf' ); - my @triples; - foreach my $pkg (sort keys %pkgs) { - foreach my $ver (@SUITES) { - if (exists $pkgs{$pkg}{$ver}) { - my @versions = version_sort keys %{$pkgs{$pkg}{$ver}}; - foreach my $version (@versions) { - my $id = "$ROOT/$ver/$sect{$pkg}{$ver}{$version}/$pkg/$version"; - push @triples, [ $id, 'debpkg:package', $pkg ]; - push @triples, [ $id, 'debpkg:version', $version ]; - push @triples, [ $id, 'debpkg:section', $sect{$pkg}{$ver}{$version}, ]; - push @triples, [ $id, 'debpkg:suite', $ver ]; - push @triples, [ $id, 'debpkg:shortdesc', $desc{$pkg}{$ver}{$version} ]; - push @triples, [ $id, 'debpkg:part', $part{$pkg}{$ver}{$version} || 'main' ]; - foreach my $arch (sort keys %{$pkgs{$pkg}{$ver}{$version}}) { - push @triples, [ $id, 'debpkg:architecture', $arch ]; - } - } - } - } - } - - print $rdf->serialise(@triples); } } else { foreach (@results) { my ($package, $suite, $section, $subsection, $priority, - $version, $binaries) = @$_; + $version) = @$_; $pkgs{$package}{$suite} = $version; $sect{$package}{$suite}{source} = $subsection; $part{$package}{$suite}{source} = $section unless $section eq 'main'; - $binaries{$package}{$suite} = [ sort split( /\s*,\s*/, $binaries ) ]; + $binaries{$package}{$suite} = find_binaries( $package, $suite ); } if ($format eq 'html') { @@ -498,15 +531,8 @@ unless ($search_on_sources) { print "
Binary packages: "; my @bp_links; foreach my $bp (@{$binaries{$pkg}{$ver}}) { - my $sect = 'section'; - - my $bp_link; - if ($sect) { - $bp_link = sprintf( "%s", - $ver, $sect, uri_escape( $bp ), $bp ); - } else { - $bp_link = $bp; - } + my $bp_link = sprintf( "%s", + $ver, uri_escape( $bp ), $bp ); push @bp_links, $bp_link; } print join( ", ", @bp_links ); @@ -515,29 +541,6 @@ unless ($search_on_sources) { } print "\n"; } - } elsif ($format eq 'xml') { - require RDF::Simple::Serialiser; - my $rdf = new RDF::Simple::Serialiser; - $rdf->addns( debpkg => 'http://packages.debian.org/xml/01-debian-packages-rdf' ); - my @triples; - foreach my $pkg (sort keys %pkgs) { - foreach my $ver (@SUITES) { - if (exists $pkgs{$pkg}{$ver}) { - my $id = "$ROOT/$ver/source/$pkg"; - - push @triples, [ $id, 'debpkg:package', $pkg ]; - push @triples, [ $id, 'debpkg:type', 'source' ]; - push @triples, [ $id, 'debpkg:section', $sect{$pkg}{$ver}{source} ]; - push @triples, [ $id, 'debpkg:version', $pkgs{$pkg}{$ver} ]; - push @triples, [ $id, 'debpkg:part', $part{$pkg}{$ver}{source} || 'main' ]; - - foreach my $bp (@{$binaries{$pkg}{$ver}}) { - push @triples, [ $id, 'debpkg:binary', $bp ]; - } - } - } - } - print $rdf->serialise(@triples); } }