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

  import re
import logging import logging
import operator import operator
  import collections
from ckan.lib.base import BaseController, c, render, request, response, abort from ckan.lib.base import BaseController, c, render, request, response, abort
   
import sqlalchemy import sqlalchemy
from sqlalchemy import func, cast, Integer from sqlalchemy import func, cast, Integer
import ckan.model as model import ckan.model as model
from ga_model import GA_Url, GA_Stat from ga_model import GA_Url, GA_Stat
   
log = logging.getLogger('ckanext.ga-report') log = logging.getLogger('ckanext.ga-report')
   
   
def _get_month_name(strdate): def _get_month_name(strdate):
import calendar import calendar
from time import strptime from time import strptime
d = strptime(strdate, '%Y-%m') d = strptime(strdate, '%Y-%m')
return '%s %s' % (calendar.month_name[d.tm_mon], d.tm_year) return '%s %s' % (calendar.month_name[d.tm_mon], d.tm_year)
   
   
def _month_details(cls): def _month_details(cls):
months = [] months = []
vals = model.Session.query(cls.period_name).distinct().all() vals = model.Session.query(cls.period_name).distinct().all()
for m in vals: for m in vals:
months.append( (m[0], _get_month_name(m[0]))) months.append( (m[0], _get_month_name(m[0])))
return sorted(months, key=operator.itemgetter(0), reverse=True) return sorted(months, key=operator.itemgetter(0), reverse=True)
   
   
class GaReport(BaseController): class GaReport(BaseController):
   
def csv(self, month): def csv(self, month):
import csv import csv
   
entries = model.Session.query(GA_Stat).\ q = model.Session.query(GA_Stat)
filter(GA_Stat.period_name==month).\ if month != 'all':
order_by('GA_Stat.stat_name, GA_Stat.key').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" response.headers['Content-Type'] = "text/csv; charset=utf-8"
   
writer = csv.writer(response) writer = csv.writer(response)
writer.writerow(["Period", "Statistic", "Key", "Value"]) writer.writerow(["Period", "Statistic", "Key", "Value"])
   
for entry in entries: for entry in entries:
writer.writerow([entry.period_name.encode('utf-8'), writer.writerow([entry.period_name.encode('utf-8'),
entry.stat_name.encode('utf-8'), entry.stat_name.encode('utf-8'),
entry.key.encode('utf-8'), entry.key.encode('utf-8'),
entry.value.encode('utf-8')]) entry.value.encode('utf-8')])
   
def index(self): def index(self):
   
# Get the month details by fetching distinct values and determining the # Get the month details by fetching distinct values and determining the
# month names from the values. # month names from the values.
c.months = _month_details(GA_Stat) c.months = _month_details(GA_Stat)
   
# Work out which month to show, based on query params of the first item # 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 = 'all time'
c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month]) c.month = request.params.get('month', '')
  if c.month:
entries = model.Session.query(GA_Stat).\ c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month])
filter(GA_Stat.stat_name=='Totals').\  
filter(GA_Stat.period_name==c.month).\ q = model.Session.query(GA_Stat).\
order_by('ga_stat.key').all() filter(GA_Stat.stat_name=='Totals')
  if c.month:
c.global_totals = [] q = q.filter(GA_Stat.period_name==c.month)
for e in entries: entries = q.order_by('ga_stat.key').all()
val = e.value  
if e.key in ['Average time on site', 'Pages per visit', 'Percent new visits']: def clean_key(key, val):
val = "%.2f" % round(float(e.value), 2) if key in ['Average time on site', 'Pages per visit', 'Percent new visits']:
if e.key == 'Average time on site': val = "%.2f" % round(float(val), 2)
  if key == 'Average time on site':
mins, secs = divmod(float(val), 60) mins, secs = divmod(float(val), 60)
hours, mins = divmod(mins, 60) hours, mins = divmod(mins, 60)
val = '%02d:%02d:%02d (%s seconds) ' % (hours, mins, secs, val) val = '%02d:%02d:%02d (%s seconds) ' % (hours, mins, secs, val)
e.key = '%s *' % e.key key = '%s *' % key
c.global_totals.append((e.key, val)) 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 = { keys = {
'Browser versions': 'browsers', 'Browser versions': 'browsers',
'Operating Systems versions': 'os', 'Operating Systems versions': 'os',
'Social sources': 'social_networks', 'Social sources': 'social_networks',
'Languages': 'languages', 'Languages': 'languages',
'Country': 'country' 'Country': 'country'
} }
   
  browser_version_re = re.compile("(.*)\((.*)\)")
