From f67777c54709c83e65ef421bdb3191a11bbd027c Mon Sep 17 00:00:00 2001 From: Sergey Motornyuk Date: Mon, 9 Dec 2019 15:23:33 +0200 Subject: [PATCH] Add webassets / some clean-up --- README.rst | 30 +------- .../assets/googleanalytics_event_tracking.js | 17 +++++ ckanext/googleanalytics/assets/webassets.yml | 5 ++ .../googleanalytics_event_tracking.js | 16 ----- ckanext/googleanalytics/ga_auth.py | 11 ++- .../scripts/ckanext-googleanalytics.js | 72 ------------------- .../legacy_templates/summary.html | 53 -------------- ckanext/googleanalytics/plugin/__init__.py | 44 ++++++------ ckanext/googleanalytics/templates/base.html | 23 +++--- .../snippets/event_tracking_asset.html | 1 + .../snippets/event_tracking_resource.html | 1 + ckanext/googleanalytics/views.py | 28 ++++---- pyproject.toml | 3 + 13 files changed, 85 insertions(+), 219 deletions(-) create mode 100644 ckanext/googleanalytics/assets/googleanalytics_event_tracking.js create mode 100644 ckanext/googleanalytics/assets/webassets.yml delete mode 100644 ckanext/googleanalytics/fanstatic_library/googleanalytics_event_tracking.js delete mode 100644 ckanext/googleanalytics/legacy_public/scripts/ckanext-googleanalytics.js delete mode 100644 ckanext/googleanalytics/legacy_templates/summary.html create mode 100644 ckanext/googleanalytics/templates/googleanalytics/snippets/event_tracking_asset.html create mode 100644 ckanext/googleanalytics/templates/googleanalytics/snippets/event_tracking_resource.html create mode 100644 pyproject.toml diff --git a/README.rst b/README.rst index 4896519..6f97c99 100644 --- a/README.rst +++ b/README.rst @@ -26,28 +26,6 @@ Features ``ckanext.googleanalytics.plugin._post_analytics`` -* Adds Google Analytics Event Tracking to group links on the home page, - user profile links, editing and saving user profiles, etc. - - *Only if* ``googleanalytics.track_events = true`` *is in your CKAN ini file.* - - *CKAN 1.x only*. - -* Puts download stats into dataset pages, e.g. "[downloaded 4 times]". - - *CKAN 1.x only.* - -* Provides a ``/analytics/dataset/top`` page that shows the most popular - datasets and resources - - *CKAN 1.x only* - -CKAN 1.x Support ----------------- - -To use ckanext-googleanalytics with CKAN 1.x, make sure you have -``ckan.legacy_templates = true`` in your CKAN ini file. - Installation ------------ @@ -81,13 +59,7 @@ Installation (If there are other plugins activated, add this to the list. Each plugin should be separated with a space). -4. If you are using this plugin with a version of CKAN < 2.0 then you should - also put the following in your ini file:: - - ckan.legacy_templates = true - - -5. Finally, there are some optional configuration settings (shown here +4. Finally, there are some optional configuration settings (shown here with their default settings):: googleanalytics_resource_prefix = /downloads/ diff --git a/ckanext/googleanalytics/assets/googleanalytics_event_tracking.js b/ckanext/googleanalytics/assets/googleanalytics_event_tracking.js new file mode 100644 index 0000000..6b67fd2 --- /dev/null +++ b/ckanext/googleanalytics/assets/googleanalytics_event_tracking.js @@ -0,0 +1,17 @@ +// Add Google Analytics Event Tracking to resource download links. +this.ckan.module("google-analytics", function(jQuery, _) { + "use strict"; + return { + options: { + googleanalytics_resource_prefix: "" + }, + initialize: function() { + jQuery("a.resource-url-analytics").on("click", function() { + var resource_url = encodeURIComponent(jQuery(this).prop("href")); + if (resource_url) { + ga("send", "event", "Resource", "Download", resource_url); + } + }); + } + }; +}); diff --git a/ckanext/googleanalytics/assets/webassets.yml b/ckanext/googleanalytics/assets/webassets.yml new file mode 100644 index 0000000..a439628 --- /dev/null +++ b/ckanext/googleanalytics/assets/webassets.yml @@ -0,0 +1,5 @@ +event_tracking: + filters: rjsmin + output: ckanext-googleanalytics/event_tracking.js + contents: + - googleanalytics_event_tracking.js diff --git a/ckanext/googleanalytics/fanstatic_library/googleanalytics_event_tracking.js b/ckanext/googleanalytics/fanstatic_library/googleanalytics_event_tracking.js deleted file mode 100644 index 60bcb5c..0000000 --- a/ckanext/googleanalytics/fanstatic_library/googleanalytics_event_tracking.js +++ /dev/null @@ -1,16 +0,0 @@ -// Add Google Analytics Event Tracking to resource download links. -this.ckan.module('google-analytics', function(jQuery, _) { - return { - options: { - googleanalytics_resource_prefix: '' - }, - initialize: function() { - jQuery('a.resource-url-analytics').on('click', function() { - var resource_url = encodeURIComponent(jQuery(this).prop('href')); - if (resource_url) { - ga('send', 'event', 'Resource', 'Download', resource_url); - } - }); - } - } -}); diff --git a/ckanext/googleanalytics/ga_auth.py b/ckanext/googleanalytics/ga_auth.py index a958b1a..44bdc8f 100644 --- a/ckanext/googleanalytics/ga_auth.py +++ b/ckanext/googleanalytics/ga_auth.py @@ -2,7 +2,15 @@ import httplib2 from apiclient.discovery import build from oauth2client.service_account import ServiceAccountCredentials -from pylons import config +from ckan.exceptions import CkanVersionException +import ckan.plugins.toolkit as tk + +try: + tk.requires_ckan_version("2.9") +except CkanVersionException: + from pylons import config +else: + config = tk.config def _prepare_credentials(credentials_filename): @@ -43,7 +51,6 @@ def get_profile_id(service): if not accounts.get("items"): return None - accountName = config.get("googleanalytics.account") webPropertyId = config.get("googleanalytics.id") for acc in accounts.get("items"): diff --git a/ckanext/googleanalytics/legacy_public/scripts/ckanext-googleanalytics.js b/ckanext/googleanalytics/legacy_public/scripts/ckanext-googleanalytics.js deleted file mode 100644 index 8e9047d..0000000 --- a/ckanext/googleanalytics/legacy_public/scripts/ckanext-googleanalytics.js +++ /dev/null @@ -1,72 +0,0 @@ -(function ($) { - $(document).ready(function () { - // Google Analytics event tracking - - // group links on home page - $('body.home div.group a').click(function() { - _gaq.push(['_trackEvent', 'Home', 'Click: Group Link', $(this).attr('href')]); - }); - - // clicking on user name (go to profile) - $('div.account span.ckan-logged-in a').first().click(function() { - _gaq.push(['_trackEvent', 'User', 'Click: User Name', $(this).attr('href')]); - }); - - // In user profile, clicking on Edit Profile - $('body.user div#minornavigation a') - .filter(function(index) {return $(this).text() === "Edit Profile";}) - .click(function() { - _gaq.push(['_trackEvent', 'User', 'Click: Tab', 'Edit Profile']); - }); - - // Clicking Save Changes on Edit Profile page - $('body.user.edit input#save').click(function() { - _gaq.push(['_trackEvent', 'User', 'Click: Button', 'Save Profile Changes']); - }); - - // Clicking on any dataset link on User Profile page - $('body.user.read ul.datasets a').click(function() { - _gaq.push(['_trackEvent', 'User', 'Click: Dataset Link', $(this).attr('href')]); - }); - - // Compare Button on /dataset/history/X - $('body.package.history form#dataset-revisions input[name="diff"]').click(function() { - _gaq.push(['_trackEvent', 'Dataset', 'Click: Button', 'Compare History']); - }); - - // Tags on right hand sidebar of /dataset/X - $('body.package.read div#sidebar h3') - .filter(function(index) {return $(this).text().indexOf("Tags") != -1;}) - .next('ul') - .find('a') - .click(function() { - _gaq.push(['_trackEvent', 'Dataset', 'Click: Tag', $(this).attr('href')]); - }); - - // Any of the group links on /group - $('body.group.index table.groups a').click(function() { - _gaq.push(['_trackEvent', 'Group', 'Click: Group Link', $(this).attr('href')]); - }); - - // Clicking any of the right hand sidebar tags on /group/X - $('body.group.read div#sidebar h2') - .filter(function(index) {return $(this).text().indexOf("Tags") != -1;}) - .next('ul') - .find('a') - .click(function() { - _gaq.push(['_trackEvent', 'Group', 'Click: Tag', $(this).attr('href')]); - }); - - // Visiting /group/history/X - $('body.group div#minornavigation ul.nav a') - .filter(function(index) {return $(this).text().indexOf("History") != -1;}) - .click(function() { - _gaq.push(['_trackEvent', 'Group', 'Click: History Tab', $(this).attr('href')]); - }); - - // Compare Button on /group/history/X - $('body.group.history form#group-revisions input[name="diff"]').click(function() { - _gaq.push(['_trackEvent', 'Group', 'Click: Button', 'Compare History']); - }); - }); -}(jQuery)); diff --git a/ckanext/googleanalytics/legacy_templates/summary.html b/ckanext/googleanalytics/legacy_templates/summary.html deleted file mode 100644 index 3be593c..0000000 --- a/ckanext/googleanalytics/legacy_templates/summary.html +++ /dev/null @@ -1,53 +0,0 @@ - - - Analytics for ${g.site_title} - -
- -

Most viewed datasets

-

Note: this data does not include API calls

- - - - - - - - - - - - - - -
DatasetUnique views (last 14 days)Unique views (since recording started)
${h.link_to(package.title or package.name, h.url_for(controller='package', action='read', id=package.name))} - ${recent}${ever}
- -

Most downloaded resources

- - - - - - - - - - - - - -
ResourceDownloads (last 14 days)Downloads (since recording started)
${h.link_to(h.truncate(resource.description, length=50,whole_word=True) if resource.description else resource.format, h.url_for(controller='package',action='resource_read',id=resource.resource_group.package.id,resource_id=resource.id))}
- in ${h.link_to(resource.resource_group.package.title or resource.resource_group.package.name, h.url_for(controller='package', action='read', id=resource.resource_group.package.name))} -
${recent}${ever}
- -
- - - - - - diff --git a/ckanext/googleanalytics/plugin/__init__.py b/ckanext/googleanalytics/plugin/__init__.py index 0811c89..78bc0df 100644 --- a/ckanext/googleanalytics/plugin/__init__.py +++ b/ckanext/googleanalytics/plugin/__init__.py @@ -1,20 +1,27 @@ +# -*- coding: utf-8 -*- from __future__ import absolute_import + from future import standard_library standard_library.install_aliases() -from builtins import str -from builtins import range + +import urllib.parse import ast import logging -import ckanext.googleanalytics.commands as commands -import paste.deploy.converters as converters +import threading + +from builtins import str, range + +import requests + import ckan.lib.helpers as h import ckan.plugins as p import ckan.plugins.toolkit as tk -import urllib.parse + from ckan.exceptions import CkanVersionException -import threading -import requests + +import ckanext.googleanalytics.commands as commands + log = logging.getLogger(__name__) @@ -46,9 +53,7 @@ class AnalyticsPostThread(threading.Thread): log.debug("Sending API event to Google Analytics: " + data) # send analytics res = requests.post( - "http://www.google-analytics.com/collect", - data, - timeout=10, + "http://www.google-analytics.com/collect", data, timeout=10, ) # signals to queue job is done self.queue.task_done() @@ -101,22 +106,19 @@ class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin): "googleanalytics_resource_prefix" ] - self.show_downloads = converters.asbool( + self.show_downloads = tk.asbool( config.get("googleanalytics.show_downloads", True) ) - self.track_events = converters.asbool( + self.track_events = tk.asbool( config.get("googleanalytics.track_events", False) ) - self.enable_user_id = converters.asbool( + self.enable_user_id = tk.asbool( config.get("googleanalytics.enable_user_id", False) ) - if not converters.asbool(config.get("ckan.legacy_templates", "false")): - p.toolkit.add_resource( - "../fanstatic_library", "ckanext-googleanalytics" - ) + p.toolkit.add_resource("../assets", "ckanext-googleanalytics") - # spawn a pool of 5 threads, and pass them queue instance + # spawn a pool of 5 threads, and pass them queue instance for i in range(5): t = AnalyticsPostThread(self.analytics_queue) t.setDaemon(True) @@ -128,11 +130,7 @@ class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin): See IConfigurer. """ - if converters.asbool(config.get("ckan.legacy_templates", "false")): - p.toolkit.add_template_directory(config, "../legacy_templates") - p.toolkit.add_public_directory(config, "../legacy_public") - else: - p.toolkit.add_template_directory(config, "../templates") + p.toolkit.add_template_directory(config, "../templates") def get_helpers(self): """Return the CKAN 2.0 template helper functions this plugin provides. diff --git a/ckanext/googleanalytics/templates/base.html b/ckanext/googleanalytics/templates/base.html index 9e1cf09..c3ebd1f 100644 --- a/ckanext/googleanalytics/templates/base.html +++ b/ckanext/googleanalytics/templates/base.html @@ -1,18 +1,19 @@ {% ckan_extends %} {% block links %} - {{ super() }} - {% block googleanalytics_header %} - {{ h.googleanalytics_header() }} - {% endblock %} + {{ super() }} + {% block googleanalytics_header %} + {{ h.googleanalytics_header() }} + {% endblock %} {% endblock %} {% block scripts %} - {{ super() }} - {% block googleanalytics_event_tracking %} - {% resource 'ckanext-googleanalytics/googleanalytics_event_tracking.js' %} -
-
- {% endblock %} + {{ super() }} + {% block googleanalytics_event_tracking %} + {% set type = 'asset' if h.ckan_version() > '2.9' else 'resource' %} + {% include 'googleanalytics/snippets/event_tracking_' ~ type ~ '.html' %} +
+
+ {% endblock %} {% endblock %} diff --git a/ckanext/googleanalytics/templates/googleanalytics/snippets/event_tracking_asset.html b/ckanext/googleanalytics/templates/googleanalytics/snippets/event_tracking_asset.html new file mode 100644 index 0000000..5f34ff2 --- /dev/null +++ b/ckanext/googleanalytics/templates/googleanalytics/snippets/event_tracking_asset.html @@ -0,0 +1 @@ +{% asset 'ckanext-googleanalytics/event_tracking' %} diff --git a/ckanext/googleanalytics/templates/googleanalytics/snippets/event_tracking_resource.html b/ckanext/googleanalytics/templates/googleanalytics/snippets/event_tracking_resource.html new file mode 100644 index 0000000..d48de62 --- /dev/null +++ b/ckanext/googleanalytics/templates/googleanalytics/snippets/event_tracking_resource.html @@ -0,0 +1 @@ +{% resource 'ckanext-googleanalytics/googleanalytics_event_tracking.js' %} diff --git a/ckanext/googleanalytics/views.py b/ckanext/googleanalytics/views.py index d90aca1..7337c08 100644 --- a/ckanext/googleanalytics/views.py +++ b/ckanext/googleanalytics/views.py @@ -1,16 +1,19 @@ # -*- coding: utf-8 -*- -from flask import Blueprint + import hashlib +import logging + +from flask import Blueprint + +import ckan.logic as logic +import ckan.plugins.toolkit as tk import ckan.views.api as api import ckan.views.resource as resource -import ckan.logic as logic -import logging + from ckan.common import g -import ckan.plugins.toolkit as tk log = logging.getLogger(__name__) - -ga = Blueprint(u"google_analytics", "google_analytics",) +ga = Blueprint("google_analytics", "google_analytics") def action(logic_function, ver=api.API_MAX_VERSION): @@ -23,7 +26,7 @@ def action(logic_function, ver=api.API_MAX_VERSION): if "q" in request_data: id = request_data["q"] if "query" in request_data: - id = request_data["query"] + id = request_data[u"query"] _post_analytics(g.user, "CKAN API Request", logic_function, "", id) except Exception as e: log.debug(e) @@ -33,15 +36,13 @@ def action(logic_function, ver=api.API_MAX_VERSION): ga.add_url_rule( - u"/api/action/", - methods=[u"GET", u"POST"], - view_func=action, + "/api/action/", methods=["GET", "POST"], view_func=action, ) ga.add_url_rule( u"//action/".format( api.API_MAX_VERSION ), - methods=[u"GET", u"POST"], + methods=["GET", "POST"], view_func=action, ) @@ -58,10 +59,10 @@ def download(id, resource_id, filename=None, package_type="dataset"): ga.add_url_rule( - u"/dataset//resource//download", view_func=download + "/dataset//resource//download", view_func=download ) ga.add_url_rule( - u"/dataset//resource//download/", + "/dataset//resource//download/", view_func=download, ) @@ -71,6 +72,7 @@ def _post_analytics( ): from ckanext.googleanalytics.plugin import GoogleAnalyticsPlugin + if tk.config.get("googleanalytics.id"): data_dict = { "v": 1, diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..858d39d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,3 @@ +[tool.black] +line-length = 79 +include = '\.py$'