From: Frank Lichtenheld Date: Wed, 1 Feb 2006 15:09:57 +0000 (+0000) Subject: Include all stuff to be quickly able to set up a experimental search script X-Git-Tag: switch-to-templates~224 X-Git-Url: https://git.deb.at/w?a=commitdiff_plain;h=e41d34b008ea4b4ad09b5eea457d7523c7ef2fa3;p=deb%2Fpackages.git Include all stuff to be quickly able to set up a experimental search script --- diff --git a/cgi-bin/search_packages.pl b/cgi-bin/search_packages.pl new file mode 100755 index 0000000..bc51c30 --- /dev/null +++ b/cgi-bin/search_packages.pl @@ -0,0 +1,614 @@ +#!/usr/bin/perl -wT +# +# search_packages.pl -- CGI interface to the Packages files on packages.debian.org +# +# Copyright (C) 1998 James Treacy +# Copyright (C) 2000, 2001 Josip Rodin +# Copyright (C) 2001 Adam Heath +# Copyright (C) 2004 Martin Schulze +# Copyright (C) 2004 Frank Lichtenheld +# +# use is allowed under the terms of the GNU Public License (GPL) +# see http://www.fsf.org/copyleft/gpl.html for a copy of the license + +require 5.001; +use strict; +use CGI qw( -oldstyle_urls ); +#use CGI::Carp qw( fatalsToBrowser ); +use POSIX; +use URI::Escape; +use HTML::Entities; +use DB_File; +use Benchmark; + +use lib "../lib"; + +use Deb::Versions; +use Packages::Search qw( :all ); +use Packages::HTML (); + +my $thisscript = "search_packages.pl"; +my $use_grep = 1; +my $HOME = "http://www.debian.org"; +my $ROOT = ""; +my $SEARCHPAGE = "http://packages.debian.org/"; +my @SUITES = qw( oldstable stable testing unstable experimental ); +my @DISTS = @SUITES; +my @SECTIONS = qw( main contrib non-free ); +my @ARCHIVES = qw( us security installer ); +my @ARCHITECTURES = qw( alpha amd64 arm hppa hurd-i386 i386 ia64 + kfreebsd-i386 mips mipsel powerpc s390 sparc ); + +$ENV{PATH} = "/bin:/usr/bin"; + +# Read in all the variables set by the form +my $input = new CGI; + +my $pet0 = new Benchmark; +# use this to disable debugging in production mode completly +my $debug_allowed = 0; +my $debug = $debug_allowed && $input->param("debug"); +$Search::Param::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->dump; +# exit; + +my %params_def = ( keywords => { default => undef, match => '^\s*([-+\@\w\/.:]+)\s*$' }, + suite => { default => 'stable', match => '^(\w+)$', + alias => 'version', array => ',', + replace => { all => \@SUITES } }, + case => { default => 'insensitive', match => '^(\w+)$' }, + official => { default => 0, match => '^(\w+)$' }, + use_cache => { default => 1, match => '^(\w+)$' }, + subword => { default => 0, match => '^(\w+)$' }, + exact => { default => undef, match => '^(\w+)$' }, + searchon => { default => 'all', match => '^(\w+)$' }, + section => { default => 'all', match => '^([\w-]+)$', + alias => 'release', array => ',', + replace => { all => \@SECTIONS } }, + arch => { default => 'any', match => '^(\w+)$', + array => ',', replace => + { any => \@ARCHITECTURES } }, + archive => { default => 'all', match => '^(\w+)$', + array => ',', replace => + { all => \@ARCHIVES } }, + format => { default => 'html', match => '^(\w+)$' }, + ); +my %params = Packages::Search::parse_params( $input, \%params_def ); + +my $format = $params{values}{format}{final}; +#XXX: Don't use alternative output formats yet +$format = 'html'; + +if ($format eq 'html') { + print $input->header; +} elsif ($format eq 'xml') { +# print $input->header( -type=>'application/rdf+xml' ); + print $input->header( -type=>'text/plain' ); +} + +if ($params{errors}{keywords}) { + print "Error: keyword not valid or missing" if $format eq 'html'; + exit 0; +} +my $keyword = $params{values}{keywords}{final}; +my @suites = @{$params{values}{suite}{final}}; +my $official = $params{values}{official}{final}; +my $use_cache = $params{values}{use_cache}{final}; +my $case = $params{values}{case}{final}; +my $case_bool = ( $case !~ /insensitive/ ); +my $subword = $params{values}{subword}{final}; +my $exact = $params{values}{exact}{final}; +$exact = !$subword unless defined $exact; +my $searchon = $params{values}{searchon}{final}; +my @sections = @{$params{values}{section}{final}}; +my @archs = @{$params{values}{arch}{final}}; +my $page = $params{values}{page}{final}; +my $results_per_page = $params{values}{number}{final}; + +# for URL construction +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 $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}}; +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, + }, + ); +} + +# 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; +} +while () { + $topdir = $1 if (/^\s*topdir="?(.*)"?\s*$/); +} +close (C); + +my $FLATDIR = $topdir . "/files/flat"; +my $search_on_sources = 0; + +my %descr; +my %sections; + +sub find_desc +{ + my $pkg = shift; + my $suite = shift; + my $part = shift; + my $descr = ''; + + unless (exists $descr{$suite}{$part}) { + $descr{$suite}{$part} = {}; + tie %{$descr{$suite}{$part}}, 'DB_File', "$FLATDIR/$suite/$part/Description", O_RDONLY + or return "Error while loading descriptions database: $!"; + } + + return $descr{$suite}{$part}{$pkg}; +} + +sub find_section +{ + my $pkg = shift; + my $suite = shift; + my $part = shift; + my $section = ''; + + unless (exists $sections{$suite}{$part}) { + $sections{$suite}{$part} = {}; + tie %{$sections{$suite}{$part}}, 'DB_File', "$FLATDIR/$suite/$part/Section", O_RDONLY + or return undef; + } + + return $sections{$suite}{$part}{$pkg}; +} + +my $st0 = new Benchmark; +tie my %cache, 'DB_File', "$topdir/files/search.cache/search.cache", O_RDWR|O_CREAT or $use_cache = 0; +my $cached; +my @results; +my $cache_key = $keyword.$exact.$subword.$searchon.$suites_param.$sections_param.$archs_param; +if ($searchon eq 'sourcenames') { + $search_on_sources = 1; +} +if ($use_cache && ($cached = $cache{$cache_key})) { + @results = split /\n/, $cached; + print "DEBUG: Used cached results
$cached
" if $debug; +} else { + my $searchkeyword = $keyword; + my $grep_searchkeyword = $keyword; + $searchkeyword =~ s/[.]/\\./; + if (($searchon eq 'names') || ($searchon eq 'sourcenames')) { + # asserting that all package names are lower case + $searchkeyword = lc($searchkeyword) unless $case_bool; + $case_bool = 1; + $grep_searchkeyword = "^[^ ]*$searchkeyword" unless $exact; + $searchkeyword = "^\\S*$searchkeyword" unless $exact; + } else { + $grep_searchkeyword = "\\(^$searchkeyword\\b\\|\\b$searchkeyword\\b\\)" + if $subword != 1; + $searchkeyword = "\\b$searchkeyword\\b" + if $subword != 1; + } + +# FIXME +# check if the Packages files are there +#my @files = glob ("$fdir/$file"); +#if ($#files == -1) { +# XXX has to be updated for new architectures +# if ($format eq 'html') { +# if (($version eq "stable" and $arch =~ /^(hurd|sh)$/) +# || ($version eq "oldstable" and $arch =~ /^amd64$/)) { +# print "Error: the $arch architecture didn't exist in $version.
\n" +# ."Please go back and choose a different distribution.\n"; +# } else { +# print "Error: Packages/Sources file not found.
\n" +# ."If the problem persists, please inform $ENV{SERVER_ADMIN}.\n"; +# printf "

