Moved minor nav into util file and implemented
Moved minor nav into util file and implemented

--- a/ckanext/ga_report/controller.py
+++ b/ckanext/ga_report/controller.py
@@ -1,5 +1,7 @@
+import re
 import logging
 import operator
+import collections
 from ckan.lib.base import BaseController, c, render, request, response, abort
 
 import sqlalchemy
@@ -30,9 +32,10 @@
     def csv(self, month):
         import csv
 
-        entries = model.Session.query(GA_Stat).\
-            filter(GA_Stat.period_name==month).\
-            order_by('GA_Stat.stat_name, GA_Stat.key').all()
+        q = model.Session.query(GA_Stat)
+        if month != 'all':
+            q = q.filter(GA_Stat.period_name==month)
+        entries = q.order_by('GA_Stat.period_name, GA_Stat.stat_name, GA_Stat.key').all()
 
         response.headers['Content-Type'] = "text/csv; charset=utf-8"
 
@@ -52,26 +55,46 @@
         c.months = _month_details(GA_Stat)
 
         # Work out which month to show, based on query params of the first item
-        c.month = request.params.get('month', c.months[0][0] if c.months else '')
-        c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month])
-
-        entries = model.Session.query(GA_Stat).\
-            filter(GA_Stat.stat_name=='Totals').\
-            filter(GA_Stat.period_name==c.month).\
-            order_by('ga_stat.key').all()
-
-        c.global_totals = []
-        for e in entries:
-            val = e.value
-            if e.key in ['Average time on site', 'Pages per visit', 'Percent new visits']:
-                val =  "%.2f" % round(float(e.value), 2)
-                if e.key == 'Average time on site':
+        c.month_desc = 'all time'
+        c.month = request.params.get('month', '')
+        if c.month:
+            c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month])
+
+        q = model.Session.query(GA_Stat).\
+            filter(GA_Stat.stat_name=='Totals')
+        if c.month:
+            q = q.filter(GA_Stat.period_name==c.month)
+        entries = q.order_by('ga_stat.key').all()
+
+        def clean_key(key, val):
+            if key in ['Average time on site', 'Pages per visit', 'Percent new visits']:
+                val =  "%.2f" % round(float(val), 2)
+                if key == 'Average time on site':
                     mins, secs = divmod(float(val), 60)
                     hours, mins = divmod(mins, 60)
                     val = '%02d:%02d:%02d (%s seconds) ' % (hours, mins, secs, val)
-                e.key = '%s *' % e.key
-            c.global_totals.append((e.key, val))
-
+                key = '%s *' % key
+            if key in ['Bounces', 'Total pageviews']:
+                val = int(val)
+            return key, val
+
+        c.global_totals = []
+        if c.month:
+            for e in entries:
+                key, val = clean_key(e.key, e.value)
+                c.global_totals.append((key, val))
+        else:
+            d = collections.defaultdict(list)
+            for e in entries:
+                d[e.key].append(float(e.value))
+            for k, v in d.iteritems():
+                if k in ['Bounces', 'Total pageviews']:
+                    v = sum(v)
+                else:
+                    v = float(sum(v))/len(v)
+                key, val = clean_key(k,v)
+                c.global_totals.append((key, val))
+                c.global_totals = sorted(c.global_totals, key=operator.itemgetter(0))
 
         keys = {
             'Browser versions': 'browsers',
@@ -81,12 +104,45 @@
             'Country': 'country'
         }
 
+        browser_version_re = re.compile("(.*)\((.*)\)")
         for k, v in keys.iteritems():
-            entries = model.Session.query(GA_Stat).\
-                filter(GA_Stat.stat_name==k).\
-                filter(GA_Stat.period_name==c.month).\
-                order_by('ga_stat.value::int desc').all()
-            setattr(c, v, [(s.key, s.value) for s in entries ])
+
+            def clean_field(key):
+                if k != 'Browser versions':
+                    return key
+                m = browser_version_re.match(key)
+                browser = m.groups()[0].strip()
+                ver = m.groups()[1]
+                parts = ver.split('.')
+                if len(parts) > 1:
+                    if parts[1][0] == '0':
+                        ver = parts[0]
+                    else:
+                        ver = "%s.%s" % (parts[0],parts[1])
+                if browser in ['Safari','Android Browser']:  # Special case complex version nums
+                    ver = parts[0]
+                    if len(ver) > 2:
+                        ver = "%s%sX" % (ver[0], ver[1])
+
+                return "%s (%s)" % (browser, ver,)
+
+            q = model.Session.query(GA_Stat).\
+                filter(GA_Stat.stat_name==k)
+            if c.month:
+                entries = []
+                q = q.filter(GA_Stat.period_name==c.month).\
+                          order_by('ga_stat.value::int desc')
+
+            d = collections.defaultdict(int)
+            for e in q.all():
+                d[clean_field(e.key)] += int(e.value)
+            entries = []
+            for key, val in d.iteritems():
+                entries.append((key,val,))
+            entries = sorted(entries, key=operator.itemgetter(1), reverse=True)
+
+            setattr(c, v, [(k,v) for k,v in entries ])
+
 
 
         return render('ga_report/site/index.html')

