[Debtags-commits] [svn] r1452 - central-database/branches/alioth/webfrontend

Enrico Zini enrico at costa.debian.org
Mon Oct 31 13:21:16 UTC 2005


Author: enrico
Date: Mon Oct 31 13:21:16 2005
New Revision: 1452

Added:
   central-database/branches/alioth/webfrontend/Navigation.pm
      - copied, changed from r1450, central-database/branches/alioth/webfrontend/index.cgi
Modified:
   central-database/branches/alioth/webfrontend/Engine.pm
   central-database/branches/alioth/webfrontend/browsetemplate.html
   central-database/branches/alioth/webfrontend/index.cgi
Log:
Output starts being about right.


Modified: central-database/branches/alioth/webfrontend/Engine.pm
==============================================================================
--- central-database/branches/alioth/webfrontend/Engine.pm	(original)
+++ central-database/branches/alioth/webfrontend/Engine.pm	Mon Oct 31 13:21:16 2005
@@ -86,7 +86,7 @@
 sub hasTag ($@)
 {
 	my $self = shift;
-	my %tags = map { $_ => 1 } @{$db->{pkgs}{$self->name}{tags}};
+	my %tags = map { $_->{name} => 1 } @{$db->{pkgs}{$self->name}{tags}};
 	for my $t (@_)
 	{
 		return undef if not exists $tags{$t->name()};
@@ -360,11 +360,11 @@
 
 	if (my @tags = @{$parms->{tags}})
 	{
-#		&main::msg("Tags search (%s)\n", join(', ', @tags));
+#		&main::msg("Tags search (%s)\n", join(', ',map{$_->name} @tags));
         # Use the last tag as the beginning of the search, because it is usually
 		# the one with the least matches
 		my $t = $tags[$#tags];
-#		&main::msg("Tag used: %s with %d packages.\n", $t->{name}, scalar(@{$t->{packages}}));
+#		&main::msg("Tag used: %s with %d packages.\n", $t->name, scalar($t->pkgs));
 		return grep { matchPackage($parms, $_) } $t->pkgs();
 	} else {
 #		&main::msg("Search all\n");

Copied: central-database/branches/alioth/webfrontend/Navigation.pm (from r1450, central-database/branches/alioth/webfrontend/index.cgi)
==============================================================================
--- central-database/branches/alioth/webfrontend/index.cgi	(original)
+++ central-database/branches/alioth/webfrontend/Navigation.pm	Mon Oct 31 13:21:16 2005
@@ -1,20 +1,7 @@
-#!/usr/bin/perl -w
-
-#
-# WARNING:
-#
-# This is not the cleanest code, and it really needs a rewrite
-# Use at your own risk!
-#
+package Navigation;
 
 use strict;
 use warnings;
-use English;
-use CGI qw/:standard/;
-use HTML::Template;
-use URI::Escape;
-#use Cache::FileCache;
-#use Storable qw(freeze thaw);
 use Engine;
 
 ##
@@ -22,22 +9,26 @@
 ##
 
 #my $release="unstable";
-my $packages_limit = 15; # always show when below this
-my $subgroup_limit = 3; # don't make smaller subgroups
+our $packages_min = 10; # aggregate subgroups when less than this
+our $packages_max = 25; # try not to show more than this
+our $subgroup_limit = 3; # don't make smaller subgroups
 #my $useless_limit=0.6; # don't put everything into one subgroup.
 
+
 ##
-## Generic functions
+## Navigation structures
 ##
 
-my $log;
-# Log a message
-sub msg ($@)
-{
-	my ($format, @list) = @_;
-	$log .= sprintf($format, @list);
-	printf STDERR $format, @list;
-}
+# Packages we should display
+our @pkgs;
+
+# Packages displayed in subgroups
+our @subpkgs;
+
+
+##
+## Generic functions
+##
 
 # Returns the facet name for a tag
 sub facet ($) { return (split('::', $_[0]))[0] or 'legacy'; }
@@ -52,315 +43,68 @@
 
 
 ##
-## Startup
-##
-
-# Open database connection
-Engine::openDB();
-
-# Load the template file
-my $template = HTML::Template->new(
-	filename => 'browsetemplate.html',
-	die_on_bad_params => 0)
-|| die "Could not open template";
-
-# Parse input values
-my (@sel_tags, @sel_words);
-
-for my $par (param())
-{
-#	msg "Testing: %s\n", $par;
-	if ($par =~ /^facet-/)
-	{
-		my $tag = param($par);
-		next if $tag eq ':NONE:';
-#		msg "Found: %s->%s\n", $par, $tag;
-		push @sel_tags, $tag if ($tag =~ /^[a-z0-9\-:]+$/);
-	}
-	elsif ($par eq 'tags')
-	{
-		my $seltags = param($par);
-#		msg "Found: %s->%s\n", $par, $seltags;
-		if ($seltags && $seltags =~ m/([a-z0-9\-:.,]+)/)
-		{
-			push @sel_tags, split(/,/, $1);
-#		} else {
-#			$packages_limit = 0;
-#			$subgroup_limit = 0;
-		}
-	}
-	elsif ($par eq 'words')
-	{
-		my $selwords = param($par);
-#		msg "Found: %s->%s\n", $par, $selwords;
-		if ($selwords && $selwords =~ m/([a-z0-9\-:.,]+)/)
-		{
-			@sel_words = split(/\s+/, $1);
-		}
-	}
-}
-
-# Only take input tags once, and validate them
-{
-	my %tags = map { $_ => 1 } @sel_tags;
-	@sel_tags = Engine::tag(sort keys %tags);
-}
-
-#msg "Tags: %s\n", join(', ', map { $_->name } @sel_tags);
-
-
-##
 ## Select packages and build navigation
 ##
 
-# Packages we should display
-my @pkgs;
-
-# Packages displayed in subgroups
-my @subpkgs;
-
-# Package selection
-if (@sel_tags or @sel_words)
+sub build (\@\@)
 {
-	# Packages by tagset
-	my %ts;
-
-	# Current tagset
-	my $curts = join(',', sort map{$_->name} @sel_tags);
+	my ($sel_tags, $sel_words) = @_;
 
-	# Packages that have exactly the current tagset
-	my @curpkgs;
-
-	my %sub;
-	for my $p (Engine::findPackages({tags => \@sel_tags, words => \@sel_words}))
+	# Basic package selection
+	if (@$sel_tags or @$sel_words)
 	{
-		next if not $p->tags();
+		# Packages by tagset
+		my %ts;
 
-		# Compute tagset statistics
-		my $ts = join(',', sort map{$_->name} $p->tags);
-		# Store packages by tagset
-		push(@{$ts{$ts}}, $p) if $ts ne $curts;
-
-		if ($ts eq $curts) {
-			push @curpkgs, $p
-		} else {
-			$sub{$p->name} = 1;
-		}
-	}
+		# Current tagset
+		my $curts = join(',', sort map{$_->name} @$sel_tags);
 
-	# Add more packages if:
-	#  - there are less then $packages_limit packages to display
-	#  - there are subgroups of less than $subgroup_limit
+		# Packages that have exactly the current tagset
+		my @curpkgs;
 
-	@pkgs = @curpkgs;
-	for my $pkgs ( sort { scalar(@$a) <=> scalar(@$b) } values %ts )
-	{
-		last if @pkgs > $packages_limit && @$pkgs > $subgroup_limit;
-		for my $p (@$pkgs)
+		my %sub;
+		for my $p (Engine::findPackages({tags => $sel_tags, words => $sel_words}))
 		{
-			push @pkgs, $p;
-			delete $sub{$p->name};
-		}
-	}
+			next if not $p->tags();
 
-	@subpkgs = Engine::package(keys %sub);
-} else {
-	@subpkgs = grep { scalar($_->tags()) } Engine::packages();
-}
-
-##
-## Building statistics for packages in subgroups
-##
-
-msg "SP %d\n", scalar(@subpkgs);
-
-# Compute tag statistics
-my %tag_counts;
-for my $p (@subpkgs)
-{
-	foreach my $t (map { $_->name() } $p->tags())
-	{
-		$tag_counts{$t} += 1;
-	}
-}
-
-msg "KTC %d\n", scalar(keys %tag_counts);
-
-# Select the child tags
-my %seen = map { $_->name => 1 } @sel_tags;
-
-msg "SEEN %d\n", scalar(keys %seen);
-
-my @tag_newtags = Engine::tag(grep { not exists $seen{$_} } keys %tag_counts);
-
-msg "TNT %d\n", scalar(@tag_newtags);
-
-##
-## Output results
-##
-
-## Build HTML::Template data structures
-
-# Currently selected tags
-my %seltags_perfacet;
-my @ht_seltags;
-for (my $i = 0; $i < @sel_tags; $i++)
-{
-	my $t = $sel_tags[$i];
-	my @othertags = map { $_->name } @sel_tags;
-	splice(@othertags, $i, 1);
-	my $url ="?tags=".uri_escape(join(",", at othertags)); 
-	
-	push @{$seltags_perfacet{$t->facet()->name()}}, {
-		TAG => $t->name(),
-		DESC => $t->sdesc(),
-		COUNT => $tag_counts{$t->name()},
-		URL => $url
-	};
-
-	push @ht_seltags, {
-		TAG => $t->name(),
-		DESC => $t->sdesc(),
-		COUNT => $tag_counts{$t->name()},
-		URL => $url
-	};
-}
-
-# Further selectable tags in the navigation part
-my $cur_fac;
-my @ht_newfacets;
-foreach my $t (sort { $a->name cmp $b->name } @tag_newtags, @sel_tags)
-{
-	my $f = $t->facet();
-	if (not defined $cur_fac or $cur_fac ne $f->name())
-	{
-		push @ht_newfacets, {
-			NAME => $f->name(),
-			DESC => $f->sdesc(),
-			COUNT => 0,
-			SELTAGS => exists $seltags_perfacet{$f->name()} ? $seltags_perfacet{$f->name()} : [],
-			TAGS => []
-		};
-		$cur_fac = $f->name();
-	}
-	next if $seen{$t};
-	$ht_newfacets[$#ht_newfacets]{COUNT} += $tag_counts{$t->name()};
-	push @{$ht_newfacets[$#ht_newfacets]{TAGS}}, {
-		TAG => $t->name(),
-		DESC => $t->sdesc(),
-		COUNT => $tag_counts{$t->name()},
-		URL => "?tags=".uri_escape(join(",", map { $_->name } @sel_tags, $t))
-	};
-}
-sub bystats ($$)
-{
-	my ($a, $b) = @_;
-	return @{$b->{SELTAGS}} <=> @{$a->{SELTAGS}}
-		if @{$b->{SELTAGS}} != @{$a->{SELTAGS}};
-	return @{$b->{TAGS}} <=> @{$a->{TAGS}}
-		if @{$b->{TAGS}} != @{$a->{TAGS}};
-	return $a->{DESC} cmp $b->{DESC};
-	
-}
- at ht_newfacets = sort bystats @ht_newfacets;
-
-# Packages in the current view
-my @ht_pkgs;
-my @ht_subpkgs;
-sub bytagset ($$)
-{
-	my ($a, $b) = @_;
-	my @atags = sort map { $_->name } $a->tags;
-	my @btags = sort map { $_->name } $b->tags;
-
-	# Smallest tagsets first
-	return scalar(@atags) <=> scalar(@btags) if (scalar(@atags) != scalar(@btags));
-
-	for my $i (0 .. $#atags)
-	{
-		return $atags[$i] cmp $btags[$i] if $atags[$i] ne $btags[$i];
-	}
-	return 0;
-}
-
-# Packages in subgroups
-my $count = 0;
-my $groups = 0;
-my $last_sec = 0;
-my $lastsection = '';
-foreach my $pkg (sort bytagset @pkgs)
-{
-	my @tags = sort { $a->name() cmp $b->name() } grep { !$seen{$_->name()} } $pkg->tags();
-	my $tags = join(',', @tags);
+			# Compute tagset statistics
+			my $ts = join(',', sort map{$_->name} $p->tags);
+			# Store packages by tagset
+			push(@{$ts{$ts}}, $p) if $ts ne $curts;
+
+			if ($ts eq $curts) {
+				push @curpkgs, $p
+			} else {
+				$sub{$p->name} = 1;
+			}
+		}
 
-	my %data;
-	if ($tags eq '')
-	{
-		$data{PACKAGE} = $pkg->name();
-		$data{DESC} = $pkg->sdesc();
-		$data{URL} = "edit.cgi?package=".uri_escape($pkg->name()).
-						"&tags=".uri_escape(join(',', map{$_->name()} @sel_tags)),
-		
-		push @ht_pkgs, \%data;
-		next;
-	}
+		# Add more packages if:
+		#  - there are less then $packages_limit packages to display
+		#  - there are subgroups of less than $subgroup_limit
 
-	++$count;
-	if ($lastsection ne $tags)
-	{
-		# We are at a tagset change
-		++$groups;
-		$data{SECTION} =
-			[ map { NAME=>$_->sdesc() },
-				sort { $a->sdesc cmp $b->sdesc }
-					grep { !$seen{$_->name} } @tags ];
-
-		# Initialize with current position, we'll subtract it from the start of
-		# next section when it happens
-		$data{COUNT} = $count;
-		if ($count != 1)
+		@pkgs = @curpkgs;
+		if (@pkgs < $packages_min)
 		{
-			$ht_subpkgs[$#ht_subpkgs]{LAST} = 1;
-			$ht_subpkgs[$last_sec]{COUNT} = $count - $last_sec - 1;
-			$last_sec = $count - 1;
+			for my $pkgs ( sort { scalar(@$a) <=> scalar(@$b) } values %ts )
+			{
+				#last if @$pkgs > $subgroup_limit;
+				for my $p (@$pkgs)
+				{
+					push @pkgs, $p;
+					delete $sub{$p->name};
+				}
+				last if @pkgs > $packages_max;
+			}
 		}
-		$lastsection = $tags;
+
+		@subpkgs = Engine::package(keys %sub);
+	} else {
+		@subpkgs = grep { scalar($_->tags()) } Engine::packages();
 	}
-	$data{PACKAGE} = $pkg->name();
-	$data{DESC} = $pkg->sdesc();
-	$data{URL} = "edit.cgi?package=".uri_escape($pkg->name()).
-					"&tags=".uri_escape(join(',', map{$_->name()} @sel_tags)),
 
-	push @ht_subpkgs, \%data;
+	# Rearrange subgroups
 }
-$ht_subpkgs[$last_sec]{LAST} = 1;
-$ht_subpkgs[$last_sec]{COUNT} = $count - $last_sec;
-
-# Fill in the template
-$template->param(HAVETAGS => \@ht_seltags);
-$template->param(NEWFACETS => \@ht_newfacets);
-$template->param(NUMNEWFACETS => scalar(@ht_newfacets));
-$template->param(NUMNEWTAGS => scalar(@tag_newtags));
-$template->param(NUMSELTAGS => scalar(@sel_tags));
-$template->param(NUMSELTAGS_TXT => scalar(@sel_tags) == 1 ? "There is one tag" : "There are ".scalar(@sel_tags)." tags");
-$template->param(NUMGROUPS => $groups);
-$template->param(NUMPACKAGES => scalar(@pkgs));
-$template->param(CURPACKAGES => scalar(@ht_pkgs));
-$template->param(SUBPACKAGES => scalar(@ht_subpkgs));
-$template->param(TOTPACKAGES => scalar(@pkgs) + scalar(@subpkgs));
-$template->param(PACKAGES => \@ht_pkgs);
-$template->param(SPACKAGES => \@ht_subpkgs);
-$template->param(CURTAGS => join(',', map{$_->name} @sel_tags));
-$template->param(CURWORDS => join(' ', at sel_words));
-if ($log)
-{
-	$log =~ s/\n/<br>/g;
-	$template->param(LOG => $log);
-}
-
-# Finally, output
-print "Content-Type: text/html\n\n";
-print $template->output();
 
-exit 0;
+1;
 # vim:set ts=4 sw=4:

Modified: central-database/branches/alioth/webfrontend/browsetemplate.html
==============================================================================
--- central-database/branches/alioth/webfrontend/browsetemplate.html	(original)
+++ central-database/branches/alioth/webfrontend/browsetemplate.html	Mon Oct 31 13:21:16 2005
@@ -32,105 +32,90 @@
   </div>
 
   <div id="subgroups">
-    <tmpl_if name="NEWFACETS">
-      <div class="intro">
-	<tmpl_if name="NUMNEWTAGS">
-	  <p><tmpl_var name="NUMSELTAGS_TXT"> currently selected and 
-	     <tmpl_var name="NUMNEWTAGS"> tags in
-	     <tmpl_var name="NUMNEWFACETS"> subgroups available to further
-	     refine the search.</p>
-	<tmpl_else>
-	  <p><tmpl_var name="NUMSELTAGS_TXT"> currently selected.</p>
-	</tmpl_if>
-      </div>
-      <div id="facets">
-      <tmpl_loop name="NEWFACETS">
-        <div class="facet">
-          <div class="facet-title">
-	    <tmpl_var name="DESC"> (<tmpl_var name="COUNT">):
-	  </div>
-          <div class="facet-body">
-	    <ul>
-            <tmpl_loop name="SELTAGS">
-              <li><tmpl_var name="DESC"> (<tmpl_var name="COUNT">) <a href='<tmpl_var name="URL">'>[remove]</a></li>
-            </tmpl_loop>
-	    <tmpl_if name="TAGS">
-            <li><select name="facet-<tmpl_var name="NAME">" onChange='this.form.submit()'>
-	      <option value=":NONE:">Add one
-              <tmpl_loop name="TAGS">
-                <option value='<tmpl_var name="TAG">'><tmpl_var name="DESC">
-              </tmpl_loop>
-            </select></li>
-	    </tmpl_if>
-	    </ul>
-          </div>
-	</div>
-      </tmpl_loop>
-      <div style="clear: both"></div>
-      </div>
-    <tmpl_else>
-      <div class="intro">
+    <div class="intro">
+      <p><tmpl_var name="FACET_INTRO"></p>
+    </div>
+      <!--div class="intro">
 	<p>There is no further refining and all matching packages are listed
 	   below.</p>
+      </div-->
+    <tmpl_if name="FACETS">
+      <div id="facets">
+      <tmpl_loop name="FACETS">
+      <div class="facet">
+        <div class="facet-title">
+          <tmpl_var name="SDESC"> (<tmpl_var name="COUNT">):
+        </div>
+        <div class="facet-body">
+          <ul>
+          <tmpl_loop name="SEEN">
+            <li>
+              <tmpl_var name="SDESC"> (<tmpl_var name="COUNT">)
+              <a href='<tmpl_var name="REMURL">'>[remove]</a>
+            </li>
+          </tmpl_loop>
+          <tmpl_if name="TAGS">
+          <li><select name="facet-<tmpl_var name="NAME">" onChange='this.form.submit()'>
+            <option value=":NONE:">Add one
+            <tmpl_loop name="TAGS">
+              <option value='<tmpl_var name="NAME">'><tmpl_var name="SDESC">
+            </tmpl_loop>
+          </select></li>
+          </tmpl_if>
+          </ul>
+        </div>
       </div>
+      </tmpl_loop>
     </tmpl_if>
+    <div style="clear: both"></div>
+    </div>
   </div>
-  
+
   <div id="packages">
-    <TMPL_UNLESS NAME="NUMPACKAGES">
-      <div class="intro">
-        <p>No Packages shown. All packages can be found in the subcategories.</p>
+    <div class="intro">
+      <p><tmpl_var name="PKGS_INTRO"></p>
+    </div>
+  
+    <tmpl_if name="CURPKGS">
+      <div id="curpkgs">
+        <tmpl_loop name="CURPKGS">
+          <a class="pkg" href='<tmpl_var name="URL">'><tmpl_var name="NAME"></a>
+          - <tmpl_var name="SDESC"><br />
+        </tmpl_loop>
       </div>
-    <TMPL_ELSE>
-      <tmpl_iF name="CURPACKAGES">
-        <div class="intro">
-          <p><b><TMPL_VAR NAME="CURPACKAGES">/<TMPL_VAR NAME="TOTPACKAGES"></b> Packages shown from this group.</p>
-        </div>
-        <div id="curpkgs">
-          <tmpl_loop name="PACKAGES">
-            <a class="pkg" href="<tmpl_var name="URL">"><tmpl_var name="PACKAGE"></a>
-            - <tmpl_var name="DESC"><br />
-          </tmpl_loop>
-        </div>
-      <tmpl_else>
-        <div class="intro">
-          <p>There are no packages shown from this group; some packages from minor categories are displayed below.</p>
-        </div>
-      </tmpl_if>
+    </tmpl_if>
 
-      <div class="intro">
-        <p><b><TMPL_VAR NAME="SUBPACKAGES">/<TMPL_VAR NAME="TOTPACKAGES"></b> Packages shown from minor subgroups.</p>
-      </div>
+    <tmpl_if name="SUBPKGS">
       <table class="pkglist">
-        <tmpl_loop name="SPACKAGES">
-	<tmpl_if SECTION>
-	  <tr>
-	    <td class="left">
-	      <div class="pkggroup">
-	      <tmpl_loop name="SECTION">
+        <tmpl_loop name="SUBPKGS">
+        <tmpl_if SECTION>
+          <tr>
+            <td class="left">
+              <div class="pkggroup">
+              <tmpl_loop name="SECTION">
                 <tmpl_var name="NAME"><br />
-	      </tmpl_loop>
-	      </div>
-	    </td>
-	    <td class="right">
-	</tmpl_if>
-	  <a class="pkg" href="<tmpl_var name="URL">"><tmpl_var name="PACKAGE"></a>
-	  - <tmpl_var name="DESC"><br />
-	<tmpl_if LAST>
-	    </td>
-	  </tr>
-	</tmpl_if>
+              </tmpl_loop>
+              </div>
+            </td>
+            <td class="right">
+        </tmpl_if>
+          <a class="pkg" href="<tmpl_var name="URL">"><tmpl_var name="NAME"></a>
+          - <tmpl_var name="SDESC"><br />
+        <tmpl_if LAST>
+            </td>
+          </tr>
+        </tmpl_if>
         </tmpl_loop>
-	<tr>
-	  <td class='lastleft'>
-	    <tmpl_var name="NUMGROUPS"> groups.
-	  </td>
-	  <td class='lastright'>
-	    <tmpl_var name="NUMPACKAGES"> packages.
-	  </td>
-	</tr>
+        <!--tr>
+          <td class='lastleft'>
+            <tmpl_var name="NUMGROUPS"> groups.
+          </td>
+          <td class='lastright'>
+            <tmpl_var name="NUMPACKAGES"> packages.
+          </td>
+        </tr-->
       </table>
-    </TMPL_UNLESS>
+    </tmpl_if>
   </div>
 
   </form>

Modified: central-database/branches/alioth/webfrontend/index.cgi
==============================================================================
--- central-database/branches/alioth/webfrontend/index.cgi	(original)
+++ central-database/branches/alioth/webfrontend/index.cgi	Mon Oct 31 13:21:16 2005
@@ -13,18 +13,15 @@
 use CGI qw/:standard/;
 use HTML::Template;
 use URI::Escape;
-#use Cache::FileCache;
-#use Storable qw(freeze thaw);
 use Engine;
+use Navigation;
 
 ##
 ## Configuration options
 ##
 
 #my $release="unstable";
-my $packages_limit = 15; # always show when below this
-my $subgroup_limit = 3; # don't make smaller subgroups
-#my $useless_limit=0.6; # don't put everything into one subgroup.
+
 
 ##
 ## Generic functions
@@ -110,163 +107,98 @@
 
 
 ##
-## Select packages and build navigation
+## Build navigation
 ##
 
-# Packages we should display
-my @pkgs;
-
-# Packages displayed in subgroups
-my @subpkgs;
-
-# Package selection
-if (@sel_tags or @sel_words)
-{
-	# Packages by tagset
-	my %ts;
-
-	# Current tagset
-	my $curts = join(',', sort map{$_->name} @sel_tags);
-
-	# Packages that have exactly the current tagset
-	my @curpkgs;
-
-	my %sub;
-	for my $p (Engine::findPackages({tags => \@sel_tags, words => \@sel_words}))
-	{
-		next if not $p->tags();
-
-		# Compute tagset statistics
-		my $ts = join(',', sort map{$_->name} $p->tags);
-		# Store packages by tagset
-		push(@{$ts{$ts}}, $p) if $ts ne $curts;
+Navigation::build(@sel_tags, @sel_words);
 
-		if ($ts eq $curts) {
-			push @curpkgs, $p
-		} else {
-			$sub{$p->name} = 1;
-		}
-	}
-
-	# Add more packages if:
-	#  - there are less then $packages_limit packages to display
-	#  - there are subgroups of less than $subgroup_limit
-
-	@pkgs = @curpkgs;
-	for my $pkgs ( sort { scalar(@$a) <=> scalar(@$b) } values %ts )
-	{
-		last if @pkgs > $packages_limit && @$pkgs > $subgroup_limit;
-		for my $p (@$pkgs)
-		{
-			push @pkgs, $p;
-			delete $sub{$p->name};
-		}
-	}
-
-	@subpkgs = Engine::package(keys %sub);
-} else {
-	@subpkgs = grep { scalar($_->tags()) } Engine::packages();
-}
 
 ##
-## Building statistics for packages in subgroups
+## Build structures for HTML::Template
 ##
 
-msg "SP %d\n", scalar(@subpkgs);
+my @ht_facets;
+my @ht_curpkgs;
+my @ht_subpkgs;
+
 
 # Compute tag statistics
+my %facet_counts;
 my %tag_counts;
-for my $p (@subpkgs)
+for my $p (@Navigation::pkgs, @Navigation::subpkgs)
 {
-	foreach my $t (map { $_->name() } $p->tags())
+	foreach my $t ($p->tags())
 	{
-		$tag_counts{$t} += 1;
+		$tag_counts{$t->name} += 1;
+		$facet_counts{$t->facet->name} += 1;
 	}
 }
 
-msg "KTC %d\n", scalar(keys %tag_counts);
-
 # Select the child tags
 my %seen = map { $_->name => 1 } @sel_tags;
 
-msg "SEEN %d\n", scalar(keys %seen);
-
-my @tag_newtags = Engine::tag(grep { not exists $seen{$_} } keys %tag_counts);
-
-msg "TNT %d\n", scalar(@tag_newtags);
-
-##
-## Output results
-##
-
-## Build HTML::Template data structures
-
-# Currently selected tags
-my %seltags_perfacet;
-my @ht_seltags;
-for (my $i = 0; $i < @sel_tags; $i++)
-{
-	my $t = $sel_tags[$i];
-	my @othertags = map { $_->name } @sel_tags;
-	splice(@othertags, $i, 1);
-	my $url ="?tags=".uri_escape(join(",", at othertags)); 
-	
-	push @{$seltags_perfacet{$t->facet()->name()}}, {
-		TAG => $t->name(),
-		DESC => $t->sdesc(),
-		COUNT => $tag_counts{$t->name()},
-		URL => $url
-	};
-
-	push @ht_seltags, {
-		TAG => $t->name(),
-		DESC => $t->sdesc(),
-		COUNT => $tag_counts{$t->name()},
-		URL => $url
-	};
-}
-
-# Further selectable tags in the navigation part
-my $cur_fac;
-my @ht_newfacets;
-foreach my $t (sort { $a->name cmp $b->name } @tag_newtags, @sel_tags)
-{
-	my $f = $t->facet();
-	if (not defined $cur_fac or $cur_fac ne $f->name())
+# Facets
+my $count_unselected = 0;
+my $count_subpkg = scalar(@Navigation::subpkgs);
+foreach my $f (Engine::facet(keys %facet_counts))
+{
+	my @seen_tags;
+	my @tags;
+	foreach my $t ($f->tags())
 	{
-		push @ht_newfacets, {
-			NAME => $f->name(),
-			DESC => $f->sdesc(),
-			COUNT => 0,
-			SELTAGS => exists $seltags_perfacet{$f->name()} ? $seltags_perfacet{$f->name()} : [],
-			TAGS => []
-		};
-		$cur_fac = $f->name();
+		# Skip the empty tags
+		next if not $tag_counts{$t->name};
+
+		if (exists $seen{$t->name})
+		{
+			push @seen_tags, {
+				NAME => $t->name,
+				SDESC => $t->sdesc,
+				LDESC => $t->ldesc,
+				COUNT => $tag_counts{$t->name},
+				REMURL => 
+					"?tags=".uri_escape(join(",", map { $_->name } grep { $_ != $t } @sel_tags)), 
+			};
+		} else {
+			++$count_unselected;
+			if ($count_subpkg) {
+				push @tags, {
+					NAME => $t->name,
+					SDESC => $t->sdesc,
+					LDESC => $t->ldesc,
+					COUNT => $tag_counts{$t->name},
+				};
+			}
+		}
+		
 	}
-	next if $seen{$t};
-	$ht_newfacets[$#ht_newfacets]{COUNT} += $tag_counts{$t->name()};
-	push @{$ht_newfacets[$#ht_newfacets]{TAGS}}, {
-		TAG => $t->name(),
-		DESC => $t->sdesc(),
-		COUNT => $tag_counts{$t->name()},
-		URL => "?tags=".uri_escape(join(",", map { $_->name } @sel_tags, $t))
-	};
+	push @ht_facets, {
+		NAME => $f->name,
+		SDESC => $f->sdesc,
+		LDESC => $f->ldesc,
+		SEEN => \@seen_tags,
+		TAGS => \@tags,
+		COUNT => $facet_counts{$f->name},
+		SELCOUNT => scalar(@seen_tags),
+		UNSCOUNT => scalar(@tags),
+		TAGCOUNT => scalar(@seen_tags) + scalar(@tags),
+	} if scalar(@seen_tags) or scalar(@tags);
 }
 sub bystats ($$)
 {
 	my ($a, $b) = @_;
-	return @{$b->{SELTAGS}} <=> @{$a->{SELTAGS}}
-		if @{$b->{SELTAGS}} != @{$a->{SELTAGS}};
-	return @{$b->{TAGS}} <=> @{$a->{TAGS}}
-		if @{$b->{TAGS}} != @{$a->{TAGS}};
-	return $a->{DESC} cmp $b->{DESC};
+	return $b->{SELCOUNT} <=> $a->{SELCOUNT}
+		if $b->{SELCOUNT} !=  $a->{SELCOUNT};
+	return $b->{TAGCOUNT} <=> $a->{TAGCOUNT}
+		if $b->{TAGCOUNT} !=  $a->{TAGCOUNT};
+	return $a->{SDESC} cmp $b->{SDESC};
 	
 }
- at ht_newfacets = sort bystats @ht_newfacets;
+ at ht_facets = sort bystats @ht_facets;
 
-# Packages in the current view
-my @ht_pkgs;
-my @ht_subpkgs;
+# Package groups
+
+# Sort packages by their tagset
 sub bytagset ($$)
 {
 	my ($a, $b) = @_;
@@ -284,74 +216,143 @@
 }
 
 # Packages in subgroups
-my $count = 0;
-my $groups = 0;
-my $last_sec = 0;
-my $lastsection = '';
-foreach my $pkg (sort bytagset @pkgs)
+my $subgroup_count= 0;
+my $last_sec_start = 0;
+my $lastts = '';
+foreach my $p (sort bytagset @Navigation::pkgs)
 {
-	my @tags = sort { $a->name() cmp $b->name() } grep { !$seen{$_->name()} } $pkg->tags();
-	my $tags = join(',', @tags);
+	my @tags = sort { $a->name() cmp $b->name() } grep { !$seen{$_->name()} } $p->tags();
 
-	my %data;
-	if ($tags eq '')
+	if (! @tags)
 	{
-		$data{PACKAGE} = $pkg->name();
-		$data{DESC} = $pkg->sdesc();
-		$data{URL} = "edit.cgi?package=".uri_escape($pkg->name()).
+		# This is a package really in the current group
+		push @ht_curpkgs, {
+			NAME	=> $p->name(),
+			SDESC	=> $p->sdesc(),
+			LDESC	=> $p->ldesc(),
+			URL		=> "edit.cgi?package=".uri_escape($p->name()).
 						"&tags=".uri_escape(join(',', map{$_->name()} @sel_tags)),
-		
-		push @ht_pkgs, \%data;
-		next;
-	}
+		};
+	} else {
+		# This is a package pulled from a subgroup
+		my %data;
 
-	++$count;
-	if ($lastsection ne $tags)
-	{
-		# We are at a tagset change
-		++$groups;
-		$data{SECTION} =
-			[ map { NAME=>$_->sdesc() },
-				sort { $a->sdesc cmp $b->sdesc }
-					grep { !$seen{$_->name} } @tags ];
-
-		# Initialize with current position, we'll subtract it from the start of
-		# next section when it happens
-		$data{COUNT} = $count;
-		if ($count != 1)
+		my $ts = join(',', @tags);
+		if ($ts ne $lastts)
 		{
-			$ht_subpkgs[$#ht_subpkgs]{LAST} = 1;
-			$ht_subpkgs[$last_sec]{COUNT} = $count - $last_sec - 1;
-			$last_sec = $count - 1;
+			# We are at a tagset change
+			++$subgroup_count;
+
+			$data{SECTION} =
+				[ map { NAME=>$_->sdesc() },
+					sort { $a->sdesc cmp $b->sdesc }
+						grep { !$seen{$_->name} } @tags ];
+
+			# Initialize with current position, we'll subtract it from the start of
+			# next section when it happens
+			if (@ht_subpkgs)
+			{
+				$ht_subpkgs[$#ht_subpkgs]{LAST} = 1;
+				$ht_subpkgs[$last_sec_start]{COUNT} = @ht_subpkgs - $last_sec_start;
+				$last_sec_start = @ht_subpkgs;
+			}
+
+			$lastts = $ts;
 		}
-		$lastsection = $tags;
-	}
-	$data{PACKAGE} = $pkg->name();
-	$data{DESC} = $pkg->sdesc();
-	$data{URL} = "edit.cgi?package=".uri_escape($pkg->name()).
-					"&tags=".uri_escape(join(',', map{$_->name()} @sel_tags)),
+		$data{NAME} = $p->name();
+		$data{SDESC} = $p->sdesc();
+		$data{LDESC} = $p->ldesc();
+		$data{URL} = "edit.cgi?package=".uri_escape($p->name()).
+						"&tags=".uri_escape(join(',', map{$_->name()} @sel_tags)),
 
-	push @ht_subpkgs, \%data;
+		push @ht_subpkgs, \%data;
+	}
+}
+if (@ht_subpkgs)
+{
+	$ht_subpkgs[$#ht_subpkgs]->{LAST} = 1;
+	$ht_subpkgs[$last_sec_start]{COUNT} = @ht_subpkgs - $last_sec_start;
 }
-$ht_subpkgs[$last_sec]{LAST} = 1;
-$ht_subpkgs[$last_sec]{COUNT} = $count - $last_sec;
+
+#msg "%d facets, %d pkgs, %d curpkgs, %d subpkgs\n", scalar(@ht_facets), scalar(@Navigation::pkgs), scalar(@ht_curpkgs), scalar @ht_subpkgs;
 
 # Fill in the template
-$template->param(HAVETAGS => \@ht_seltags);
-$template->param(NEWFACETS => \@ht_newfacets);
-$template->param(NUMNEWFACETS => scalar(@ht_newfacets));
-$template->param(NUMNEWTAGS => scalar(@tag_newtags));
-$template->param(NUMSELTAGS => scalar(@sel_tags));
-$template->param(NUMSELTAGS_TXT => scalar(@sel_tags) == 1 ? "There is one tag" : "There are ".scalar(@sel_tags)." tags");
-$template->param(NUMGROUPS => $groups);
-$template->param(NUMPACKAGES => scalar(@pkgs));
-$template->param(CURPACKAGES => scalar(@ht_pkgs));
-$template->param(SUBPACKAGES => scalar(@ht_subpkgs));
-$template->param(TOTPACKAGES => scalar(@pkgs) + scalar(@subpkgs));
-$template->param(PACKAGES => \@ht_pkgs);
-$template->param(SPACKAGES => \@ht_subpkgs);
+
 $template->param(CURTAGS => join(',', map{$_->name} @sel_tags));
 $template->param(CURWORDS => join(' ', at sel_words));
+
+$template->param(FACETS => \@ht_facets);
+$template->param(CURPKGS => \@ht_curpkgs);
+$template->param(SUBPKGS => \@ht_subpkgs);
+
+my $facet_intro;
+my $c = scalar(keys %tag_counts);
+if ($c == 0)
+{
+	$facet_intro = "There is <b>no</b> tag ";
+} elsif ($c == 1) {
+	$facet_intro = "There is <b>one</b> tag ";
+} else {
+	$facet_intro = "There are <b>$c</b> tags ";
+}
+if ($count_unselected == 0)
+{
+	$facet_intro .= "currently selected."
+} else {
+	$c = scalar keys %facet_counts;
+	if ($c == 1)
+	{
+		$facet_intro .= "in <b>one</b> facet. ";
+	} else {
+		$facet_intro .= sprintf "in <b>%d</b> facets. ", $c;
+	} 
+	$c = scalar(@sel_tags);	
+	if ($c == 0)
+	{
+		$facet_intro .= "<b>None</b> is currently selected.";
+	}
+	elsif ($c == 1)
+	{
+		$facet_intro .= "<b>One</b> is currently selected.";
+	} else {
+		$facet_intro .= sprintf "<b>%d</b> are currently selected.", $c;
+	} 
+}
+$template->param(FACET_INTRO => $facet_intro);
+
+my $curpkgs_intro;
+my $curpkgs_also;
+my $cur = scalar(@ht_curpkgs);
+my $sub = scalar(@ht_subpkgs);
+if ($cur == 0)
+{
+	$curpkgs_intro = "There is <b>no</b> package in this group.  ";
+	$curpkgs_also = '';
+} elsif ($cur == 1) {
+	$curpkgs_intro = "There is <b>one</b> package in this group.  ";
+	$curpkgs_also = ' also';
+} else {
+	$curpkgs_intro = "There are <b>$cur</b> packages in this group.  ";
+	$curpkgs_also = ' also';
+}
+if ($sub == 0)
+{
+	$curpkgs_intro .= "More packages can be found by further refining the selection."
+} elsif ($sub == 1) {
+	$curpkgs_intro .= "Packages from <b>one</b> subgroup are$curpkgs_also displayed below.";
+} else {
+	$curpkgs_intro .= "Packages from <b>$sub</b> subgroups are$curpkgs_also displayed below.";
+}
+$template->param(PKGS_INTRO => $curpkgs_intro);
+
+#$template->param(COUNT_SUBGROUPS => $subgroup_count);
+#$template->param(NUMGROUPS => $groups);
+#$template->param(NUMPACKAGES => scalar(@pkgs));
+#$template->param(CURPACKAGES => scalar(@ht_pkgs));
+#$template->param(SUBPACKAGES => scalar(@ht_subpkgs));
+#$template->param(TOTPACKAGES => scalar(@pkgs) + scalar(@subpkgs));
+#$template->param(PACKAGES => \@ht_pkgs);
+#$template->param(SPACKAGES => \@ht_subpkgs);
 if ($log)
 {
 	$log =~ s/\n/<br>/g;



More information about the Debtags-commits mailing list