$file

"; +# } +# &printfooter; +# } +# exit; +#} + + my @files; + foreach my $s (@suites) { + foreach my $sec (@sections) { + foreach my $a (@archs) { + foreach my $archive (@ARCHIVES) { + if (($searchon eq 'names' or $searchon eq 'sourcenames') + and $exact) { + my ( %packages, $file ); + if ($search_on_sources) { + $file = "$FLATDIR/$s/$sec/Sources.$archive.db"; + } else { + $file = "$FLATDIR/$s/$sec/Packages-$a.$archive.db"; + } + if (-f $file) { + print "DEBUG: Use file $file
" + if $debug > 1; + + tie %packages, 'DB_File', $file, O_RDONLY + or die "Couldn't open packages file $file: $!"; + + if (my $data = $packages{$searchkeyword}) { + print "DEBUG: Found result $data
" + if $debug > 1; + push @results, "$file:$data"; + } + } + } else { + my $file; + if ($search_on_sources) { + $file = "$FLATDIR/$s/$sec/Sources.$archive"; + } else { + $file = "$FLATDIR/$s/$sec/Packages-$a.$archive"; + } + if (-f $file) { + print "DEBUG: Use file $file
" + if $debug > 1; + + # use_grep is currently way faster, though + # I can't pinpoint exactly why, yet + # most probably the perl regexes are + # slow compared to the simpler grep + # regexes + unless ($use_grep) { + open my $pkg_fh, '<', $file + or die "Couldn't open packages file $file: $!"; + + foreach (<$pkg_fh>) { + if (/$searchkeyword/o) { + print "DEBUG: Found result $_
" + if $debug > 1; + + push @results, "$file:$_"; + } + } + } else { + push @files, $file; + } + } + } + } + } + } + } + + if ($use_grep) { + if (@files) { + my @grep = ( 'grep', '-H' ); + push @grep, '-i' unless $case_bool; + push @grep, $grep_searchkeyword; + push @grep, @files; + + print "DEBUG: starting grep command '". + substr("@grep",0,100)."[...]'
" if $debug; + open my $grep_out, '-|', @grep or + die "grep failed: $!"; + @results = <$grep_out>; + } + } + + $cache{$cache_key} = join "", @results; +} + +my $st1 = new Benchmark; +my $std = timediff($st1, $st0); +print "DEBUG: Search took ".timestr($std)."
" if $debug; + +if ($format eq 'html') { + my $suite_wording = $suites_enc eq "all" ? "all suites" + : "suite(s) $suites_enc"; + my $section_wording = $sections_enc eq 'all' ? "all sections" + : "section(s) $sections_enc"; + my $arch_wording = $archs_enc eq 'any' ? "all architectures" + : "architecture(s) $archs_enc"; + 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.