for k, v in keys.iteritems(): for k, v in keys.iteritems():
entries = model.Session.query(GA_Stat).\  
filter(GA_Stat.stat_name==k).\ def clean_field(key):
filter(GA_Stat.period_name==c.month).\ if k != 'Browser versions':
order_by('ga_stat.value::int desc').all() return key
setattr(c, v, [(s.key, s.value) for s in entries ]) 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') return render('ga_report/site/index.html')
   
   
class GaPublisherReport(BaseController): class GaPublisherReport(BaseController):
""" """
Displays the pageview and visit count for specific publishers based on Displays the pageview and visit count for specific publishers based on
the datasets associated with the publisher. the datasets associated with the publisher.
""" """
   
def index(self): def index(self):
   
# Get the month details by fetching distinct values and determining the # Get the month details by fetching distinct values and determining the
# month names from the values. # month names from the values.
c.months = _month_details(GA_Url) c.months = _month_details(GA_Url)
   
# Work out which month to show, based on query params of the first item # Work out which month to show, based on query params of the first item
c.month = request.params.get('month', '') c.month = request.params.get('month', '')
c.month_desc = 'all time' c.month_desc = 'all time'
if c.month: if c.month:
c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month]) c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month])
   
connection = model.Session.connection() connection = model.Session.connection()
q = """ q = """
select department_id, sum(pageviews::int) views, sum(visitors::int) visits select department_id, sum(pageviews::int) views, sum(visitors::int) visits
from ga_url from ga_url
where department_id <> ''""" where department_id <> ''"""
if c.month: if c.month:
q = q + """ q = q + """
and period_name=%s and period_name=%s
""" """
q = q + """ q = q + """
group by department_id order by views desc limit 20; group by department_id order by views desc limit 20;
""" """
   
# Add this back (before and period_name =%s) if you want to ignore publisher # Add this back (before and period_name =%s) if you want to ignore publisher
# homepage views # homepage views
# and not url like '/publisher/%%' # and not url like '/publisher/%%'
   
c.top_publishers = [] c.top_publishers = []
res = connection.execute(q, c.month) res = connection.execute(q, c.month)
   
for row in res: for row in res:
c.top_publishers.append((model.Group.get(row[0]), row[1], row[2])) c.top_publishers.append((model.Group.get(row[0]), row[1], row[2]))
   
return render('ga_report/publisher/index.html') return render('ga_report/publisher/index.html')
   
   
def read(self, id): def read(self, id):
count = 20 count = 20
   
c.publisher = model.Group.get(id) c.publisher = model.Group.get(id)
if not c.publisher: if not c.publisher:
abort(404, 'A publisher with that name could not be found') abort(404, 'A publisher with that name could not be found')
c.top_packages = [] # package, dataset_views in c.top_packages c.top_packages = [] # package, dataset_views in c.top_packages
   
# Get the month details by fetching distinct values and determining the # Get the month details by fetching distinct values and determining the
# month names from the values. # month names from the values.
c.months = _month_details(GA_Url) c.months = _month_details(GA_Url)
   
# Work out which month to show, based on query params of the first item # Work out which month to show, based on query params of the first item
c.month = request.params.get('month', '') c.month = request.params.get('month', '')
if not c.month: if not c.month:
c.month_desc = 'all time' c.month_desc = 'all time'
else: else:
c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month]) c.month_desc = ''.join([m[1] for m in c.months if m[0]==c.month])
   
c.publisher_page_views = 0 c.publisher_page_views = 0
q = model.Session.query(GA_Url).\ q = model.Session.query(GA_Url).\
filter(GA_Url.url=='/publisher/%s' % c.publisher.name) filter(GA_Url.url=='/publisher/%s' % c.publisher.name)
if c.month: if c.month:
entry = q.filter(GA_Url.period_name==c.month).first() entry = q.filter(GA_Url.period_name==c.month).first()
c.publisher_page_views = entry.pageviews if entry else 0 c.publisher_page_views = entry.pageviews if entry else 0
else: else:
for e in q.all(): for e in q.all():
c.publisher_page_views = c.publisher_page_views + int(e.pageviews) c.publisher_page_views = c.publisher_page_views + int(e.pageviews)
   
   
q = model.Session.query(GA_Url).\ q = model.Session.query(GA_Url).\
filter(GA_Url.department_id==c.publisher.name).\ filter(GA_Url.department_id==c.publisher.name).\
filter(GA_Url.url.like('/dataset/%')) filter(GA_Url.url.like('/dataset/%'))
if c.month: if c.month:
q = q.filter(GA_Url.period_name==c.month) q = q.filter(GA_Url.period_name==c.month)
q = q.order_by('ga_url.pageviews::int desc') q = q.order_by('ga_url.pageviews::int desc')
   