--- /dev/null
+++ b/ckanext/ga_report/templates/ga_report/ga_util.html
@@ -1,1 +1,37 @@
+<html
+  xmlns="http://www.w3.org/1999/xhtml"
+  xmlns:i18n="http://genshi.edgewall.org/i18n"
+  xmlns:py="http://genshi.edgewall.org/"
+  xmlns:xi="http://www.w3.org/2001/XInclude"
+  py:strip=""
+  >
 
+ <table py:def="publisher_list(groups)" class="groups">
+   <py:for each="group,title in groups">
+   <tr>
+     <td><a href="/publisher/${group.name}">${title}</a></td>
+   </tr>
+   </py:for>
+ </table>
+
+
+<div py:def="usage_nav(active_name,publisher)" id="minornavigation">
+    <div id="minornavigation-bg-left">
+    <div id="minornavigation-bg-right">
+        <ul class="nav nav-pills">
+        <li py:attrs="{'class': 'active' if active_name=='Site-wide' else None}"><a py:attrs="{'class': 'active' if active_name=='Site-wide' else None}"  href="${h.url_for(controller='ckanext.ga_report.controller:GaReport',action='index')}"><img src="/images/icons/page_white_gear.png" height="16px" width="16px" alt="None" class="inline-icon "/> Site-wide</a></li>
+        <li py:attrs="{'class': 'active' if active_name=='Publishers' else None}">
+                <a py:attrs="{'class': 'active' if active_name=='Publishers' else None}"  href="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport',action='index')}"><img src="/images/icons/page_white_gear.png" height="16px" width="16px" alt="None" class="inline-icon "/> Publishers</a>
+        </li>
+        <li py:if="publisher" class="active">
+                <a class="active"  href="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport',action='read', id=publisher.name)}"><img src="/images/icons/page_white_gear.png" height="16px" width="16px" alt="None" class="inline-icon "/>${publisher.title}</a>
+        </li>
+
+        </ul>
+    </div>
+    </div>
+</div>
+
+
+</html>
+

--- a/ckanext/ga_report/templates/ga_report/publisher/index.html
+++ b/ckanext/ga_report/templates/ga_report/publisher/index.html
@@ -2,19 +2,35 @@
   xmlns:i18n="http://genshi.edgewall.org/i18n"
   xmlns:xi="http://www.w3.org/2001/XInclude"
   py:strip="">
+
+  <xi:include href="../ga_util.html" />
 
   <py:def function="page_title">Publisher Analytics for ${g.site_title}</py:def>
 
   <py:match path="primarysidebar">
     <li class="widget-container boxed widget_text">
       <h4>Publishers</h4>
-      <p>The table shows the top 20 publishers as recorded by page views of datasets owned by that publisher, and the number of visits to each publisher's home page.</p>
+      <p>
+          Dataset views records the number of times a specific dataset page has been viewed. Visits records the number of unique site visits.
+      </p>
+      <p>
+          Note: this data does not include API calls.
+      </p>
+    </li>
+    <li class="widget-container boxed widget_text">
+      <h4>Download</h4>
+      <p><center>
+          <a class="btn button" href="${h.url_for(controller='ckanext.ga_report.controller:GaReport',action='csv',month=c.month or 'all')}">Download as CSV</a></center>
+      </p>
     </li>
   </py:match>
 
+
   <div py:match="content">
-      <h1>Publisher Analytics</h1>
-      <h2>The top 20 publishers of ${c.month_desc}</h2>
+      <h1>Site Usage</h1>
+
+      ${usage_nav('Publishers', None)}
+
 
       <form class="form-inline" action="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport',action='index')}" method="get">
           <div class="controls">
@@ -62,5 +78,3 @@
 </html>
 
 
-
-