"; + } 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.

"; + } +} + +if (!@results) { + if ($format eq 'html') { + my $keyword_esc = uri_escape( $keyword ); + my $printed = 0; + if (($searchon eq "names") || ($searchon eq 'sourcenames')) { + if (($suites_enc eq 'all') + && ($archs_enc eq 'any') + && ($sections_enc eq 'all')) { + print "

Can't find that package.

\n"; + } else { + print "

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

\n"; + } + + 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.

"; + } + } else { + if (($suites_enc eq 'all') + && ($archs_enc eq 'any') + && ($sections_enc eq 'all')) { + print "

Can't find that string.

\n"; + } 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"; + } + + unless ($subword) { + $printed = 1; + print "

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; + } + exit; +} + +my (%pkgs, %sect, %part, %desc, %binaries); +my (@colon, $package, $pkg_t, $section, $ver, $arch, $foo, $binaries); + +unless ($search_on_sources) { + foreach my $line (@results) { + @colon = split (/:/, $line); + ($pkg_t, $section, $ver, $arch, $foo) = split (/ /, $#colon >1 ? $colon[1].":".$colon[2]:$colon[1], 5); + $section =~ s,^(non-free|contrib)/,,; + $section =~ s,^non-US.*$,non-US,,; + my ($dist,$part,undef) = $colon[0] =~ m,.*/([^/]+)/([^/]+)/Packages-([^\.]+)\.,; #$1=stable, $2=main, $3=alpha + + ($package) = $pkg_t =~ m/^(.+)/; # untaint + $pkgs{$package}{$dist}{$ver}{$arch} = 1; + $sect{$package}{$dist}{$ver} = $section; + $part{$package}{$dist}{$ver} = $part unless $part eq 'main'; + + $desc{$package}{$dist}{$ver} = find_desc ($package, $dist, $part) if (! exists $desc{$package}{$dist}{$ver}); + + } + + if ($format eq 'html') { + my ($start, $end) = multipageheader( scalar keys %pkgs ); + my $count = 0; + + foreach my $pkg (sort keys %pkgs) { + $count++; + next if $count < $start or $count > $end; + printf "

Package %s

\n", $pkg; + 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 $ver (@DISTS) { + 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 my $line (@results) { + chomp($line); + @colon = split (/:/, $line); + ($package, $section, $ver, $binaries) = split (/ /, $#colon >1 ? $colon[1].":".$colon[2]:$colon[1], 4); + $section =~ s,^(non-free|contrib)/,,; + $section =~ s,^non-US.*$,non-US,,; + $colon[0] =~ m,.*/([^/]+)/([^/]+)/Sources\.,; #$1=stable, $2=main + + my ($suite, $part) = ($1, $2); + $pkgs{$package}{$suite} = $ver; + $sect{$package}{$suite}{source} = $section; + $part{$package}{$suite}{source} = $part unless $part eq 'main'; + + $binaries{$package}{$suite} = [ sort split( /\s*,\s*/, $binaries ) ]; + + } + + if ($format eq 'html') { + my ($start, $end) = multipageheader( scalar keys %pkgs ); + my $count = 0; + + foreach my $pkg (sort keys %pkgs) { + $count++; + next if ($count < $start) or ($count > $end); + printf "

Source package %s

\n", $pkg; + 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 $ver (@DISTS) { + 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); + } +} + +if ($format eq 'html') { + &printindexline( scalar keys %pkgs ); + &printfooter; +} + +exit; + +sub printindexline { + my $no_results = shift; + + my $index_line; + if ($no_results > $results_per_page) { + + $index_line = prevlink($input,\%params)." | ".indexline( $input, \%params, $no_results)." | ".nextlink($input,\%params, $no_results); + + print "

$index_line

"; + } +} + +sub multipageheader { + my $no_results = shift; + + my ($start, $end); + if ($results_per_page =~ /^all$/i) { + $start = 1; + $end = $no_results; + $results_per_page = $no_results; + } else { + $start = Packages::Search::start( \%params ); + $end = Packages::Search::end( \%params ); + if ($end > $no_results) { $end = $no_results; } + } + + print "

Found $no_results matching packages,"; + if ($end == $start) { + print " displaying package $end.

"; + } else { + print " displaying packages $start to $end.

"; + } + + printindexline( $no_results ); + + if ($no_results > 100) { + print "

Results per page: "; + my @resperpagelinks; + for (50, 100, 200) { + if ($results_per_page == $_) { + push @resperpagelinks, $_; + } else { + push @resperpagelinks, resperpagelink($input,\%params,$_); + } + } + if ($params{values}{number}{final} =~ /^all$/i) { + push @resperpagelinks, "all"; + } else { + push @resperpagelinks, resperpagelink($input, \%params,"all"); + } + print join( " | ", @resperpagelinks )."

"; + } + return ( $start, $end ); +} + +sub printfooter { +print < + +
+

Packages search page

+ + +END + +print $input->end_html; +} diff --git a/config.sh b/config.sh new file mode 100644 index 0000000..b1a039f --- /dev/null +++ b/config.sh @@ -0,0 +1,49 @@ +# Configuration for packages.debian.org +# + +topdir=/org/packages.debian.org + +tmpdir=${topdir}/tmp +bindir=${topdir}/bin +scriptdir=${topdir}/htmlscripts +libdir=${topdir}/lib +filesdir=${topdir}/files +htmldir=${topdir}/www +archivedir=${topdir}/archive +podir=${topdir}/po +localedir=${topdir}/locale +staticdir=${topdir}/static +configdir=${topdir}/etc + +# unset this if packages.debian.org moves somewhere where the packages files +# cannot be obtained locally +# +localdir=/org/ftp.debian.org/ftp + +# path to private ftp directory +ftproot=/org/ftp.root + +ftpsite=http://ftp.debian.org/debian +nonus_ftpsite=http://ftp.uk.debian.org/debian-non-US +security_ftpsite=http://security.debian.org/debian-security +volatile_ftpsite=http://volatile.debian.net/debian-volatile +amd64_ftpsite=http://amd64.debian.net/debian +kfreebsd_ftpsite=http://kfreebsd-gnu.debian.net/debian + +# Architectures +# +polangs="de fi nl fr uk" +ddtplangs="de cs da eo es fi fr hu it ja nl pl pt_BR pt_PT ru sk sv_SE uk" +parts="main contrib non-free" +dists="oldstable stable testing unstable" +arch_oldstable="alpha arm hppa i386 ia64 m68k mips mipsel powerpc s390 sparc" +arch_stable="${arch_oldstable} amd64" +arch_testing="${arch_stable}" +arch_unstable="${arch_stable} hurd-i386 kfreebsd-i386" +arch_experimental="${arch_unstable}" +arch_testing_proposed_updates="${arch_testing}" +arch_stable_proposed_updates="${arch_stable}" + +# Miscellaneous +# +admin_email="djpig@debian.org,joey@infodrom.org" diff --git a/lib/Packages/HTML.pm b/lib/Packages/HTML.pm new file mode 100644 index 0000000..1003949 --- /dev/null +++ b/lib/Packages/HTML.pm @@ -0,0 +1,483 @@ +package Packages::HTML; + +use strict; +use warnings; + +use URI::Escape; +use HTML::Entities; + +use Packages::Util; +use Packages::I18N::Locale; +use Packages::I18N::Languages; +use Packages::I18N::LanguageNames; +use Generated::Strings qw( gettext dgettext ); + +our @ISA = qw( Exporter ); +our @EXPORT = qw( header title trailer file_changed time_stamp + read_md5_hash write_md5_hash simple_menu + ds_begin ds_item ds_end note title marker pdesc + pdeplegend pkg_list pmoreinfo ); + +our $HOME = "http://www.debian.org"; +our $CONTACT_MAIL = 'debian-www@lists.debian.org'; +our $WEBMASTER_MAIL = 'webmaster@debian.org'; +our $SEARCH_PAGE = "http://packages.debian.org/"; +our $CGI_ROOT = "http://packages.debian.org/cgi-bin"; +our $CN_HELP_URL = "${HOME}/intro/cn"; +our $CHANGELOG_URL = '/changelogs'; +our $COPYRIGHT_URL = '/changelogs'; +our $SEARCH_URL = '/cgi-bin/search_packages.pl?searchon=names&version=all&exact=1&keywords='; +our $SRC_SEARCH_URL = '/cgi-bin/search_packages.pl?searchon=sourcenames&version=all&exact=1&keywords='; +our $BUG_URL = 'http://bugs.debian.org/'; +our $SRC_BUG_URL = 'http://bugs.debian.org/src:'; +our $QA_URL = 'http://packages.qa.debian.org/'; + + +my %img_trans = ( pt_BR => "pt", pt_PT => "pt", sv_SE => "sv" ); + +sub img { + my ( $root, $url, $src, $alt, %attr ) = @_; + my @attr; + + foreach my $a ( keys %attr ) { + push @attr, "$a=\"$attr{$a}\""; + } + + return "\"$alt\""; +} + +sub simple_menu { + my $str = ""; + foreach my $entry (@_) { + $str .= "[ $entry->[0] [1]\" href=\"$entry->[2]\">$entry->[3] ]\n"; + } + return $str; +} + +sub title { + return "

$_[0]

\n"; +} + +sub marker { + return "[$_[0]]"; +} + +sub note { + my ( $title, $note ) = @_; + my $str = ""; + + if ($note) { + $str .= "

$title

"; + } else { + $note = $title; + } + $str .= "

$note

"; + return $str; +} + +sub pdesc { + my ( $short_desc, $long_desc ) = @_; + my $str = ""; + + $str .= "
\n"; + $str .= "

$short_desc

\n"; + + $str .= "

$long_desc\n"; + $str .= "

\n"; + + return $str; +} + +sub pdeplegend { + my $str = "\n"; + + foreach my $entry (@_) { + $str .= ""; + } + + $str .= "\n
[0].gif\" alt=\"[$entry->[0]]\" width=\"16\" height=\"16\">= $entry->[1]
\n"; + return $str; +} + +sub pkg_list { + my ( $pkgs, $lang, $env ) = @_; + + my $str = ""; + foreach my $p ( @$pkgs ) { + my $p_pkg = $env->{db}->get_pkg( $p ); + + if ( $p_pkg ) { + if ($p_pkg->is_virtual) { + $str .= "
$p
\n". + "\t
".gettext("Virtual package")."
\n"; + } else { + my %subsections = $p_pkg->get_arch_fields( 'section', + $env->{archs} ); + my $subsection = $subsections{max_unique}; + my %desc_md5s = $p_pkg->get_arch_fields( 'description-md5', + $env->{archs} ); + my $short_desc = conv_desc( $lang, + encode_entities( $env->{db}->get_short_desc( $desc_md5s{max_unique}, $lang ), "<>&\"" ) ); + $str .= "
$p
\n". + "\t
$short_desc
\n"; + } + } else { + $str .= "
$p
\n\t
".gettext("Not available")."
\n"; + } + } + if ($str) { + $str = "
$str
\n"; + } + + return $str; +} + +sub pmoreinfo { + my %info = @_; + + my $name = $info{name} or return; + my $env = $info{env} or return; + my $d = $info{data} or return; + my $is_source = $info{is_source}; + + my $str = "
"; + $str .= sprintf( "