if c.month: if c.month:
for entry in q[:count]: for entry in q[:count]:
p = model.Package.get(entry.url[len('/dataset/'):]) p = model.Package.get(entry.url[len('/dataset/'):])
c.top_packages.append((p,entry.pageviews,entry.visitors)) c.top_packages.append((p,entry.pageviews,entry.visitors))
else: else:
ds = {} ds = {}
for entry in q.all(): for entry in q.all():
if len(ds) >= count: if len(ds) >= count:
break break
p = model.Package.get(entry.url[len('/dataset/'):]) p = model.Package.get(entry.url[len('/dataset/'):])
if not p in ds: if not p in ds:
ds[p] = {'views':0, 'visits': 0} ds[p] = {'views':0, 'visits': 0}
ds[p]['views'] = ds[p]['views'] + int(entry.pageviews) ds[p]['views'] = ds[p]['views'] + int(entry.pageviews)
ds[p]['visits'] = ds[p]['visits'] + int(entry.visitors) ds[p]['visits'] = ds[p]['visits'] + int(entry.visitors)
   
results = [] results = []
for k, v in ds.iteritems(): for k, v in ds.iteritems():
results.append((k,v['views'],v['visits'])) results.append((k,v['views'],v['visits']))
   
c.top_packages = sorted(results, key=operator.itemgetter(1), reverse=True) c.top_packages = sorted(results, key=operator.itemgetter(1), reverse=True)
   
return render('ga_report/publisher/read.html') return render('ga_report/publisher/read.html')
   
  <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>
 
<html xmlns:py="http://genshi.edgewall.org/" <html xmlns:py="http://genshi.edgewall.org/"
xmlns:i18n="http://genshi.edgewall.org/i18n" xmlns:i18n="http://genshi.edgewall.org/i18n"
xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xi="http://www.w3.org/2001/XInclude"
py:strip=""> py:strip="">
   
  <xi:include href="../ga_util.html" />
   
<py:def function="page_title">Publisher Analytics for ${g.site_title}</py:def> <py:def function="page_title">Publisher Analytics for ${g.site_title}</py:def>
   
<py:match path="primarysidebar"> <py:match path="primarysidebar">
<li class="widget-container boxed widget_text"> <li class="widget-container boxed widget_text">
<h4>Publishers</h4> <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> </li>
</py:match> </py:match>
   
   
<div py:match="content"> <div py:match="content">
<h1>Publisher Analytics</h1> <h1>Site Usage</h1>
<h2>The top 20 publishers of ${c.month_desc}</h2>  
  ${usage_nav('Publishers', None)}
   
   
<form class="form-inline" action="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport',action='index')}" method="get"> <form class="form-inline" action="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport',action='index')}" method="get">
<div class="controls"> <div class="controls">
<select name="month"> <select name="month">
<option value='' py:attrs="{'selected': 'selected' if not c.month else None}">All time</option> <option value='' py:attrs="{'selected': 'selected' if not c.month else None}">All time</option>
   
<py:for each="val,desc in c.months"> <py:for each="val,desc in c.months">
<option value='${val}' py:attrs="{'selected': 'selected' if c.month == val else None}">${desc}</option> <option value='${val}' py:attrs="{'selected': 'selected' if c.month == val else None}">${desc}</option>
</py:for> </py:for>
</select> </select>
<input class="btn button" type='submit' value="Update"/> <input class="btn button" type='submit' value="Update"/>
</div> </div>
</form> </form>
   
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<tr> <tr>
<th>Publisher</th> <th>Publisher</th>
<th>Dataset Views</th> <th>Dataset Views</th>
<th>Visits</th> <th>Visits</th>
</tr> </tr>
<py:for each="publisher, views, visits in c.top_publishers"> <py:for each="publisher, views, visits in c.top_publishers">
<tr> <tr>
<td>${h.link_to(publisher.title, h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport', action='read', id=publisher.name))} <td>${h.link_to(publisher.title, h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport', action='read', id=publisher.name))}
</td> </td>
<td>${views}</td> <td>${views}</td>
<td>${visits}</td> <td>${visits}</td>
</tr> </tr>
</py:for> </py:for>
</table> </table>
   
   
</div> </div>
   