--- a/ckanext/ga_report/templates/ga_report/publisher/read.html
+++ b/ckanext/ga_report/templates/ga_report/publisher/read.html
@@ -3,29 +3,34 @@
   xmlns:xi="http://www.w3.org/2001/XInclude"
   py:strip="">
 
+  <xi:include href="../ga_util.html" />
+
   <py:def function="page_title">Analytics for ${g.site_title}</py:def>
 
- <py:match path="primarysidebar">
+  <py:match path="primarysidebar">
+    <li class="widget-container boxed widget_text">
+      <h4>Publishers</h4>
+      <p>
+          Dataset views records the number of times a specific dataset page has been viewed. Visits records the number of unique site visits.
+      </p>
+      <p>
+          Note: this data does not include API calls.
+      </p>
+    </li>
 
     <li class="widget-container boxed widget_text">
-      <h4>${c.publisher.title}</h4>
-      <p>
-          The table shows the top 20 most viewed datasets belonging to ${c.publisher.title}.
+      <h4>Download</h4>
+      <p><center>
+          <a class="btn button" href="${h.url_for(controller='ckanext.ga_report.controller:GaReport',action='csv',month=c.month or 'all')}">Download as CSV</a></center>
       </p>
-      <p>
-          As well as showing the number of views for ${c.month_desc}, it will also show the
-          number of visitors that viewed each dataset.
-      </p>
-       <p>The dataset list page for <a href="${h.url_for(controller='ckanext.dgu.controllers.publisher:PublisherController', action='read', id=c.publisher.name)}">${c.publisher.title}</a> was viewed ${c.publisher_page_views} times during the selected time period</p>
-       <p>View the <a href="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport', action='index')}">publishers</a> leaderboard</p>
     </li>
   </py:match>
 
+
   <div py:match="content">
-      <h1>Analytics for ${c.publisher.title}</h1>
+      <h1>Site Usage</h1>
 
-      <h2>Top 20 most viewed datasets of ${c.month_desc}</h2>
-      <p><em>Note: this data does not include API calls</em></p>
+      ${usage_nav(c.publisher.title, c.publisher)}
 
       <form class="form-inline" action="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport',action='read',id=c.publisher.name)}" method="get">
           <div class="controls">

--- a/ckanext/ga_report/templates/ga_report/site/index.html
+++ b/ckanext/ga_report/templates/ga_report/site/index.html
@@ -3,26 +3,36 @@
   xmlns:xi="http://www.w3.org/2001/XInclude"
   py:strip="">
 
-  <py:def function="page_title">Site analytics</py:def>
+  <xi:include href="../ga_util.html" />
+
+  <py:def function="page_title">Site usage</py:def>
 
   <py:match path="primarysidebar">
     <li class="widget-container boxed widget_text">
-      <h4>Statistics</h4>
-        <p>It is possible to <a href="${h.url_for(controller='ckanext.ga_report.controller:GaReport',action='csv',month=c.month)}">export the analytics data</a> as a CSV file, which contains all of the information for ${c.month_desc}</p>
+      <h4>Site-wide</h4>
+      <p>
+          Note: this data does not include API calls and some values have been rounded up to 2 decimal places.  Where there are a large number of browser versions they have been grouped together.
+      </p>
     </li>
     <li class="widget-container boxed widget_text">
-        <h4>Publisher statistics</h4>
-        <p>You can view statistics about specific publishers at the <a href="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport',action='index')}">Publisher Analytics</a> page</p>
+      <h4>Download</h4>
+      <p><center>
+          <a class="btn button" href="${h.url_for(controller='ckanext.ga_report.controller:GaReport',action='csv',month=c.month or 'all')}">Download as CSV</a></center>
+      </p>
+    </li>
 
-    </li>
   </py:match>
 
   <div py:match="content">
-      <h1>Site statistics</h1>
+      <h1>Site Usage</h1>
+
+      ${usage_nav('Site-wide', None)}
 
       <form class="form-inline" action="${h.url_for(controller='ckanext.ga_report.controller:GaReport',action='index')}" method="get">
           <div class="controls">
           <select name="month">
+                <option value='' py:attrs="{'selected': 'selected' if not c.month else None}">All time</option>
+
               <py:for each="val,desc in c.months">
                 <option value='${val}' py:attrs="{'selected': 'selected' if c.month == val else None}">${desc}</option>
               </py:for>
@@ -54,8 +64,6 @@
                     </tr>
                 </py:for>
                </table>
-
-              <p>* Values are rounded up to 2 decimal places.</p>
         </div>
         <div class="tab-pane" id="browsers">
              <table class="table table-condensed table-bordered table-striped">