".gettext( "More Information on %s" )."

", + $name ); + + + if ($info{bugreports}) { + my $bug_url = $is_source ? $SRC_BUG_URL : $BUG_URL; + $str .= "

\n".sprintf( gettext( "Check for Bug Reports about %s." )."
\n", + $bug_url.$name, $name ); + } + + if ($info{sourcedownload}) { + $str .= gettext( "Source Package:" ); + $str .= " {src_name}\">$d->{src_name}, ". + gettext( "Download" ).":\n"; + + unless ($d->{src_files}) { + $str .= gettext( "Not found" ); + } else { + foreach( @{$d->{src_files}} ) { + my ($src_file_md5, $src_file_size, $src_file_name) = @$_; + if ($d->{is_security}) { + $str .= "{opts}{security_site}/$d->{src_directory}/$src_file_name\">["; + } elsif ($d->{is_volatile}) { + $str .= "{opts}{volatile_site}/$d->{src_directory}/$src_file_name\">["; + } elsif ($d->{is_nonus}) { + $str .= "{opts}{nonus_site}/$d->{src_directory}/$src_file_name\">["; + } else { + $str .= "{opts}{debian_site}/$d->{src_directory}/$src_file_name\">["; + } + if ($src_file_name =~ /dsc$/) { + $str .= "dsc"; + } else { + $str .= $src_file_name; + } + $str .= "]\n"; + } + } +# $package_page .= sprintf( gettext( " (These sources are for version %s)\n" ), $src_version ) +# if ($src_version ne $version) && !$src_version_given_in_control; + } + + if ($info{changesandcopy}) { + if ( $d->{src_directory} ) { + my $src_dir = $d->{src_directory}; + (my $src_basename = $d->{src_version}) =~ s,^\d+:,,; # strip epoche + $src_basename = "$d->{src_name}_$src_basename"; + $src_dir =~ s,pool/updates,pool,o; + $src_dir =~ s,pool/non-US,pool,o; + $str .= "
".sprintf( gettext( "View the Debian changelog" ), + "$CHANGELOG_URL/$src_dir/$src_basename/changelog" )."
\n"; + my $copyright_url = "$COPYRIGHT_URL/$src_dir/$src_basename/"; + $copyright_url .= ( $is_source ? 'copyright' : "$name.copyright" ); + + $str .= sprintf( gettext( "View the copyright file" ), + $copyright_url )."

