Initial Commit
Initial Commit

  # empty file needed for pylons to find templates in this directory
 
 Binary files /dev/null and b/ckanext/dga-stats/__init__.pyc differ
  import ckan.plugins as p
  from ckan.lib.base import BaseController, config
  import stats as stats_lib
  import ckan.lib.helpers as h
 
  class StatsController(BaseController):
 
  def index(self):
  c = p.toolkit.c
  stats = stats_lib.Stats()
  rev_stats = stats_lib.RevisionStats()
  c.top_rated_packages = stats.top_rated_packages()
  c.most_edited_packages = stats.most_edited_packages()
  c.largest_groups = stats.largest_groups()
  c.top_tags = stats.top_tags()
  c.top_package_owners = stats.top_package_owners()
  c.new_packages_by_week = rev_stats.get_by_week('new_packages')
  c.deleted_packages_by_week = rev_stats.get_by_week('deleted_packages')
  c.num_packages_by_week = rev_stats.get_num_packages_by_week()
  c.package_revisions_by_week = rev_stats.get_by_week('package_revisions')
 
  # Used in the legacy CKAN templates.
  c.packages_by_week = []
 
  # Used in new CKAN templates gives more control to the templates for formatting.
  c.raw_packages_by_week = []
  for week_date, num_packages, cumulative_num_packages in c.num_packages_by_week:
  c.packages_by_week.append('[new Date(%s), %s]' % (week_date.replace('-', ','), cumulative_num_packages))
  c.raw_packages_by_week.append({'date': h.date_str_to_datetime(week_date), 'total_packages': cumulative_num_packages})
 
  c.all_package_revisions = []
  c.raw_all_package_revisions = []
  for week_date, revs, num_revisions, cumulative_num_revisions in c.package_revisions_by_week:
  c.all_package_revisions.append('[new Date(%s), %s]' % (week_date.replace('-', ','), num_revisions))
  c.raw_all_package_revisions.append({'date': h.date_str_to_datetime(week_date), 'total_revisions': num_revisions})
 
  c.new_datasets = []
  c.raw_new_datasets = []
  for week_date, pkgs, num_packages, cumulative_num_packages in c.new_packages_by_week:
  c.new_datasets.append('[new Date(%s), %s]' % (week_date.replace('-', ','), num_packages))
  c.raw_new_datasets.append({'date': h.date_str_to_datetime(week_date), 'new_packages': num_packages})
 
  return p.toolkit.render('ckanext/stats/index.html')
 
  def leaderboard(self, id=None):
  c = p.toolkit.c
  c.solr_core_url = config.get('ckanext.stats.solr_core_url',
  'http://solr.okfn.org/solr/ckan')
  return p.toolkit.render('ckanext/stats/leaderboard.html')
 
 
  from logging import getLogger
 
  import ckan.plugins as p
 
  log = getLogger(__name__)
 
  class StatsPlugin(p.SingletonPlugin):
  '''Stats plugin.'''
 
  p.implements(p.IRoutes, inherit=True)
  p.implements(p.IConfigurer, inherit=True)
 
  def after_map(self, map):
  map.connect('stats', '/stats',
  controller='ckanext.stats.controller:StatsController',
  action='index')
  map.connect('stats_action', '/stats/{action}',
  controller='ckanext.stats.controller:StatsController')
  return map
 
  def update_config(self, config):
  templates = 'templates'
  if p.toolkit.asbool(config.get('ckan.legacy_templates', False)):
  templates = 'templates_legacy'
  p.toolkit.add_template_directory(config, templates)
  p.toolkit.add_public_directory(config, 'public')
  p.toolkit.add_resource('public/ckanext/stats', 'ckanext_stats')
 
 Binary files /dev/null and b/ckanext/dga-stats/plugin.pyc differ
  **.min.js
  **.min.css
 
  # this is a namespace package
  try:
  import pkg_resources
  pkg_resources.declare_namespace(__name__)
  except ImportError:
  import pkgutil
  __path__ = pkgutil.extend_path(__path__, __name__)
 
  # this is a namespace package
  try:
  import pkg_resources
  pkg_resources.declare_namespace(__name__)
  except ImportError:
  import pkgutil
  __path__ = pkgutil.extend_path(__path__, __name__)
 
  # this is a namespace package
  try:
  import pkg_resources
  pkg_resources.declare_namespace(__name__)
  except ImportError:
  import pkgutil
  __path__ = pkgutil.extend_path(__path__, __name__)
 
  jQuery(document).ready(function($) {
  $('form').submit(function(e) {
  e.preventDefault();
  attribute = $('#form-attribute').val();
  loadSolr(attribute);
  })
  // default! (also in html)
  loadSolr('tags');
 
  function loadSolr(attribute) {
  var url = solrCoreUrl + '/select?indent=on&wt=json&facet=true&rows=0&indent=true&facet.mincount=1&facet.limit=30&q=*:*&facet.field=' + attribute;
  function handleSolr(data) {
  var results = [];
  ourdata = data.facet_counts.facet_fields[attribute];
  var newrow = {};
  for (ii in ourdata) {
  if (ii % 2 == 0) {
  newrow.name = ourdata[ii];
  if (!newrow.name) {
  newrow.name = '[Not Specified]';
  }
  } else {
  newrow.count = ourdata[ii];
  results.push(newrow);
  newrow = {};
  }
  }
  display(results);
  }
 
  $.ajax({
  url: url,
  success: handleSolr,
  dataType: 'jsonp',
  jsonp: 'json.wrf'
  });
  }
 
  function display(results) {
  var list = $('#category-counts');
  list.html('');
  if (results.length == 0) {
  return
  }
  var maximum = results[0]['count'];
  for(ii in results) {
  maximum = Math.max(maximum, results[ii]['count']);
  }
 
  $.each(results, function(idx, row) {
  var newentry = $('<li></li>');
  newentry.append($('<a href="#">' + row['name'] + '</a>'));
  newentry.append($('<span class="count">' + row['count'] + '</a>'));
  var percent = 100 * row['count'] / maximum;
  newentry.append($('<span class="index" style="width: ' + percent + '%"></span>'));
  list.append(newentry);
  });
  }
  });
 
  .tab-content h2 {
  margin-bottom: 12px;
  }
 
  .js .tab-content {
  padding-top: 20px;
  padding-bottom: 20px;
  margin-top: 0;
  }
 
  .module-plot-canvas {
  display: block;
  width: 650px;
  height: 300px;
  margin: 20px 0;
  }
 
  <html>
  <head>
  <script type="text/javascript">
  var solrCoreUrl = 'http://solr.okfn.org/solr/ckan';
  </script>
  <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
  <script type="text/javascript" src="app.js"></script>
 
  <link type="text/css" rel="stylesheet" media="all" href="style.css" />
  </head>
  <body>
  <h1>CKAN Dataset Leaderboard</h1>
  <p>Choose a dataset attribute and find out which categories in that area have the most datasets. E.g. tags, groups, license, res_format, country.</p>
  <form>
  <label for="category">Choose area</label>
  <input type="text" value="tags" name="attribute" id="form-attribute" />
  <input type="submit" value="Dataset Counts &raquo;" name="submit" />
  </form>
 
  <div class="category-counts">
  <ul class="chartlist" id="category-counts">
  </ul>
  </div>
  </body>
  </html>
 
  /* A quick module for generating flot charts from an HTML table. Options can
  * be passed directly to flot using the data-module-* attributes. The tables
  * are currently expected to be marked up as follows:
  *
  * <table data-module="plot">
  * <thead>
  * <tr>
  * <th>X Axis</th>
  * <th>Series A Legend</th>
  * <th>Series B Legend</th>
  * </tr>
  * </thead>
  * <tbody>
  * <tr>
  * <th>X Value</th>
  * <td>Series A Y Value</td>
  * <td>Series B Y Value</td>
  * </tr>
  * ...
  * </tbody>
  * </table>
  *
  * Points are pulled out of the th/td elements using innerHTML or by looking
  * for a data-value attribute. This is useful when a more readable value
  * needs to be used in the elements contents (eg. dates). A data-type attribute
  * can also be applied to parse the value. Only data-type="date" is currently
  * supported and expects data-value to be a unix timestamp.
  */
  this.ckan.module('plot', function (jQuery, _) {
  return {
  /* Holds the jQuery.plot() object when created */
  graph: null,
 
  /* Holds the canvas container when created */
  canvas: null,
 
  /* Default options */
  options: {
  xaxis: {},
  yaxis: {},
  legend: {position: 'nw'},
  colors: ['#ffcc33', '#ff8844']
  },
 
  /* Sets up the canvas element and parses the table.
  *
  * Returns nothing.
  */
  initialize: function () {
  jQuery.proxyAll(this, /_on/);
 
  if (!this.el.is('table')) {
  throw new Error('CKAN module plot can only be called on table elements');
  }
 
  this.setupCanvas();
 
  // Because the canvas doesn't render correctly unless visible we must
  // listen for events that reveal the canvas and then try and re-render.
  // Currently the most common of these is the "shown" event triggered by
  // the tabs plugin.
  this.sandbox.body.on("shown", this._onShown);
  this.data = this.parseTable(this.el);
 
  this.draw();
  },
 
  /* Removes event handlers when the module is removed from the DOM.
  *
  * Returns nothing.
  */
  teardown: function () {
  this.sandbox.body.off("shown", this._onShown);
  },
 
  /* Creates the canvas wrapper and removes the table from the document.
  *
  * Returns nothing.
  */
  setupCanvas: function () {
  this.canvas = jQuery('<div class="module-plot-canvas">');
  this.el.replaceWith(this.canvas);
  },
 
  /* Attempts to draw the chart if the canvas is visible. If not visible the
  * graph does not render correctly. So we keep trying until it is.
  *
  * Examples
  *
  * module.draw();
  *
  * Returns nothing.
  */
  draw: function () {
  if (!this.drawn && this.canvas.is(':visible')) {
  this.graph = jQuery.plot(this.canvas, this.data, this.options);
  }
  },
 
  /* Parses an HTML table element to build the data array for the chart.
  * The thead element provides the axis and labels for the series. The
  * first column in the tbody is used for the x-axis and subsequent
  * columns are the series.
  *
  * table - A table element to parse.
  *
  * Examples
  *
  * module.parseTable(module.el);
  *
  * Returns data object suitable for use in jQuery.plot().
  */
  parseTable: function (table) {
  var data = [];
  var _this = this;
 
  var headings = table.find('thead tr:first th').map(function () {
  return this.innerHTML;
  });
 
  table.find('tbody tr').each(function (row) {
  var element = jQuery(this);
  var x = [];