<xi:include href="../../layout.html" /> <xi:include href="../../layout.html" />
   
<py:def function="optional_footer"> <py:def function="optional_footer">
<script type='text/javascript'> <script type='text/javascript'>
$('.nav-tabs li a').click(function (e) { $('.nav-tabs li a').click(function (e) {
e.preventDefault(); e.preventDefault();
$(this).tab('show'); $(this).tab('show');
}) })
</script> </script>
</py:def> </py:def>
   
</html> </html>
   
   
   
   
<html xmlns:py="http://genshi.edgewall.org/" <html xmlns:py="http://genshi.edgewall.org/"
xmlns:i18n="http://genshi.edgewall.org/i18n" xmlns:i18n="http://genshi.edgewall.org/i18n"
xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xi="http://www.w3.org/2001/XInclude"
py:strip=""> py:strip="">
   
  <xi:include href="../ga_util.html" />
   
<py:def function="page_title">Analytics for ${g.site_title}</py:def> <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"> <li class="widget-container boxed widget_text">
<h4>${c.publisher.title}</h4> <h4>Download</h4>
<p> <p><center>
The table shows the top 20 most viewed datasets belonging to ${c.publisher.title}. <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>
<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> </li>
</py:match> </py:match>
   
   
<div py:match="content"> <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> ${usage_nav(c.publisher.title, c.publisher)}
<p><em>Note: this data does not include API calls</em></p>  
   
<form class="form-inline" action="${h.url_for(controller='ckanext.ga_report.controller:GaPublisherReport',action='read',id=c.publisher.name)}" method="get"> <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"> <div class="controls">
<select name="month"> <select name="month">
<option value='' py:attrs="{'selected': 'selected' if not c.month else None}">All time</option> <option value='' py:attrs="{'selected': 'selected' if not c.month else None}">All time</option>
<py:for each="val,desc in c.months"> <py:for each="val,desc in c.months">
<option value='${val}' py:attrs="{'selected': 'selected' if c.month == val else None}">${desc}</option> <option value='${val}' py:attrs="{'selected': 'selected' if c.month == val else None}">${desc}</option>
</py:for> </py:for>
</select> </select>
<input class="btn button" type='submit' value="Update"/> <input class="btn button" type='submit' value="Update"/>
</div> </div>
</form> </form>
   
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<tr> <tr>
<th>Dataset</th> <th>Dataset</th>
<th>Views</th> <th>Views</th>
<th>Visits</th> <th>Visits</th>
</tr> </tr>
<py:for each="package, views, visits in c.top_packages"> <py:for each="package, views, visits in c.top_packages">
<tr> <tr>
<td>${h.link_to(package.title or package.name, h.url_for(controller='package', action='read', id=package.name))} <td>${h.link_to(package.title or package.name, h.url_for(controller='package', action='read', id=package.name))}
</td> </td>
<td>${views}</td> <td>${views}</td>
<td>${visits}</td> <td>${visits}</td>
</tr> </tr>
</py:for> </py:for>
</table> </table>
   
   
</div> </div>
   
<xi:include href="../../layout.html" /> <xi:include href="../../layout.html" />
</html> </html>
   
   
   
   
<html xmlns:py="http://genshi.edgewall.org/" <html xmlns:py="http://genshi.edgewall.org/"
xmlns:i18n="http://genshi.edgewall.org/i18n" xmlns:i18n="http://genshi.edgewall.org/i18n"
xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xi="http://www.w3.org/2001/XInclude"
py:strip=""> 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"> <py:match path="primarysidebar">
<li class="widget-container boxed widget_text"> <li class="widget-container boxed widget_text">
<h4>Statistics</h4> <h4>Site-wide</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> <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>
<li class="widget-container boxed widget_text"> <li class="widget-container boxed widget_text">
<h4>Publisher statistics</h4> <h4>Download</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> <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> </py:match>
   
<div py:match="content"> <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"> <form class="form-inline" action="${h.url_for(controller='ckanext.ga_report.controller:GaReport',action='index')}" method="get">
<div class="controls"> <div class="controls">
<select name="month"> <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"> <py:for each="val,desc in c.months">
<option value='${val}' py:attrs="{'selected': 'selected' if c.month == val else None}">${desc}</option> <option value='${val}' py:attrs="{'selected': 'selected' if c.month == val else None}">${desc}</option>
</py:for> </py:for>
</select> </select>
<input class="btn button" type='submit' value="Update"/> <input class="btn button" type='submit' value="Update"/>
</div> </div>
</form> </form>
   