"; + } + } + + if ($info{maintainers}) { + my @uploaders = @{$d->{uploaders}}; + foreach (@uploaders) { + $_->[0] = encode_entities( $_->[0], '&<>' ); + } + my ($maint_name, $maint_mail ) = @{shift @uploaders}; + unless (@uploaders) { + $str .= "

\n".sprintf( gettext( "%s is responsible for this Debian package." ). + "\n", + "$maint_name" + ); + } else { + my $up_str = "$maint_name"; + my @uploaders_str; + foreach (@uploaders) { + push @uploaders_str, "[1]\">$_->[0]"; + } + my $last_up = pop @uploaders_str; + $up_str .= ", ".join ", ", @uploaders_str if @uploaders_str; + $up_str .= sprintf( gettext( " and %s are responsible for this Debian package." ), $last_up ); + $str .= "

\n$up_str "; + } + + $str .= sprintf( gettext( "See the developer information for %s." )."

", $QA_URL.$d->{src_name}, $name ); + } + + if ($info{search}) { + my $encodedname = uri_escape( $name ); + my $search_url = $is_source ? $SRC_SEARCH_URL : $SEARCH_URL; + $str .= "

".sprintf( gettext( "Search for other versions of %s" ), $search_url.$encodedname, $name )."

\n"; + } + + $str .= "
\n"; + return $str; +} + +my $ds_begin = '
'; +my $ds_item_desc = '
'; +my $ds_item = ':
'; +my $ds_item_end = '
'; +my $ds_end = '
'; +# my $ds_begin = ''; +# my $ds_item_desc = ''; +# my $ds_end = '
'; +# my $ds_item = ''; +# my $ds_item_end = '
'; + +sub ds_begin { + return $ds_begin; +} +sub ds_item { + return "$ds_item_desc$_[0]$ds_item$_[1]$ds_item_end\n"; +} +sub ds_end { + return $ds_end; +} + +sub header { + my (%params) = @_; + + my $DESC_LINE; + if (defined $params{desc}) { + $DESC_LINE = ""; + } + else { + $DESC_LINE = ''; + } + + my $title_keywords = $params{title_keywords} || $params{title} || ''; + my $title_tag = $params{title_tag} || $params{title} || ''; + my $title_in_header = $params{page_title} || $params{title} || ''; + my $page_title = $params{page_title} || $params{title} || ''; + my $meta = $params{meta} || ''; + + if ($params{print_title_above}) { + $title_in_header = "

