From ddc4b974fe44832c696724d512fd9b935f5085df Mon Sep 17 00:00:00 2001
From: Dan McGee <dan@archlinux.org>
Date: Fri, 27 Aug 2010 17:05:59 -0500
Subject: Add a package group overview page

Signed-off-by: Dan McGee <dan@archlinux.org>
---
 packages/views.py              | 42 ++++++++++++++++++++++++++++++++++++++++--
 templates/packages/groups.html | 35 +++++++++++++++++++++++++++++++++++
 urls.py                        |  1 +
 3 files changed, 76 insertions(+), 2 deletions(-)
 create mode 100644 templates/packages/groups.html

diff --git a/packages/views.py b/packages/views.py
index 0a0d0afa..3caf5ec9 100644
--- a/packages/views.py
+++ b/packages/views.py
@@ -11,16 +11,17 @@ from django.contrib.admin.widgets import AdminDateWidget
 from django.views.decorators.cache import never_cache
 from django.views.decorators.vary import vary_on_headers
 from django.views.generic import list_detail
-from django.db.models import Q
+from django.db.models import Count, Q
 
 from datetime import datetime
+from operator import itemgetter
 import string
 
 from main.models import Package, PackageFile
 from main.models import Arch, Repo, Signoff
 from main.models import MirrorUrl
 from main.utils import make_choice
-from packages.models import PackageRelation
+from packages.models import PackageGroup, PackageRelation
 
 def opensearch(request):
     if request.is_secure():
@@ -84,6 +85,43 @@ def details(request, name='', repo='', arch=''):
         return HttpResponseRedirect("/packages/?arch=%s&repo=%s&q=%s" % (
             arch.lower(), repo.title(), name))
 
+def get_group_information():
+    raw_groups = PackageGroup.objects.values_list(
+            'name', 'pkg__arch__name').order_by('name').annotate(
+             cnt=Count('pkg'))
+    # now for post_processing. we need to seperate things out and add
+    # the count in for 'any' to all of the other architectures.
+    group_mapping = {}
+    for g in raw_groups:
+        arch_groups = group_mapping.setdefault(g[1], {})
+        arch_groups[g[0]] = {'name': g[0], 'arch': g[1], 'count': g[2]}
+
+    # we want to promote the count of 'any' packages in groups to the
+    # other architectures, and also add any 'any'-only groups
+    if 'any' in group_mapping:
+        any_groups = group_mapping['any']
+        del group_mapping['any']
+        for arch, arch_groups in group_mapping.iteritems():
+            for g in any_groups.itervalues():
+                if g['name'] in arch_groups:
+                    arch_groups[g['name']]['count'] += g['count']
+                else:
+                    new_g = g.copy()
+                    # override the arch to not be 'any'
+                    new_g['arch'] = arch
+                    arch_groups[g['name']] = new_g
+
+    # now transform it back into a sorted list
+    groups = []
+    for v in group_mapping.itervalues():
+        groups.extend(v.itervalues())
+    return sorted(groups, key=itemgetter('name', 'arch'))
+
+def groups(request):
+    groups = get_group_information()
+    return render_to_response('packages/groups.html',
+            RequestContext(request, {'groups': groups}))
+
 def group_details(request, arch, name):
     arch = get_object_or_404(Arch, name=arch)
     pkgs = Package.objects.filter(packagegroup__name=name)
diff --git a/templates/packages/groups.html b/templates/packages/groups.html
new file mode 100644
index 00000000..4bf12ac6
--- /dev/null
+++ b/templates/packages/groups.html
@@ -0,0 +1,35 @@
+{% extends "base.html" %}
+{% block title %}Arch Linux - Package Groups{% endblock %}
+{% block navbarclass %}anb-packages{% endblock %}
+
+{% block content %}
+<div class="box">
+    <h2>Package Groups Overview</h2>
+    <table class="results">
+        <thead>
+            <tr>
+                <th>Arch</th>
+                <th>Group Name</th>
+                <th>Package Count</th>
+            </tr>
+        </thead>
+        <tbody>
+            {% for grp in groups %}
+            <tr class="{% cycle 'odd' 'even' %}">
+                <td>{{ grp.arch }}</td>
+                <td><a href="/groups/{{ grp.arch }}/{{ grp.name }}/"
+                        title="Group details for {{ grp.name }}">{{ grp.name }}</a></td>
+                <td>{{ grp.count }} Packages</td>
+            </tr>
+            {% endfor %}
+        </tbody>
+    </table>
+</div>
+{% load cdn %}{% jquery %}
+<script type="text/javascript" src="/media/jquery.tablesorter.min.js"></script>
+<script type="text/javascript">
+$(document).ready(function() {
+    $(".results").tablesorter({widgets: ['zebra'], sortList: [[1,0], [0,0]]});
+});
+</script>
+{% endblock %}
diff --git a/urls.py b/urls.py
index 202efe53..7d7e363c 100644
--- a/urls.py
+++ b/urls.py
@@ -50,6 +50,7 @@ urlpatterns = patterns('',
     (r'^packages/(?P<repo>[A-z0-9\-]+)/(?P<arch>[A-z0-9]+)/(?P<name>[A-z0-9\-+.]+)/download/$',
         'packages.views.download'),
 
+    (r'^groups/$', 'packages.views.groups'),
     (r'^groups/(?P<arch>[A-z0-9]+)/(?P<name>[A-z0-9\-+.]+)/$',
         'packages.views.group_details'),
 
-- 
cgit v1.2.3-2-g168b