import logging import urllib import os from genshi.filters import Transformer from genshi import HTML from genshi.core import START, TEXT from genshi.filters.transform import INSIDE from pylons import config from ckan.plugins import implements, SingletonPlugin from ckan.plugins import IGenshiStreamFilter, IConfigurable, IRoutes from ckan.plugins import IConfigurer from gasnippet import gacode from commands import DEFAULT_RESOURCE_URL_TAG import dbutil log = logging.getLogger('ckanext.googleanalytics') class GoogleAnalyticsException(Exception): pass class GoogleAnalyticsPlugin(SingletonPlugin): implements(IConfigurable, inherit=True) implements(IGenshiStreamFilter, inherit=True) implements(IRoutes, inherit=True) implements(IConfigurer, inherit=True) def configure(self, config): self.config = config log.info("Loading Google Analytics plugin...") if (not 'googleanalytics.id' in config): msg = "Missing googleanalytics.id in config" raise GoogleAnalyticsException(msg) def filter(self, stream): log.info("Inserting GA code into template") ga_id = self.config['googleanalytics.id'] code = HTML(gacode % ga_id) stream = stream | Transformer('head').append(code) resource_url = config.get('googleanalytics.resource_prefix', DEFAULT_RESOURCE_URL_TAG) # add download tracking link def js_attr(name, event): attrs = event[1][1] link = '%s%s' % (resource_url, urllib.quote(attrs.get('href'))) js = "javascript: _gaq.push(['_trackPageview', '%s']);" % link return js # add some stats def download_adder(stream): download_html = ' (%s downloads)' count = None for mark, (kind, data, pos) in stream: if mark and kind == START: href = data[1].get('href') count = dbutil.get_resource_visits_for_url(href) if count and kind == TEXT and mark == INSIDE: yield mark, (kind, data + download_html % count, pos) else: yield mark, (kind, data, pos) # perform the stream transform stream = stream | Transformer( '//div[@id="package"]//td/a')\ .apply(download_adder).attr('onclick', js_attr) return stream def after_map(self, map): map.connect('analytics', '/analytics/package/top', controller='ckanext.googleanalytics.controller:GAController', action='view') return map def update_config(self, config): here = os.path.dirname(__file__) rootdir = os.path.dirname(os.path.dirname(here)) template_dir = os.path.join(rootdir, 'ckanext', 'googleanalytics', 'templates') config['extra_template_paths'] = ','.join([template_dir, config.get('extra_template_paths', '')])