$title_in_header

"; + } else { + $title_in_header = ''; + } + + my $search_in_header = ''; + $params{print_search_field} ||= ""; + if ($params{print_search_field} eq 'packages') { + my %values = %{$params{search_field_values}}; + my %checked_searchon = ( names => "", + all => "", + sourcenames => "", ); + $checked_searchon{$values{searchon}} = "checked=\"checked\""; + $search_in_header = < +
+ + + + + + + + +Full options +
+
Search on: + +   + + +
+ + +
+
+ +MENU +; + } elsif ($params{print_search_field} eq 'contents') { + my %values = %{$params{search_field_values}}; + my %checked_searchmode = ( searchfiles => "", + searchfilesanddirs => "", + searchword => "", + filelist => "", ); + $checked_searchmode{$values{searchmode}} = "checked=\"checked\""; + $search_in_header = < +
+ + + +  + +Full options +
+
Display: + + + + +
+ + + + +
+
+ +MENU +; + } + + my $keywords = $params{keywords} || ''; + my $KEYWORDS_LINE = ""; + + my $LANG = $params{lang}; + my $img_lang = $img_trans{$LANG} || $LANG; + my $charset = get_charset($LANG); + my $txt = < + + +Debian -- $title_tag + + + +$KEYWORDS_LINE +$DESC_LINE +$meta + + + +