files
archive
config.sh
+cache
+tmp
+*~
+*.ttc
| key: "packagename version arch"
| value: a unique description id, did
-| descriptions.txt:
-| on each line:
-| description with strange characters mangled for proper substring
-| searching, linenumber being the did
-
| descriptions.db:
| key: did
| value: description, first line being short, the rest being long [no
matches" and abce: 90 matches"
- fulltext search:
- - Max 100 results
- - Better exact=1 performance by indexing per word?
- - drop case-sensitive from options, descriptions.txt all lowercase and without
- punctuation, such that instead of =~ //, indexof can be used
- in results, show full descriptions, so one sees what's being matched?
- backend:
run-parts --verbose $topdir/cron.d >> $log 2>&1
rm -f "${files}/cron.lock"
else
- echo "couldn't aquire lock file in due time" >> $log
+ echo "couldn't aquire cron lock file in due time" >> $log
fi
+date >> $log
+if lockfile -600 -r5 "${files}/changelogs.lock" >> $log 2>&1
+then
+ $topdir/bin/extract_changelogs >> $log 2>&1
+ rm -f "${files}/changelogs.lock"
+else
+ echo "couldn't aquire changelogs lock file in due time" >> $log
+fi
date >> $log
--- /dev/null
+#!/bin/bash
+
+. `dirname $0`/../config.sh
+
+if test -z "${localdir}"; then
+ echo skipping due to missing local archive
+ exit 1
+fi
+
+#set -e
+
+NOCPY_TEMPLATE=$topdir/etc/copyright_error
+NOCPY_BIN_TEMPLATE=$topdir/etc/copyright_error_bin
+
+logs="$topdir/files/logs"
+log="${logs}/changelogs.log"
+
+test -d "$logs" || mkdir -p "$logs"
+test -d "$tmpdir" || mkdir -p "$tmpdir"
+
+if [ -s "$log" ]
+then
+ savelog -c 14 "$log" > /dev/null
+fi
+
+(
+date
+
+for part in $parts; do
+ time "${bindir}/extract_files" -v -d "${localdir}/pool/$part/" \
+ -t "${htmldir}/changelogs/pool/$part/" \
+ -c "$configdir" -w "$tmpdir" \
+ --dumpfile "${filesdir}/changelogs.$part.dump" \
+ --cachefile "${filesdir}/changelogs.cache"
+done
+
+find "${htmldir}/changelogs/" -name log -cmin +7200 \
+ | while read logfile; do
+ dir=$(dirname "$logfile")
+ echo deleting $dir
+ rm -r "$dir"
+ rmdir --ignore-fail-on-non-empty $(dirname "$dir")
+done
+
+date
+) > $log 2>&1
use DB_File;
use Storable;
use File::Path;
+use Digest::MD5;
use Deb::Versions;
use Lingua::Stem v0.82;
use Search::Xapian;
}
# Skip double package
next if exists($packages_all_db{"$data{'package'} $data{'architecture'} $data{'version'}"});
- # Skip arch:all for amd64&kfreebsd, too often broken
- next if ($archive eq 'amd64' or $archive eq 'kfreebsd')
+ # Skip arch:all for amd64 & gnuab, any non-redundancy is
+ # usually a bug anyway
+ next if ($archive eq 'amd64' or $archive eq 'gnuab')
and $data{architecture} eq 'all';
if ($data{'provides'}) {
$src =~ s/\s+.*//o; # strip version info
}
$data{'source'} = $src;
+
+ # expand tags like devel::{lang:c,lang:c++}
+ if ($data{'tag'} && $data{'tag'} =~ /\{/) {
+ my @complete_tags = split(/, /, $data{'tag'});
+ my @tags;
+ foreach (@complete_tags) {
+ my ($facet, $tag) = split( /::/, $_, 2);
+ if ($tag =~ s/^\{(.+)\}$/$1/) {
+ foreach (split( /,/, $tag )) {
+ push @tags, "${facet}::$_";
+ }
+ } else {
+ push @tags, "${facet}::$tag";
+ }
+ }
+ my $old = $data{tag};
+ $data{'tag'} = join ", ", @tags;
+ }
+
# we add some additional data here
my $descr = "$data{'description'}\000$data{'package'}\000"
.($data{'tag'}||'');
$descriptions[$did] = $descr;
$descriptions{$descr} = $did;
}
+ $data{'description-md5'} = Digest::MD5::md5_hex($data{'description'}, "\n");
$data{'description'} = $did;
$packages_descriptions{"$data{'package'} $data{'version'} $data{'architecture'}"} = $did;
$descriptions_packages{$did} .=
tie %descriptions_db, "DB_File", "$DBDIR/descriptions.db.new",
O_RDWR|O_CREAT, 0666, $DB_BTREE
or die "Error creating DB: $!";
-open DESCR, ">", "$DBDIR/descriptions.txt" or die "Error creating descriptions textfile";
print "Index $#descriptions descriptions\n";
for (my $i=1; $i<= $#descriptions; $i++) {
- my $plain_description = $descriptions[$i];
# strip away additional data
- my ($only_desc) = split /\000/o, $plain_description, 2;
+ my ($only_desc, $pkg, $tags) = split /\000/o, $descriptions[$i], 3;
# WARNING: This needs to correspond with what happens in
-# Packages/Search.pm:do_fulltext_search
- $plain_description =~ tr [A-Z] [a-z];
- # ensure one space on both ends
- $plain_description = " $plain_description ";
- $plain_description =~ s/[(),.-]+//og;
- $plain_description =~ s#[^a-z0-9_/+]+# #og;
- print DESCR "$plain_description\n";
+# Packages/Search.pm:do_xapian_search
+ $only_desc =~ s#[^\w/+]+# #og;
#XAPIAN
eval {
- my @words = split /\s+/, $plain_description;
- my $stem_words = $stemmer->stem( \@words );
+ my @words = split /\s+/, $only_desc;
+ unshift @words, $pkg;
+
my $doc = Search::Xapian::Document->new()
or die "can't create doc object for $i: $!\n";
if ($doc->set_data($i)){
warn "can't set_data in doc object for $i: $!\n";
}
- for my $j (0 .. (@$stem_words-1)) {
- next if $stem_words->[$j] =~ /^\s*$/o;
- if ($doc->add_posting($stem_words->[$j], $j)) {
- warn "can't add word $stem_words->[$j] $j: $!\n";
+
+ # package with prefix
+ if ($doc->add_term("P$pkg")) {
+ warn "can't add term P$pkg: $!\n";
+ }
+ # description, unstemmed with positional info
+ for my $j (0 .. (@words-1)) {
+ next if $words[$j] =~ /^\s*$/o;
+ if ($doc->add_posting($words[$j], $j)) {
+ warn "can't add posting $words[$j] at $j: $!\n";
}
}
+ # description, stemmed
+ my $stem_words = $stemmer->stem( \@words );
+ foreach my $w (@$stem_words) {
+ next if $w =~ /^\s*$/o;
+ if ($doc->add_term($w)) {
+ warn "can't add term $w: $!\n";
+ }
+ }
+ if ($tags) {
+ foreach my $t (split /, /, $tags) {
+ if ($doc->add_term($t)) {
+ warn "can't add term $t: $!\n";
+ }
+ }
+ }
+
$xapian_db->add_document($doc)
or warn "failed to add document: $i\n";
};
$descriptions_db{$i} = $only_desc;
}
-close DESCR;
untie %descriptions_db;
$xapian_db->flush;
undef $xapian_db;
"$DBDIR/packages_descriptions.db");
rename("$DBDIR/descriptions_packages.db.new",
"$DBDIR/descriptions_packages.db");
-rename("$DBDIR/descriptions.txt.new", "$DBDIR/descriptions.txt");
rename("$DBDIR/descriptions.db.new", "$DBDIR/descriptions.db");
rename("$DBDIR/package_postfixes.db.new", "$DBDIR/package_postfixes.db");
--- /dev/null
+#!/usr/bin/perl -w
+# Convert Translation.gz files into Sleepycat db files for efficient usage of
+# data
+#
+# $Id$
+#
+# Copyright (C) 2006 Jeroen van Wolffelaar <jeroen@wolffelaar.nl>
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+use strict;
+use warnings;
+use lib './lib';
+
+$| = 1;
+
+# max. distinct results for a given package postfix
+my $MAX_PACKAGE_POSTFIXES = 100;
+
+use DB_File;
+use Storable;
+use File::Path;
+use Digest::MD5;
+use Text::Iconv;
+use Deb::Versions;
+use Lingua::Stem v0.82;
+use Search::Xapian;
+use Packages::Config qw( $TOPDIR $DBDIR @DDTP_LANGUAGES );
+&Packages::Config::init( './' );
+my %descriptions = ();
+
+$/ = "";
+
+-d $DBDIR || mkpath( $DBDIR );
+
+my $fixja = Text::Iconv->new("EUC-JP", "UTF-8");
+
+foreach my $lang (@DDTP_LANGUAGES) {
+ print "Reading Translations for $lang...";
+ open PKG, "zcat $TOPDIR/archive/*/*/*/i18n/Translation-$lang.gz|";
+ my $count = 0;
+ while (<PKG>) {
+ next if /^\s*$/;
+ my $data = "";
+ my %data = ();
+ chomp;
+ s/\n /\377/g;
+ while (/^(\S+):\s*(.*)\s*$/mg) {
+ my ($key, $value) = ($1, $2);
+ $value =~ s/\377/\n /g;
+ $key =~ tr [A-Z] [a-z];
+ $data{$key} = $value;
+ }
+ # Skip double descriptions
+ next if exists($descriptions{$data{"description-md5"}}{$lang});
+ # some weirdnesses in the files
+ next unless defined $data{"description-".lc($lang)};
+ if ($lang eq 'ja') {
+ my $fixed = $fixja->convert($data{"description-ja"});
+ $data{"description-ja"} = $fixed if $fixed;
+ }
+ $descriptions{$data{"description-md5"}}{$lang} = $data{"description-".lc($lang)};
+ $count++;
+ }
+ print "($count)\n";
+}
+close PKG;
+
+print "Writing database (".scalar(keys %descriptions)." unique descriptions)...\n";
+my %descriptions_db;
+tie %descriptions_db, "DB_File", "$DBDIR/descriptions_translated.db.new",
+ O_RDWR|O_CREAT, 0666, $DB_BTREE
+ or die "Error creating DB: $!";
+while (my ($md5, $v) = each(%descriptions)) {
+ my $str = "";
+ while (my ($lang, $desc) = each %$v) {
+ unless ($lang && $desc) {
+ warn "MD5: $md5 LANG: $lang DESC: $desc\n";
+ exit;
+ }
+ $str .= "$lang\001$desc\000";
+ }
+
+ $descriptions_db{$md5} = $str;
+}
+untie %descriptions_db;
+
+rename("$DBDIR/descriptions_translated.db.new",
+ "$DBDIR/descriptions_translated.db");
echo -e "Using\n\ttopdir=$topdir\n\tsite=$site"
-find "$topdir" -name '*.sed.in' | while read file;
+find "$topdir" -maxdepth 2 -name '*.sed.in' | while read file;
do
wdir=$(dirname "$file")
newfile="$wdir/"$(basename "$file" .sed.in)
use Deb::Versions;
use Packages::Config qw( $DBDIR $ROOT $TEMPLATEDIR $CACHEDIR
@SUITES @SECTIONS @ARCHIVES @ARCHITECTURES @PRIORITIES
- @LANGUAGES $LOCALES );
+ @LANGUAGES @DDTP_LANGUAGES $LOCALES );
use Packages::CGI qw( :DEFAULT error get_all_messages );
use Packages::DB;
use Packages::Search qw( :all );
&Packages::DB::init();
my $acc = I18N::AcceptLanguage->new();
+my %all_langs = map { $_ => 1 } (@LANGUAGES, @DDTP_LANGUAGES);
+my @all_langs = sort keys %all_langs;
my $http_lang = $acc->accepts( $input->http("Accept-Language"),
- \@LANGUAGES ) || 'en';
-debug( "LANGUAGES=@LANGUAGES header=".
+ \@all_langs ) || 'en';
+debug( "LANGUAGES=@all_langs header=".
($input->http("Accept-Language")||'').
" http_lang=$http_lang", 2 ) if DEBUG;
bindtextdomain ( 'pdo', $LOCALES );
apache.conf
ttreerc
+maintainer
# unset this if %SITE% moves somewhere where the packages files
# cannot be obtained locally
#
-#localdir=/org/ftp.debian.org/ftp
+localdir=/org/ftp.debian.org/debian
# path to private ftp directory
#ftproot=/org/ftp.root
for arch in `eval echo $foo`
do
test ! "$arch" = "kfreebsd-i386" || continue
+ test ! "$arch" = "kfreebsd-amd64" || continue
+ test ! "$arch" = "armel" || continue
for part in ${parts}
do
echo retrieve Packages $dist/$part/$arch
for arch in `eval echo $foo`
do
test ! "$arch" = "kfreebsd-i386" || continue
+ test ! "$arch" = "kfreebsd-amd64" || continue
+ test ! "$arch" = "armel" || continue
for part in ${parts}
do
echo retrieve Packages $dist/$part/$arch
--- /dev/null
+#! /bin/bash
+
+. `dirname $0`/../config.sh
+
+test -d ${archivedir} || mkdir -p ${archivedir}
+cd ${archivedir}
+
+# Main archive
+#
+architectures="armel kfreebsd-i386 kfreebsd-amd64"
+
+for dist in unstable experimental
+ do
+ echo "retrieve Release(.gpg) $dist"
+ test -d gnuab/${dist} || mkdir -p gnuab/${dist}
+ (cd gnuab/${dist} &&
+ wget -q -N ${gnuab_ftpsite}/dists/${dist}/Release &&
+ wget -q -N ${gnuab_ftpsite}/dists/${dist}/Release.gpg )
+
+ for arch in $architectures
+ do
+ for part in ${parts} main/debian-installer
+ do
+ echo retrieve Packages $dist/$part/$arch
+ test -d gnuab/${dist}/${part}/binary-${arch} || mkdir -p gnuab/${dist}/${part}/binary-${arch}
+ (cd gnuab/${dist}/${part}/binary-${arch} &&
+ wget -q -N ${gnuab_ftpsite}/dists/${dist}/${part}/binary-${arch}/Packages.gz)
+ done
+ echo retrieve Contents $dist/$arch
+ (cd gnuab/${dist} &&
+ wget -q -N ${gnuab_ftpsite}/dists/${dist}/Contents-${arch}.gz)
+ done
+done
--- /dev/null
+#! /bin/bash
+
+. `dirname $0`/../config.sh
+
+test -d ${archivedir} || mkdir -p ${archivedir}
+cd ${archivedir}
+
+# Main archive
+#
+arch=m68k
+if [ -z "${localdir}" ]
+then
+ echo using remote mirror
+ for dist in etch
+ do
+ echo "retrieve Release(.gpg) $dist"
+ test -d us/${dist}-${arch} || mkdir -p us/${dist}-${arch}
+ (cd us/${dist} &&
+ wget -q -N ${ftpsite}/dists/${dist}-${arch}/Release &&
+ wget -q -N ${ftpsite}/dists/${dist}-${arch}/Release.gpg )
+
+# foo=\$arch_${dist//-/_}
+# for arch in `eval echo $foo`
+# do
+ for part in ${parts}
+ do
+ echo retrieve Packages $dist-${arch}/$part/$arch
+ test -d us/${dist}-${arch}/${part}/binary-${arch} || mkdir -p us/${dist}-${arch}/${part}/binary-${arch}
+ (cd us/${dist}-${arch}/${part}/binary-${arch} &&
+ wget -q -N ${ftpsite}/dists/${dist}-${arch}/${part}/binary-${arch}/Packages.gz)
+ done
+ #FIXME: no Contents files for p-u
+ test ! "$dist" = "experimental" || continue
+ echo retrieve Contents $dist/$arch
+ (cd us/${dist}-${arch} &&
+ wget -q -N ${ftpsite}/dists/${dist}-${arch}/Contents-${arch}.gz)
+# done
+ for part in ${parts}
+ do
+ echo retrieve Sources $dist-${arch}/$part
+ test -d us/${dist}-${arch}/${part}/source || mkdir -p us/${dist}-${arch}/${part}/source
+ (cd us/${dist}-${arch}/${part}/source &&
+ wget -q -N ${ftpsite}/dists/${dist}-${arch}/${part}/source/Sources.gz)
+ done
+ done
+else
+ echo using local mirror
+ for dist in etch
+ do
+ echo "retrieve Releases(.gpg) $dist"
+ test -d us/${dist}-${arch} || mkdir -p us/${dist}-${arch}
+ (cd us/${dist}-${arch} &&
+ rsync -t ${localdir}/dists/${dist}-${arch}/Release &&
+ rsync -t ${localdir}/dists/${dist}-${arch}/Release.gpg )
+
+# foo=\$arch_${dist//-/_}
+# for arch in `eval echo $foo`
+# do
+ for part in ${parts}
+ do
+ echo retrieve Packages $dist-${arch}/$part/$arch
+ test -d us/${dist}-${arch}/${part}/binary-${arch} || mkdir -p us/${dist}-${arch}/${part}/binary-${arch}
+ rsync -t ${localdir}/dists/${dist}-${arch}/${part}/binary-${arch}/Packages.gz \
+ us/${dist}-${arch}/${part}/binary-${arch}/Packages.gz
+ done
+ #FIXME: no Contents files for p-u
+ test ! "$dist" = "experimental" || continue
+ echo retrieve Contents $dist-${arch}/$arch
+ rsync -t ${localdir}/dists/${dist}-${arch}/Contents-${arch}.gz \
+ us/${dist}-${arch}/Contents-${arch}.gz
+# done
+ for part in ${parts}
+ do
+ echo retrieve Sources $dist-${arch}/$part
+ test -d us/${dist}-${arch}/${part}/source || mkdir -p us/${dist}-${arch}/${part}/source
+ rsync -t ${localdir}/dists/${dist}-${arch}/${part}/source/Sources.gz \
+ us/${dist}-${arch}/${part}/source/Sources.gz
+ done
+ done
+fi
+
--- /dev/null
+#! /bin/sh
+
+. `dirname $0`/../config.sh
+
+test -d ${archivedir} || mkdir -p ${archivedir}
+cd ${archivedir}
+
+if [ -z "${localdir}" ]
+then
+ echo using remote mirror
+ for dist in unstable
+ do
+ for part in main
+ do
+ test -d us/${dist}/${part}/i18n || mkdir -p us/${dist}/${part}/i18n
+ for lang in $ddtplangs
+ do
+ echo retrieve translated Descs $dist/$part/$lang
+ (cd us/${dist}/${part}/i18n &&
+ wget -q -N ${ftpsite}/dists/${dist}/${part}/i18n/Translations-$lang.gz)
+ done
+ done
+ done
+else
+ echo using local mirror
+ for dist in unstable
+ do
+ for part in main
+ do
+ test -d us/${dist}/${part}/i18n || mkdir -p us/${dist}/${part}/i18n
+ for lang in $ddtplangs
+ do
+ echo retrieve translated Descs $dist/$part/$lang
+ rsync -t ${localdir}/dists/${dist}/${part}/i18n/Translation-$lang.gz \
+ us/${dist}/${part}/i18n/Translation-$lang.gz
+ done
+ done
+ done
+fi
date
./bin/parse-contents
date
+./bin/parse-translations
+date
+++ /dev/null
-#!/bin/bash
-
-exit 0
-
-. `dirname $0`/../config.sh
-
-if test -z "${localdir}"; then
- echo skipping due to missing local archive
- exit 1
-fi
-
-#set -e
-
-NOCPY_TEMPLATE=$topdir/etc/copyright_error
-NOCPY_BIN_TEMPLATE=$topdir/etc/copyright_error_bin
-
-logs="$topdir/files/logs"
-log="${logs}/changelogs.log"
-
-test -d "$logs" || mkdir -p "$logs"
-test -d "$tmpdir" || mkdir -p "$tmpdir"
-
-if [ -s "$log" ]
-then
- savelog -c 14 "$log" > /dev/null
-fi
-
-(
-date
-
-for part in $parts; do
- time "${bindir}/extract_files" -v -d "${localdir}/pool/$part/" \
- -t "${htmldir}/changelogs/pool/$part/" \
- -c "$configdir" -w "$tmpdir" \
- --dumpfile "${filesdir}/changelogs.$part.dump" \
- --cachefile "${filesdir}/changelogs.cache"
-done
-
-find "${htmldir}/changelogs/" -name log -cmin +7200 \
- | while read logfile; do
- dir=$(dirname "$logfile")
- echo deleting $dir
- rm -r "$dir"
- rmdir --ignore-fail-on-non-empty $(dirname "$dir")
-done
-
-date
-) > $log 2>&1
my ( $v1, $v2 ) = @_;
my $r;
- while ( $v1 && $v2 ) {
+ while ( $v1 || $v2 ) {
$v1 =~ s/^(\D*)//o;
my $sp1 = $1;
$v2 =~ s/^(\D*)//o;
sub _lcmp {
my ( $v1, $v2 ) = @_;
-
- for ( my $i = 0; $i < length( $v1 ); $i++ ) {
+
+ for ( my $i = 0; $i <= length( $v1 ); $i++ ) {
my ( $n1, $n2 ) = ( ord( substr( $v1, $i, 1 ) ),
ord( substr( $v2, $i, 1 ) ) );
$n1 += 256 if $n1 < 65; # letters sort earlier than non-letters
}
our @SUITES_SORT = qw( woody oldstable sarge stable stable-proposed-updates
- etch testing testing-proposed-updates sid unstable
+ etch etch-m68k testing testing-proposed-updates sid unstable
experimental warty hoary hoary-backports breezy
breezy-backports dapper );
our @ARCHIVE_SORT = qw( non-US security updates volatile backports );
our @ISA = qw( Exporter );
our ( $TOPDIR, $DBDIR, $TEMPLATEDIR, $CACHEDIR, $ROOT,
- @LANGUAGES, $LOCALES,
+ @LANGUAGES, @DDTP_LANGUAGES, $LOCALES,
@SUITES, @SECTIONS, @ARCHIVES, @ARCHITECTURES,
@PRIORITIES, %FTP_SITES );
our @EXPORT_OK = qw( $TOPDIR $DBDIR $TEMPLATEDIR $CACHEDIR $ROOT
- @LANGUAGES $LOCALES
+ @LANGUAGES @DDTP_LANGUAGES $LOCALES
@SUITES @SECTIONS @ARCHIVES @ARCHITECTURES
@PRIORITIES %FTP_SITES );
our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
$FTP_SITES{us} = $1 if /^\s*ftpsite="?([^\"]*)"?\s*$/o;
$FTP_SITES{$1} = $2 if /^\s*(\w+)_ftpsite="?([^\"]*)"?\s*$/o;
@LANGUAGES = split(/\s+/, $1) if /^\s*polangs="?([^\"]*)"?\s*$/o;
+ @DDTP_LANGUAGES = split(/\s+/, $1) if /^\s*ddtplangs="?([^\"]*)"?\s*$/o;
@SUITES = split(/\s+/, $1) if /^\s*suites="?([^\"]*)"?\s*$/o;
@SECTIONS = split(/\s+/, $1) if /^\s*sections="?([^\"]*)"?\s*$/o;
@ARCHIVES = split(/\s+/, $1) if /^\s*archives="?([^\"]*)"?\s*$/o;
our @ISA = qw( Exporter );
our ( %packages, %sources, %src2bin, %did2pkg, %descriptions,
- %postf, %spostf, %debtags,
+ %postf, %spostf, %debtags, %desctrans,
$obj, $s_obj, $p_obj, $sp_obj );
our @EXPORT = qw( %packages %sources %src2bin %did2pkg %descriptions
- %postf %spostf %debtags
+ %postf %spostf %debtags %desctrans
$obj $s_obj $p_obj $sp_obj );
our $db_read_time ||= 0;
tie %descriptions, 'DB_File', "$DBDIR/descriptions.db",
O_RDONLY, 0666, $DB_BTREE
or die "couldn't tie DB $DBDIR/descriptions.db: $!";
+ tie %desctrans, 'DB_File', "$DBDIR/descriptions_translated.db",
+ O_RDONLY, 0666, $DB_BTREE
+ or die "couldn't tie DB $DBDIR/descriptions_translated.db: $!";
tie %did2pkg, 'DB_File', "$DBDIR/descriptions_packages.db",
O_RDONLY, 0666, $DB_BTREE
or die "couldn't tie DB $DBDIR/descriptions_packages.db: $!";
do_names_search( [ @keywords ], \%packages, $p_obj,
\&read_entry_all, $opts,
\@results, \@non_results );
-# my $fts0 = new Benchmark;
-# do_fulltext_search( [ @keywords ], "$DBDIR/descriptions.txt",
-# \%did2pkg, \%packages,
-# \&read_entry_all, $opts,
-# \@results, \@non_results );
my $fts1 = new Benchmark;
do_xapian_search( [ @keywords ], "$DBDIR/xapian/",
\%did2pkg, \%packages,
\&read_entry_all, $opts,
\@results, \@non_results );
my $fts2 = new Benchmark;
-# my $fts_grep = timediff($fts1,$fts0);
my $fts_xapian = timediff($fts2,$fts1);
-# debug( "Fulltext search took ".timestr($fts_grep)." (grep)" ) if DEBUG;
- debug( "Fulltext search took ".timestr($fts_xapian)." (Xapian)" )
+ debug( "Fulltext search took ".timestr($fts_xapian) )
if DEBUG;
}
}
if (@results) {
my (%pkgs, %subsect, %sect, %archives, %desc, %binaries, %provided_by);
+ my %sort_by_relevance;
+ for (1 ... scalar @results) {
+# debug("$results[$_][0] => $_", 4) if DEBUG;
+ $sort_by_relevance{$results[$_-1][0]} = $_;
+ }
+# use Data::Dumper;
+# debug( "sort_by_relevance=".Dumper(\%sort_by_relevance), 4);
+
unless ($opts->{source}) {
foreach (@results) {
my ($pkg_t, $archive, $suite, $arch, $section, $subsection,
}
my %uniq_pkgs = map { $_ => 1 } (keys %pkgs, keys %provided_by);
- my @pkgs = sort keys %uniq_pkgs;
+ my @pkgs;
+ if ($searchon eq 'names') {
+ @pkgs = sort keys %uniq_pkgs;
+ } else {
+ @pkgs = sort { $sort_by_relevance{$a} <=> $sort_by_relevance{$b} } keys %uniq_pkgs;
+ }
process_packages( $page_content, 'packages', \%pkgs, \@pkgs, $opts, \@keywords,
\&process_package, \%provided_by,
\%archives, \%sect, \%subsect,
use Deb::Versions;
use Packages::Config qw( $DBDIR @SUITES @ARCHIVES @SECTIONS
- @ARCHITECTURES %FTP_SITES );
+ @ARCHITECTURES %FTP_SITES @DDTP_LANGUAGES);
use Packages::I18N::Locale;
use Packages::CGI qw( :DEFAULT make_url make_search_url note );
use Packages::DB;
debug( "find source package: source=$source", 1) if DEBUG;
my $src_data = $sources_all{"$archive $suite $source"};
+ #FIXME: should be $main_archive or similar, not hardcoded "us"
+ $src_data = $sources_all{"us $suite $source"} unless $src_data;
$page->add_src_data( $source, $src_data )
if $src_data;
debug( "Data search and merging took ".timestr($std) ) if DEBUG;
my $did = $page->get_newest( 'description' );
+ my $desc_md5 = $page->get_newest( 'description-md5' );
my @complete_tags = split(/, /, $page->get_newest( 'tag' ));
my @tags;
foreach (@complete_tags) {
my ($facet, $tag) = split( /::/, $_, 2);
- # handle tags like devel::{lang:c,lang:c++}
- if ($tag =~ s/^\{(.+)\}$/$1/) {
- foreach (split( /,/, $tag )) {
- next if $tag =~ /^special:/;
- push @tags, [ $facet, $_ ];
- }
- } else {
- next if $tag =~ /^special:/;
- push @tags, [ $facet, $tag ];
- }
+ next if $facet =~ /^special/;
+ next if $tag =~ /^special:/;
+ push @tags, [ $facet, $tag ];
}
$contents{tags} = \@tags;
# process description
#
- my $desc = $descriptions{$did};
- $short_desc = encode_entities( $1, "<>&\"" )
- if $desc =~ s/^(.*)$//m;
- my $long_desc = encode_entities( $desc, "<>&\"" );
+ sub process_description {
+ my ($desc) = @_;
+
+ my $short_desc = encode_entities( $1, "<>&\"" )
+ if $desc =~ s/^(.*)$//m;
+ my $long_desc = encode_entities( $desc, "<>&\"" );
- $long_desc =~ s,((ftp|http|https)://[\S~-]+?/?)((\>\;)?[)]?[']?[:.\,]?(\s|$)),<a href=\"$1\">$1</a>$3,go; # syntax highlighting -> '];
- $long_desc =~ s/\A //o;
- $long_desc =~ s/\n /\n/sgo;
- $long_desc =~ s/\n.\n/\n<p>\n/go;
- $long_desc =~ s/(((\n|\A) [^\n]*)+)/\n<pre>$1\n<\/pre>/sgo;
+ $long_desc =~ s,((ftp|http|https)://[\S~-]+?/?)((\>\;)?[)]?[']?[:.\,]?(\s|$)),<a href=\"$1\">$1</a>$3,go; # syntax highlighting -> '];
+ $long_desc =~ s/\A //o;
+ $long_desc =~ s/\n /\n/sgo;
+ $long_desc =~ s/\n.\n/\n<p>\n/go;
+ $long_desc =~ s/(((\n|\A) [^\n]*)+)/\n<pre>$1\n<\/pre>/sgo;
+
+ return ($short_desc, $long_desc);
+ }
- $contents{desc} = { short => $short_desc,
- long => $long_desc, };
+ my $desc = $descriptions{$did};
+ my $long_desc;
+ ($short_desc, $long_desc) = process_description($desc);
+
+ $contents{desc}{en} = { short => $short_desc,
+ long => $long_desc, };
+
+ debug( "desc_md5=$desc_md5", 2)
+ if DEBUG;
+ my $trans_desc = $desctrans{$desc_md5};
+ if ($trans_desc) {
+ my %trans_desc = split /\000|\001/, $trans_desc;
+ debug( "TRANSLATIONS: ".join(" ",keys %trans_desc), 2)
+ if DEBUG;
+ while (my ($l, $d) = each %trans_desc) {
+ my ($short_t, $long_t) = process_description($d);
+
+ $contents{desc}{$l} = { short => $short_t,
+ long => $long_t, };
+ }
+ }
my $v_str = $version;
my $multiple_versions = grep { $_ ne $version } values %$versions;
instsize => $sizes_inst->{$a}, );
$d{version} = $versions->{$a} if $multiple_versions;
+ $d{archive} = $archives->{$a};
if ( ($suite ne "experimental")
&& ($subsection ne 'debian-installer')) {
$d{contents_avail} = 1;
if (defined($files) and @$files) {
foreach( @$files ) {
my ($src_file_md5, $src_file_size, $src_file_name) = split /\s/o, $_;
- my ($name, $server, $path);
+ my ($server, $path);
# non-US hack
($server = lc $page->get_newest('archive')) =~ s/-//go;
$server = $env->{$server}||$env->{us};
- $path = "$src_dir/$src_file_name";
- if ($src_file_name =~ /dsc$/) {
- $name = 'dsc'
- } else {
- $name = $src_file_name;
- }
- push @downloads, { name => $name, server => $server, path => $path };
+ $path = "/$src_dir/$src_file_name";
+ push @downloads, { name => $src_file_name, server => $server, path => $path };
}
}
$contents->{src}{downloads} = \@downloads;
default => "en_US",
);
-# most of them can probably changed to UTF-8 in Sarge
-# as there are more available UTF-8 locales then
+# this can probably be removed now that all locales are available in UTF-8
my %lang2charset = (
default => 'UTF-8',
- ja => 'EUC-JP',
- uk => 'KOI8-U',
);
sub get_locale {
return (exists($self->{provided_by}) && !exists($self->{versions}));
}
-our @TAKE_NEWEST = qw( description essential priority section subsection tag
+our @TAKE_NEWEST = qw( description description-md5 essential priority section subsection tag
archive source source-version url );
our @STORE_ALL = qw( version source source-version installed-size size
filename md5sum sha1 sha256 task
&$read_entry( $packages, $pkg, $results, $non_results, $opts );
}
}
-sub do_fulltext_search {
- my ($keywords, $file, $did2pkg, $packages, $read_entry, $opts,
- $results, $non_results) = @_;
-
-# NOTE: this needs to correspond with parse-packages!
- 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;
- }
- my $first_keyword = shift @tmp;
- @$keywords = @tmp;
-
- my $numres = 0;
- my %tmp_results;
- # fgrep is seriously faster than using perl
- open DESC, '-|', 'fgrep', '-n', '--', $first_keyword, $file
- or die "couldn't open $file: $!";
- LINE:
- while (<DESC>) {
- foreach my $k (@$keywords) {
- next LINE unless /\Q$k\E/;
- }
- /^(\d+)/;
- my $nr = $1;
- debug( "Matched line $_", 2) if DEBUG;
- my $result = $did2pkg->{$nr};
- foreach (split /\000/o, $result) {
- my @data = split /\s/, $_, 3;
-# debug ("Considering $data[0], arch = $data[2]", 3) if DEBUG;
-# next unless $data[2] eq 'all' || $opts->{h_archs}{$data[2]};
-# debug ("Ok", 3) if DEBUG;
- $numres++ unless $tmp_results{$data[0]}++;
- }
- last if $numres > 100;
- }
- close DESC;
- $too_many_hits++ if $numres > 100;
-
- my @results;
- foreach my $pkg (keys %tmp_results) {
- &$read_entry( $packages, $pkg, $results, $non_results, $opts );
- }
- }
sub do_xapian_search {
my ($keywords, $db, $did2pkg, $packages, $read_entry, $opts,
# NOTE: this needs to correspond with parse-packages!
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;
+ $keyword =~ s;[^\w/+]+; ;og;
push @tmp, $keyword;
}
my $stemmer = Lingua::Stem->new();
- $keywords = $stemmer->stem( @tmp );
+ my $stemmed_keywords = $stemmer->stem( @tmp );
my $db = Search::Xapian::Database->new( $db );
- my $enq = $db->enquire( OP_AND, @$keywords );
+ my $enq = $db->enquire( OP_OR, @$keywords, @$stemmed_keywords );
debug( "Xapian Query was: ".$enq->get_query()->get_description(), 1) if DEBUG;
- my @matches = $enq->matches(0, 100);
+ my @matches = $enq->matches(0, 999);
- my $numres = 0;
- my %tmp_results;
+ my (@order, %tmp_results);
foreach my $match ( @matches ) {
my $id = $match->get_docid();
my $result = $did2pkg->{$id};
foreach (split /\000/o, $result) {
my @data = split /\s/, $_, 3;
-# debug ("Considering $data[0], arch = $data[2]", 3) if DEBUG;
+ debug ("Considering $data[0], arch = $data[2], relevance=".$match->get_percent(), 3) if DEBUG;
# next unless $data[2] eq 'all' || $opts->{h_archs}{$data[2]};
# debug ("Ok", 3) if DEBUG;
- $numres++ unless $tmp_results{$data[0]}++;
+ unless ($tmp_results{$data[0]}++) {
+ push @order, $data[0];
+ }
}
- last if $numres > 100;
+ last if @order > 100;
}
undef $db;
- $too_many_hits++ if $numres > 100;
+ $too_many_hits++ if @order > 100;
- foreach my $pkg (keys %tmp_results) {
+ debug ("ORDER: @order", 2) if DEBUG;
+ foreach my $pkg (@order) {
&$read_entry( $packages, $pkg, $results, $non_results, $opts );
}
}
margin: 0 4px 0 4px;
padding: 0;
text-align: left;
+ font-family: Arial, Helvetica, sans-serif;
/* min-width: 440px - commented out due to mozilla problems*/
}
/* direction directive reverses the navbar, too */
bottom: 0;
text-align: center;
margin: 0px;
+ border-top: 1px solid #BFC3DC;
}
#fineprint {
font-size: 0.85em;
}
-#outer>#inner { border-bottom: 1px solid #BFC3DC; }
.bordertop { border-top: 1px solid #BFC3DC; }
dl.gloss dt {
--- /dev/null
+.oldstable-volatile, .oldstable-backports, .etch-m68k, .stable-backports {
+ font-size: smaller;
+}
clear: both;
}
-#pdesc, #ptags, #pdeps, #pdownload {
+#pdesc, #pbinaries, #ptags, #pdeps, #pdownload {
margin-left: 1em;
margin-right: 1em;
}
#pdownloadmeta tr {
text-align: left;
}
+#pdownload .vcurrent {
+ background-color: #bfb;
+}
+#pdownload .volder {
+ background-color: #ffb;
+}
+#pdownload .vold {
+ background-color: #fbb;
+}
/*
#pnavbar a:hover {
}
+#ptablist ul {
+ display: inline;
+ list-style-type: none;
+ padding-left: 0px;
+ line-height: 1.5em;
+}
+#ptablist ul li {
+ display: inline;
+ margin: 0 .25em;
+ white-space: nowrap;
+}
+
.p_js_elem {
font-size: smaller;
}
else
obj.style.display = "none";
}
+
+function hide_tab(id) {
+ var tab = document.getElementById(id);
+ if (tab) {
+ tab.style.display = "none";
+ }
+ var item = document.getElementById(id+"link");
+ if (item) {
+ item.style.fontWeight = "normal";
+ }
+}
+
+function show_tab(id) {
+ var tab = document.getElementById(id);
+ if (tab) {
+ tab.style.display = "";
+ }
+ var item = document.getElementById(id+"link");
+ if (item) {
+ item.style.fontWeight = "bold";
+ }
+ var item = document.getElementById("palllink");
+ if (item) {
+ item.style.fontWeight = "normal";
+ }
+}
+
+function init_tab_list(id) {
+ hide_tab("pdeps");
+ hide_tab("pdownload");
+ show_tab("pdesctab");
+ show_tab("pbinaries");
+
+ var tablist = document.getElementById(id);
+ if (tablist) {
+ var list = document.createElement("ul");
+ if (document.getElementById("pdesctab")) {
+ var item = document.createElement("li");
+ item.setAttribute("id","pdesctablink");
+ var link = document.createElement("a");
+ link.setAttribute("href","javascript:go_to_tab(\"pdesctab\")");
+ var txt = document.createTextNode("[ Description ]");
+ link.appendChild(txt);
+ item.appendChild(link);
+ list.appendChild(item);
+ }
+ if (document.getElementById("pbinaries")) {
+ var item = document.createElement("li");
+ item.setAttribute("id","pbinarieslink");
+ var link = document.createElement("a");
+ link.setAttribute("href","javascript:go_to_tab(\"pbinaries\")");
+ var txt = document.createTextNode("[ Description ]");
+ link.appendChild(txt);
+ item.appendChild(link);
+ list.appendChild(item);
+ }
+ if (document.getElementById("pdeps")) {
+ var item = document.createElement("li");
+ item.setAttribute("id","pdepslink");
+ var link = document.createElement("a");
+ link.setAttribute("href","javascript:go_to_tab(\"pdeps\")");
+ var txt = document.createTextNode("[ Dependencies ]");
+ link.appendChild(txt);
+ item.appendChild(link);
+ list.appendChild(item);
+ }
+ if (document.getElementById("pdownload")) {
+ var item = document.createElement("li");
+ item.setAttribute("id","pdownloadlink");
+ var link = document.createElement("a");
+ link.setAttribute("href","javascript:go_to_tab(\"pdownload\")");
+ var txt = document.createTextNode("[ Download ]");
+ link.appendChild(txt);
+ item.appendChild(link);
+ list.appendChild(item);
+ }
+ if (list.childNodes.length > 0) {
+ var item = document.createElement("li");
+ item.setAttribute("id","palllink");
+ var link = document.createElement("a");
+ link.setAttribute("href","javascript:show_all_tabs()");
+ var txt = document.createTextNode("[ All ]");
+ link.appendChild(txt);
+ item.appendChild(link);
+ list.appendChild(item);
+
+ }
+ tablist.appendChild(list);
+ }
+ show_tab("pdesctab");
+ show_tab("pbinaries");
+}
+
+function go_to_tab(id) {
+ if (id == "pdeps") {
+ hide_tab("pdesctab");
+ hide_tab("pbinaries");
+ hide_tab("pdownload");
+ show_tab("pdeps");
+ }
+ if (id == "pdesctab" || id == "pbinaries") {
+ hide_tab("pdeps");
+ hide_tab("pdownload");
+ show_tab("pdesctab");
+ show_tab("pbinaries");
+ }
+ if (id == "pdownload") {
+ hide_tab("pdesctab");
+ hide_tab("pbinaries");
+ hide_tab("pdeps");
+ show_tab("pdownload");
+ }
+}
+
+function show_all_tabs() {
+ show_tab("pdesctab");
+ show_tab("pbinaries");
+ show_tab("pdeps");
+ show_tab("pdownload");
+ var item = document.getElementById("palllink");
+ if (item) {
+ item.style.fontWeight = "bold";
+ }
+}
\ No newline at end of file
# cn_help_url = homepage _ 'intro/cn'
logo = {
url => homepage,
- src => '/Pics/openlogo-nd-50.png',
+ src => '/Pics/openlogo-nd-25.png',
alt => organisation,
}
copyright = {
s390 => 'IBM S/390',
"hurd-i386" => 'Hurd (i386)',
amd64 => 'AMD64',
+ armel => 'EABI ARM',
"kfreebsd-i386" => 'GNU/kFreeBSD (i386)',
"kfreebsd-amd64" => 'GNU/kFreeBSD (amd64)'
}
-%]
\ No newline at end of file
+%]
amd64 => {
unofficial_port => {
- url_name => 'amd64',
- name => 'AMD64',
+ amd64 => {
+ url_name => 'amd64',
+ name => 'AMD64',
+ }
},
europa => [
"amd64.debian.net/debian",
],
},
- kfreebsd => {
+ gnuab => {
unofficial_port => {
- url_name => 'kfreebsd-gnu',
- name => 'GNU/kFreeBSD',
+ 'kfreebsd-amd64' => {
+ url_name => 'kfreebsd-gnu',
+ name => 'GNU/kFreeBSD',
+ },
+ 'kfreebsd-i386' => {
+ url_name => 'kfreebsd-gnu',
+ name => 'GNU/kFreeBSD',
+ },
+ armel => {
+ url => 'http://www.debonaras.org/',
+ name => 'armel',
+ },
},
north_america => [
"www.gtlib.gatech.edu/pub/gnuab/debian",
packages, instead of doing so manually via this website.</p>
<p>You should be able to use any of the listed mirrors by adding a
line to your <kbd>/etc/apt/sources.list</kbd> like this:</p>
+[% IF archive != "security" %]
<pre>
deb http://<em>[% mirrors.$archive.europa.0 %]</em> [% suite %] main [% section IF section != main_section %]
</pre>
<p>Replacing <em>[% mirrors.$archive.europa.0 %]</em> with the mirror in question.
+[% ELSE %]
+<pre>
+deb http://security.debian.org/debian-security [% suite _ "/updates" %] main [% section IF section != main_section %]
+</pre>
+[%- END %]
[% IF suite == "experimental" %]
<h2>Experimental package</h2>
<p>Warning: This package is from the <strong>experimental</strong> distribution.
[% END %]
[% IF a.unofficial_port %]
-[% SET port = a.unofficial_port %]
+[% SET port = a.unofficial_port.$architecture %]
+[% IF port.url_name;
+ SET port.url = ports_url _ port.url_name _ '/';
+ END -%]
<p style="clear:both">Note that [% port.name %] is not officially included in the [% organisation %] archive yet,
but the [% port.name %] porter group keeps their archive in sync with the official archive as close as possible.
-See the <a href="[% ports_url _ port.url_name _ '/' %]">[% port.name %] ports page</a> for current information.</p>
+See the <a href="[% port.url %]">[% port.name %] ports page</a> for current information.</p>
[% END %]
<p>Note that in some browsers you will need to tell your browser you want the file saved to a file.
<link href="/debian.css" rel="stylesheet" type="text/css" media="all">
<link href="/packages.css" rel="stylesheet" type="text/css" media="all">
+<link href="/packages-site.css" rel="stylesheet" type="text/css" media="all">
<link href="/ubuntu/ubuntu.css" rel="stylesheet" type="text/css" media="all">
<link href="/ubuntu/masthead.css" rel="stylesheet" type="text/css" media="all">
[% IF rss_alternate %]
to content</a>
[%- IF print_search_field %]
-[% checked = 'checked="checked"' %]
+[% checked = 'checked="checked"'
+ selected = 'selected="selected"' %]
<div id="search">
<form method="GET" action="/search">
<div id="hpacketsearch">
[% IF search_field_values.suite %]<input type="hidden" name="suite" value="[% search_field_values.suite %]">[% END %]
[% IF search_field_values.sections %]<input type="hidden" name="section" value="[% search_field_values.sections %]">[% END %]
[% IF search_field_values.architectures %]<input type="hidden" name="arch" value="[% search_field_values.architectures %]">[% END %]
-<input type="text" size="30" name="keywords" value="[% search_field_values.keywords | html %]" id="kw">
<input type="submit" value="Search">
+<select size="1" name="searchon">
+<option value="names" [% selected IF search_field_values.searchon == 'names' || search_field_values.searchon == 'default' %]>
+package names</option>
+<option value="all" [% selected IF search_field_values.searchon == 'all' %]>descriptions</option>
+<option value="sourcenames" [% selected IF search_field_values.searchon == 'sourcenames' %]>source package names</option>
+<option value="contents" [% selected IF search_field_values.searchon == 'contents' %]>package contents</option
+</select>
+<input type="text" size="30" name="keywords" value="[% search_field_values.keywords | html %]" id="kw">
<span style="font-size: 60%"><a href="[% searchformurl %]">all options</a></span>
-<br>
-<div style="font-size: 80%">search in:
-<input type="radio" name="searchon" value="names" id="onlynames" [% checked IF search_field_values.searchon == 'names' || search_field_values.searchon == 'default' %]>
-<label for="onlynames">package names</label>
-
-<input type="radio" name="searchon" value="all" id="descs" [% checked IF search_field_values.searchon == 'all' %]>
-<label for="descs">descriptions</label>
-<br>
-<input type="radio" name="searchon" value="sourcenames" id="src" [% checked IF search_field_values.searchon == 'sourcenames' %]>
-<label for="src">source package names</label>
-<input type="radio" name="searchon" value="contents" id="conts" [% checked IF search_field_values.searchon == 'contents' %]>
-<label for="conts">package contents</label>
-</div>
</div> <!-- end hpacketsearch -->
</form>
</div>
[% END %]
[% IF too_many_hits %]
+[% IF opts.search != "names" %]
+<p id="psearchtoomanyhits">Note that this only shows the best matches, sorted by relevance.
+If the first few packages don't match what you searched for, try using more keywords or alternative
+keywords.</p>
+[% ELSE %]
<p id="psearchtoomanyhits">Your search was too wide so we will only display exact matches.
At least <em>[% too_many_hits %]</em> results have been omitted and will not be displayed.
Please consider using a longer keyword or more keywords.</p>
-[% END %]
+[% END; END %]
[% UNLESS results %]
<p id="psearchnoresult">Sorry, your search gave no results</p>
<h3>Package [% pkg %]</h3>
<ul>
[% FOREACH s IN suites %]
- <li><a class="resultlink" href="[% make_url(pkg,'','suite',s.suite,'arch','','section','') %]">[% s.suite %]</a>[% ' (' _ s.subsection _ ')' IF s.subsection %]: [% s.desc %] [%- IF s.section != main_section %] [<strong class="pmarker">[% s.section %]</strong>][% END %]
+ <li class="[% s.suite %]"><a class="resultlink" href="[% make_url(pkg,'','suite',s.suite,'arch','','section','') %]">[% s.suite %]</a>[% ' (' _ s.subsection _ ')' IF s.subsection %]: [% s.desc %] [%- IF s.section != main_section %] [<strong class="pmarker">[% s.section %]</strong>][% END %]
[% FOREACH s.versions %]
<br>[% version %] [%- IF archive != main_archive %] [<strong class="pmarker">[% archive %]</strong>][% END %]: [% architectures.join(' ') %]
[% END %]
[% PROCESS 'config/archive_layout.tmpl' %]
+[% PROCESS 'config/mirrors.tmpl' %]
[%- nav_arr = [ { prefix=>'Distribution:', title=>'Overview over this suite', url=>make_url('/','','source',''), name=>suite }, ];
nav_arr.push( { title => 'Source packages', url=>make_url('/'), name=>'Source' } ) IF is_source;
nav_arr.push( { prefix=>'Section:', title=>'All packages in this section', url=>make_url("$subsection/"), name=>subsection } );
nav_arr.push( { prefix=>'Package:', name=>pkg } ); -%]
+[% desclang = 'en';
+ SET desclang = lang IF desc.$lang.long %]
[%- PROCESS 'html/head.tmpl'
title_tag = ( is_source ? "Details of source package $pkg in $suite"
: "Details of package $pkg in $suite" )
- description = desc
+ description = desc.$desclang.short
keywords = "$suite, $archive, $section, $subsection, $version"
print_search_field = 'packages'
search_field_values = {
<ul>
<li><a href="[% (is_source ? src_bugs_url : bugs_url) _ pkg | uri %]">Bug Reports</a></li>
-[% IF src -%]
+[% IF src.pkg -%]
<li><a href="[% pts_url _ src.pkg | uri %]">Developer Information (PTS)</a></li>
[% ELSIF is_source %]
<li><a href="[% pts_url _ pkg | uri %]">Developer Information (PTS)</a></li>
<h3>Maintainer:</h3>
[%- FOREACH maintainers -%]
<a href="mailto:[% mail %]">[% name | html %]</a>
- (<a href="[% ddpo_url _ mail %]" title="An overview over the maintainter's packages and uploads">QA Page</a>)
+ (<a href="[% ddpo_url _ mail %]" title="An overview over the maintainer's packages and uploads">QA Page</a>)
[%- END -%]
[%- ELSE -%]
<h3>Maintainers:</h3>
[%- FOREACH maintainers -%]
[%- '<ul>' IF loop.first -%]
<li><a href="mailto:[% mail %]">[% name | html %]</a>
- (<a href="[% ddpo_url _ mail %]" title="An overview over the maintainter's packages and uploads">QA Page</a>)
+ (<a href="[% ddpo_url _ mail %]" title="An overview over the maintainer's packages and uploads">QA Page</a>)
</li>
[%- '</ul>' IF loop.last -%]
[%- END -%]
</div>
[% END %]
+<div id="ptablist">
+</div>
+
+[% IF desc %]
+<div id="pdesctab">
<div id="pdesc">
[% UNLESS is_virtual %]
- [% IF desc.short %]
- <h2>[% desc.short %]</h2>
- <p>[% desc.long %]
+ [% IF desc.$desclang.short %]
+ <h2>[% desc.$desclang.short %]</h2>
+ <p>[% desc.$desclang.long %]
[% END %]
[% ELSE %]
<p>This is a <em>virtual package</em>. See the <a href="[% policy_url %]">Debian policy</a> for a <a href="[% policy_url %]ch-binary.html#s-virtual_pkg">definition of virtual packages</a>.</p>
<dd>[% desc %]</dd>
[% '</dl></div>' IF loop.last %]
[% END %]
+</div> <!-- pdesctab -->
+[% END %]
[% FOREACH binaries %]
- [% IF loop.first %]<div class="pdesc">The following binary packages are built from this source package:<dl>[% END %]
+ [% IF loop.first %]<div id="pbinaries">The following binary packages are built from this source package:<dl>[% END %]
<dt>[% IF available %]<a href="[% make_url(name,'','source','') %]">[% name %]</a>[% ELSE %][% name %][% END %]</dt>
<dd>[% desc %]</dd>
[% '</dl></div>' IF loop.last %]
[%- END %]
[% END %]
-[% FOREACH downloads %]
+[% FOREACH d IN downloads %]
[% IF loop.first -%]
<div id="pdownload">
<h2>Download [% pkg %]</h2>
[%- END %]
<tr>
-[% download_url = pkg _ '/' _ arch _ '/download'
- filelist_url = pkg _ '/' _ arch _ '/filelist' %]
-<th><a href="[% make_url(download_url) | uri %]">[% arch %]</a></th>
-[% '<td>' _ version _ '</td>' IF versions.multiple %]
-<td class="size">[% pkgsize %] kB</td><td class="size">[% instsize %] kB</td>
+[% download_url = pkg _ '/' _ d.arch _ '/download'
+ filelist_url = pkg _ '/' _ d.arch _ '/filelist' %]
+<th><a href="[% make_url(download_url) | uri %]">[% d.arch %]</a>
+[%- SET a = d.archive; IF mirrors.$a.unofficial_port %] <strong>(unofficial port)</strong>[% END %]</th>
+[% vnorm = d.version.replace( '\+b\d+$', '' ); vlatest = version.replace( '\+b\d+$', '' );
+ vup = vnorm.replace( '-[^-]+$', '' ); vuplatest = vlatest.replace( '-[^-]+$', '' );
+ IF vnorm == vlatest;
+ version_class = 'vcurrent';
+ ELSIF vup == vuplatest;
+ version_class = 'volder';
+ ELSE;
+ version_class = 'vold';
+ END %]
+[% "<td class='$version_class'>$d.version</td>" IF versions.multiple %]
+<td class="size">[% d.pkgsize %] kB</td><td class="size">[% d.instsize %] kB</td>
<td>
-[% IF contents_avail %]
+[% IF d.contents_avail %]
[<a href="[% make_url(filelist_url) | uri %]">list of files</a>]
[% ELSE %]
no current information
[%- END %]
[% END %]
+<script type="text/javascript">init_tab_list("ptablist")</script>
+