1 package Packages::DoShow;
9 use Benchmark ':hireswallclock';
13 use Packages::Config qw( $DBDIR $ROOT @SUITES @ARCHIVES @SECTIONS
14 @ARCHITECTURES %FTP_SITES $SEARCH_URL );
15 use Packages::I18N::Locale;
18 use Packages::Search qw( :all );
20 use Packages::Page ();
21 use Packages::SrcPage ();
23 our @ISA = qw( Exporter );
24 our @EXPORT = qw( do_show );
27 my ($params, $opts, $html_header, $menu, $page_content) = @_;
29 if ($params->{errors}{package}) {
30 fatal_error( _g( "package not valid or not specified" ) );
32 if ($params->{errors}{suite}) {
33 fatal_error( _g( "suite not valid or not specified" ) );
35 if (@{$opts->{suite}} > 1) {
36 fatal_error( sprintf( _g( "more than one suite specified for show (%s)" ), "@{$opts->{suite}}" ) );
39 my $pkg = $opts->{package};
40 my $encodedpkg = uri_escape( $pkg );
41 my $suite = $opts->{suite}[0];
42 my $archive = $opts->{archive}[0] ||'';
44 my $DL_URL = "$pkg/download";
45 my $FILELIST_URL = "$pkg/files";
47 our (%packages_all, %sources_all);
48 my (@results, @non_results);
49 my $page = $opts->{source} ?
50 new Packages::SrcPage( $pkg ) :
51 new Packages::Page( $pkg );
52 my $package_page = "";
53 my ($short_desc, $version, $section, $subsection) = ("")x5;
55 my $st0 = new Benchmark;
56 unless (@Packages::CGI::fatal_errors) {
57 tie %packages_all, 'DB_File', "$DBDIR/packages_all_$suite.db",
58 O_RDONLY, 0666, $DB_BTREE
59 or die "couldn't tie DB $DBDIR/packages_all_$suite.db: $!";
60 tie %sources_all, 'DB_File', "$DBDIR/sources_all_$suite.db",
61 O_RDONLY, 0666, $DB_BTREE
62 or die "couldn't tie DB $DBDIR/sources_all_$suite.db: $!";
64 unless ($opts->{source}) {
65 read_entry_all( \%packages, $pkg, \@results, \@non_results, $opts );
67 read_src_entry_all( \%sources, $pkg, \@results, \@non_results, $opts );
70 unless (@results || @non_results ) {
71 fatal_error( _g( "No such package." )."<br>".
72 sprintf( _g( '<a href="%s">Search for the package</a>' ), "$SEARCH_URL/$pkg" ) );
75 foreach (@results, @non_results) {
80 foreach (suites_sort(keys %all_suites)) {
82 $$menu .= "[ <strong>$_</strong> ] ";
84 $$menu .= "[ <a href=\"$ROOT/$_/$encodedpkg\">$_</a> ] ";
90 fatal_error( _g( "Package not available in this suite." ) );
92 unless ($opts->{source}) {
93 for my $entry (@results) {
94 debug( join(":", @$entry), 1 ) if DEBUG;
95 my (undef, $archive, undef, $arch, $section, $subsection,
96 $priority, $version, $provided_by) = @$entry;
98 if ($arch ne 'virtual') {
99 my %data = split /\000/, $packages_all{"$pkg $arch $version"};
100 $data{package} = $pkg;
101 $data{architecture} = $arch;
102 $data{version} = $version;
103 $page->merge_package(\%data) or debug( "Merging $pkg $arch $version FAILED", 2 ) if DEBUG;
105 $page->add_provided_by([split /\s+/, $provided_by]);
109 unless ($page->is_virtual()) {
110 $version = $page->{newest};
111 my $source = $page->get_newest( 'source' );
112 $archive = $page->get_newest( 'archive' );
113 debug( "find source package: source=$source", 1) if DEBUG;
114 my $src_data = $sources_all{"$archive $suite $source"};
115 $page->add_src_data( $source, $src_data )
118 my $st1 = new Benchmark;
119 my $std = timediff($st1, $st0);
120 debug( "Data search and merging took ".timestr($std) ) if DEBUG;
122 my $did = $page->get_newest( 'description' );
123 $section = $page->get_newest( 'section' );
124 $subsection = $page->get_newest( 'subsection' );
125 my $filenames = $page->get_arch_field( 'filename' );
126 my $file_md5sums = $page->get_arch_field( 'md5sum' );
127 my $archives = $page->get_arch_field( 'archive' );
128 my $versions = $page->get_arch_field( 'version' );
129 my $sizes_inst = $page->get_arch_field( 'installed-size' );
130 my $sizes_deb = $page->get_arch_field( 'size' );
131 my @archs = sort $page->get_architectures;
133 # process description
135 my $desc = $descriptions{$did};
136 $short_desc = encode_entities( $1, "<>&\"" )
137 if $desc =~ s/^(.*)$//m;
138 my $long_desc = encode_entities( $desc, "<>&\"" );
140 $long_desc =~ s,((ftp|http|https)://[\S~-]+?/?)((\>\;)?[)]?[']?[:.\,]?(\s|$)),<a href=\"$1\">$1</a>$3,go; # syntax highlighting -> '];
141 $long_desc =~ s/\A //o;
142 $long_desc =~ s/\n /\n/sgo;
143 $long_desc =~ s/\n.\n/\n<p>\n/go;
144 $long_desc =~ s/(((\n|\A) [^\n]*)+)/\n<pre>$1\n<\/pre>/sgo;
145 # $long_desc = conv_desc( $lang, $long_desc );
146 # $short_desc = conv_desc( $lang, $short_desc );
148 $$menu .= simple_menu( [ _g( "Distribution:" ),
149 _g( "Overview over this suite" ),
153 _g( "All packages in this section" ),
154 "$ROOT/$suite/$subsection/",
157 _g( "Source package building this package" ),
158 "$ROOT/$suite/source/".$page->get_src('package'),
159 $page->get_src('package') ],
162 my $v_str = $version;
163 my $multiple_versions = grep { $_ ne $version } values %$versions;
164 $v_str .= _g(" and others") if $multiple_versions;
165 my $title .= sprintf( _g( "Package: %s (%s)" ), $pkg, $v_str );
166 $title .= " ".marker( $archive ) if $archive ne 'us';
167 $title .= " ".marker( $subsection ) if $subsection eq 'non-US'
168 and $archive ne 'non-US'; # non-US/security
169 $title .= " ".marker( $section ) if $section ne 'main';
170 $package_page .= title( $title );
172 if (my $provided_by = $page->{provided_by}) {
173 note( _g( "This is also a virtual package provided by ").join( ', ', map { "<a href=\"$ROOT/$suite/$_\">$_</a>" } @$provided_by) );
176 if ($suite eq "experimental") {
177 note( _g( "Experimental package"),
178 _g( "Warning: This package is from the <strong>experimental</strong> distribution. That means it is likely unstable or buggy, and it may even cause data loss. If you ignore this warning and install it nevertheless, you do it on your own risk.")."</p>"
181 if ($subsection eq "debian-installer") {
182 note( _g( "debian-installer udeb package"),
183 _g( 'Warning: This package is intended for the use in building <a href="http://www.debian.org/devel/debian-installer">debian-installer</a> images only. Do not install it on a normal Debian system.' )
186 $package_page .= pdesc( $short_desc, $long_desc );
189 # display dependencies
192 $dep_list = print_deps( \%packages, $opts, $pkg,
193 $page->get_dep_field('depends'),
195 $dep_list .= print_deps( \%packages, $opts, $pkg,
196 $page->get_dep_field('recommends'),
198 $dep_list .= print_deps( \%packages, $opts, $pkg,
199 $page->get_dep_field('suggests'),
203 $package_page .= "<div id=\"pdeps\">\n";
204 $package_page .= sprintf( "<h2>"._g( "Other Packages Related to %s" )."</h2>\n", $pkg );
205 if ($suite eq "experimental") {
206 note( sprintf( _g( 'Note that the <strong>experimental</strong> distribution is not self-contained; missing dependencies are likely found in the <a href="%s">unstable</a> distribution.' ), "$ROOT/unstable/" ) );
209 $package_page .= pdeplegend( [ 'dep', _g( 'depends' ) ],
210 [ 'rec', _g( 'recommends' ) ],
211 [ 'sug', _g( 'suggests' ) ], );
213 $package_page .= $dep_list;
214 $package_page .= "</div> <!-- end pdeps -->\n";
220 my $encodedpack = uri_escape( $pkg );
221 $package_page .= "<div id=\"pdownload\">";
222 $package_page .= sprintf( "<h2>"._g( "Download %s\n" )."</h2>",
224 $package_page .= "<table summary=\""._g("The download table links to the download of the package and a file overview. In addition it gives information about the package size and the installed size.")."\">\n";
225 $package_page .= "<caption class=\"hidecss\">"._g("Download for all available architectures")."</caption>\n";
226 $package_page .= "<tr>\n";
227 $package_page .= "<th>"._g("Architecture")."</th>";
228 $package_page .= "<th>"._g("Version")."</th>"
229 if $multiple_versions;
230 $package_page .= "<th>"._g( "Package Size")."</th><th>"._g("Installed Size")."</th><th>"._g("Files")."</th></tr>\n";
231 foreach my $a ( @archs ) {
232 $package_page .= "<tr>\n";
233 $package_page .= "<th><a href=\"$ROOT/$suite/$encodedpkg/$a/download";
234 $package_page .= "\">$a</a></th>\n";
235 $package_page .= "<td>".$versions->{$a}."</td>"
236 if $multiple_versions;
237 $package_page .= '<td class="size">';
238 $package_page .= floor(($sizes_deb->{$a}/102.4)+0.5)/10 . " kB";
239 $package_page .= '</td><td class="size">';
240 $package_page .= $sizes_inst->{$a} . " kB";
241 $package_page .= "</td>\n<td>";
242 if ( $suite ne "experimental" ) {
243 $package_page .= sprintf( "[<a href=\"%s\">"._g( "list of files" )."</a>]\n",
244 "$ROOT/$suite/$encodedpkg/$a/filelist", $pkg );
246 $package_page .= _g( "no current information" );
248 $package_page .= "</td>\n</tr>";
250 $package_page .= "</table>\n";
251 $package_page .= "</div> <!-- end pdownload -->\n";
256 $package_page .= pmoreinfo( name => $pkg, data => $page,
259 bugreports => 1, sourcedownload => 1,
260 changesandcopy => 1, maintainers => 1,
262 } else { # unless $page->is_virtual
263 $short_desc = _g( "virtual package" );
265 $$menu .= simple_menu( [ _g( "Distribution:" ),
266 _g( "Overview over this distribution" ),
270 _g( "All packages in this section" ),
271 "$ROOT/$suite/virtual/",
275 $package_page .= title( sprintf( _g( "Virtual Package: %s" ),
278 my $policy_url = 'http://www.debian.org/doc/debian-policy/';
279 note( sprintf( _g( 'This is a <em>virtual package</em>. See the <a href="%s">Debian policy</a> for a <a href="%sch-binary.html#s-virtual_pkg">definition of virtual packages</a>.' ),
280 $policy_url, $policy_url ));
282 $package_page .= sprintf( "<h2>"._g( "Packages providing %s" )."</h2>", $pkg );
283 my $provided_by = $page->{provided_by};
284 $package_page .= pkg_list( \%packages, $opts, $provided_by, 'en');
286 } # else (unless $page->is_virtual)
287 } else { # unless $opts->{source}
288 for my $entry (@results) {
289 debug( join(":", @$entry), 1 ) if DEBUG;
290 my (undef, $archive, undef, $section, $subsection,
291 $priority, $version) = @$entry;
293 my $data = $sources_all{"$archive $suite $pkg"};
294 $page->merge_data($pkg, $suite, $archive, $data)
295 or debug( "Merging $pkg $version FAILED", 2 ) if DEBUG;
297 $version = $page->{version};
299 my $st1 = new Benchmark;
300 my $std = timediff($st1, $st0);
301 debug( "Data search and merging took ".timestr($std) ) if DEBUG;
303 $archive = $page->get_newest( 'archive' );
304 $section = $page->get_newest( 'section' );
305 $subsection = $page->get_newest( 'subsection' );
307 $$menu .= simple_menu( [ _g( "Distribution:" ),
308 _g( "Overview over this suite" ),
312 _g( "All packages in this section" ),
313 "/$suite/$subsection/",
317 my $title .= sprintf( _g( "Source Package: %s (%s)" ),
319 $title .= " ".marker( $archive ) if $archive ne 'us';
320 $title .= " ".marker( $subsection ) if $subsection eq 'non-US'
321 and $archive ne 'non-US'; # non-US/security
322 $title .= " ".marker( $section ) if $section ne 'main';
323 $package_page .= title( $title );
325 if ($suite eq "experimental") {
326 note( _g( "Experimental package"),
327 _g( "Warning: This package is from the <strong>experimental</strong> distribution. That means it is likely unstable or buggy, and it may even cause data loss. If you ignore this warning and install it nevertheless, you do it on your own risk.")."</p>"
330 if ($subsection eq "debian-installer") {
331 note( _g( "debian-installer udeb package"),
332 _g( 'Warning: This package is intended for the use in building <a href="http://www.debian.org/devel/debian-installer">debian-installer</a> images only. Do not install it on a normal Debian system.' )
336 my $binaries = find_binaries( $pkg, $archive, $suite, \%src2bin );
337 if ($binaries && @$binaries) {
338 $package_page .= '<div class="pdesc">';
339 $package_page .= _g( "The following binary packages are built from this source package:" );
340 $package_page .= pkg_list( \%packages, $opts, $binaries, 'en' );
341 $package_page .= '</div> <!-- end pdesc -->';
345 # display dependencies
348 $dep_list = print_deps( \%packages, $opts, $pkg,
349 $page->get_dep_field('build-depends'),
351 $dep_list .= print_deps( \%packages, $opts, $pkg,
352 $page->get_dep_field('build-depends-indep'),
353 'build-depends-indep' );
356 $package_page .= "<div id=\"pdeps\">\n";
357 $package_page .= sprintf( "<h2>"._g( "Other Packages Related to %s" )."</h2>\n", $pkg );
358 if ($suite eq "experimental") {
359 note( sprintf( _g( 'Note that the <strong>experimental</strong> distribution is not self-contained; missing dependencies are likely found in the <a href="%s">unstable</a> distribution.' ), "$ROOT/unstable/" ) );
363 $package_page .= pdeplegend( [ 'adep', _g( 'build-depends' ) ],
364 [ 'idep', _g( 'build-depends-indep' ) ],
367 $package_page .= $dep_list;
368 $package_page .= "</div> <!-- end pdeps -->\n";
372 # Source package download
374 $package_page .= "<div id=\"pdownload\">\n";
375 $package_page .= sprintf( "<h2>"._g( "Download %s" )."</h2>\n",
378 my $source_files = $page->get_src( 'files' );
379 my $source_dir = $page->get_src( 'directory' );
381 $package_page .= sprintf( '<table summary="'._g('Download information for the files of this source package' ).'">'.
382 "<tr><th>%s</th><th>%s</th><th>%s</th>",
386 foreach( @$source_files ) {
387 my ($src_file_md5, $src_file_size, $src_file_name)
392 $src_url = $FTP_SITES{security}; last };
394 $src_url = $FTP_SITES{volatile}; last };
397 $src_url = $FTP_SITES{backports}; last };
399 $src_url = $FTP_SITES{'non-US'}; last };
400 $src_url = $FTP_SITES{us};
402 $src_url .= "/$source_dir/$src_file_name";
404 $package_page .= "<tr><td><a href=\"$src_url\">$src_file_name</a></td>\n"
405 ."<td>".sprintf("%.1f", (floor(($src_file_size/102.4)+0.5)/10))."</td>\n"
406 ."<td class=\"md5sum\">$src_file_md5</td></tr>";
408 $package_page .= "</table>\n";
409 $package_page .= "</div> <!-- end pdownload -->\n";
414 $package_page .= pmoreinfo( name => $pkg, data => $page,
418 changesandcopy => 1, maintainers => 1,
419 search => 1, is_source => 1 );
421 } # else (unless $opts->{source})
422 } # else (unless @results)
423 } # else (unless (@results || @non_results ))
427 # debug( "Final page object:\n".Dumper($page), 3 ) if DEBUG;
429 my $title = $opts->{source} ?
430 _g( "Details of source package <em>%s</em> in %s" ) :
431 _g( "Details of package <em>%s</em> in %s" ) ;
432 my $title_tag = $opts->{source} ?
433 _g( "Details of source package %s in %s" ) :
434 _g( "Details of package %s in %s" ) ;
435 %$html_header = ( title => sprintf( $title, $pkg, $suite ) ,
436 lang => $opts->{lang},
438 keywords => "$suite, $archive, $section, $subsection, $version",
439 title_tag => sprintf( $title_tag, $pkg, $suite ),
440 print_search_field => 'packages',
441 search_field_values => {
443 searchon => $opts->{source} ? 'sourcenames' : 'names',
448 debug => $opts->{debug},
452 $$page_content = $package_page;