<div class="tabbable"> <div class="tabbable">
<ul class="nav nav-tabs"> <ul class="nav nav-tabs">
<li class="active"><a href="#totals" data-toggle="tab">Totals</a></li> <li class="active"><a href="#totals" data-toggle="tab">Totals</a></li>
<li><a href="#browsers" data-toggle="tab">Browsers</a></li> <li><a href="#browsers" data-toggle="tab">Browsers</a></li>
<li><a href="#os" data-toggle="tab">Operating Systems</a></li> <li><a href="#os" data-toggle="tab">Operating Systems</a></li>
<li><a href="#social_networks" data-toggle="tab">Social Networks</a></li> <li><a href="#social_networks" data-toggle="tab">Social Networks</a></li>
<li><a href="#languages" data-toggle="tab">Languages</a></li> <li><a href="#languages" data-toggle="tab">Languages</a></li>
<li><a href="#country" data-toggle="tab">Country</a></li> <li><a href="#country" data-toggle="tab">Country</a></li>
</ul> </ul>
<div class="tab-content"> <div class="tab-content">
<div class="tab-pane active" id="totals"> <div class="tab-pane active" id="totals">
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Value</th> <th>Value</th>
</tr> </tr>
<py:for each="name, value in c.global_totals"> <py:for each="name, value in c.global_totals">
<tr> <tr>
<td>${name}</td> <td>${name}</td>
<td>${value}</td> <td>${value}</td>
</tr> </tr>
</py:for> </py:for>
</table> </table>
   
<p>* Values are rounded up to 2 decimal places.</p>  
</div> </div>
<div class="tab-pane" id="browsers"> <div class="tab-pane" id="browsers">
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Value</th> <th>Value</th>
</tr> </tr>
<py:for each="name, value in c.browsers"> <py:for each="name, value in c.browsers">
<tr> <tr>
<td>${name}</td> <td>${name}</td>
<td>${value}</td> <td>${value}</td>
</tr> </tr>
</py:for> </py:for>
</table> </table>
</div> </div>
<div class="tab-pane" id="os"> <div class="tab-pane" id="os">
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Value</th> <th>Value</th>
</tr> </tr>
<py:for each="name, value in c.os"> <py:for each="name, value in c.os">
<tr> <tr>
<td>${name}</td> <td>${name}</td>
<td>${value}</td> <td>${value}</td>
</tr> </tr>
</py:for> </py:for>
</table> </table>
</div> </div>
<div class="tab-pane" id="social_networks"> <div class="tab-pane" id="social_networks">
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Value</th> <th>Value</th>
</tr> </tr>
<py:for each="name, value in c.social_networks"> <py:for each="name, value in c.social_networks">
<tr> <tr>
<td>${name}</td> <td>${name}</td>
<td>${value}</td> <td>${value}</td>
</tr> </tr>
</py:for> </py:for>
</table> </table>
</div> </div>
<div class="tab-pane" id="languages"> <div class="tab-pane" id="languages">
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Value</th> <th>Value</th>
</tr> </tr>
<py:for each="name, value in c.languages"> <py:for each="name, value in c.languages">
<tr> <tr>
<td>${name}</td> <td>${name}</td>
<td>${value}</td> <td>${value}</td>
</tr> </tr>
</py:for> </py:for>
</table> </table>
</div> </div>
<div class="tab-pane" id="country"> <div class="tab-pane" id="country">
<table class="table table-condensed table-bordered table-striped"> <table class="table table-condensed table-bordered table-striped">
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Value</th> <th>Value</th>
</tr> </tr>
<py:for each="name, value in c.country"> <py:for each="name, value in c.country">
<tr> <tr>
<td>${name}</td> <td>${name}</td>
<td>${value}</td> <td>${value}</td>
</tr> </tr>
</py:for> </py:for>
</table> </table>
</div> </div>
   
   
</div> </div>
</div> </div>
   
   
   
</div> </div>
   
<xi:include href="../../layout.html" /> <xi:include href="../../layout.html" />
   
<py:def function="optional_footer"> <py:def function="optional_footer">
<script type='text/javascript'> <script type='text/javascript'>
$('.nav-tabs li a').click(function (e) { $('.nav-tabs li a').click(function (e) {
e.preventDefault(); e.preventDefault();
$(this).tab('show'); $(this).tab('show');
}) })
</script> </script>
</py:def> </py:def>
</html> </html>