Prepare to v2.10
This commit is contained in:
parent
4991ca7440
commit
b70b26f392
13
README.md
13
README.md
|
@ -57,7 +57,6 @@ retrieves statistics from Google Analytics and inserts them into CKAN pages.
|
||||||
|
|
||||||
googleanalytics_resource_prefix = /downloads/
|
googleanalytics_resource_prefix = /downloads/
|
||||||
googleanalytics.domain = auto
|
googleanalytics.domain = auto
|
||||||
googleanalytics.track_events = false
|
|
||||||
googleanalytics.fields = {}
|
googleanalytics.fields = {}
|
||||||
googleanalytics.enable_user_id = false
|
googleanalytics.enable_user_id = false
|
||||||
googleanalytics.download_handler = ckan.views.resource:download
|
googleanalytics.download_handler = ckan.views.resource:download
|
||||||
|
@ -76,11 +75,6 @@ retrieves statistics from Google Analytics and inserts them into CKAN pages.
|
||||||
<http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setDomainName>`_
|
<http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setDomainName>`_
|
||||||
for more info.
|
for more info.
|
||||||
|
|
||||||
If ``track_events`` is set, Google Analytics event tracking will be
|
|
||||||
enabled. *CKAN 1.x only.* *Note that event tracking for resource downloads
|
|
||||||
is always enabled,* ``track_events`` *enables event tracking for other
|
|
||||||
pages as well.*
|
|
||||||
|
|
||||||
``fields`` allows you to specify various options when creating the tracker. See `Google's documentation <https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference>`.
|
``fields`` allows you to specify various options when creating the tracker. See `Google's documentation <https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference>`.
|
||||||
|
|
||||||
If ``enable_user_id`` is set to ``true``, then logged in users will be tracked into the Google Analytics' dashboard.
|
If ``enable_user_id`` is set to ``true``, then logged in users will be tracked into the Google Analytics' dashboard.
|
||||||
|
@ -114,13 +108,6 @@ See `Googles' documentation<https://support.google.com/analytics/answer/1034342?
|
||||||
|
|
||||||
paster initdb --config=../ckan/development.ini
|
paster initdb --config=../ckan/development.ini
|
||||||
|
|
||||||
2. Optionally, add::
|
|
||||||
|
|
||||||
googleanalytics.show_downloads = true
|
|
||||||
|
|
||||||
to your CKAN ini file. If ``show_downloads`` is set, a download count for
|
|
||||||
resources will be displayed on individual package pages.
|
|
||||||
|
|
||||||
3. Follow the steps in the *Authorization* section below.
|
3. Follow the steps in the *Authorization* section below.
|
||||||
|
|
||||||
4. Restart CKAN (e.g. by restarting Apache)
|
4. Restart CKAN (e.g. by restarting Apache)
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
// Add Google Analytics Event Tracking to resource download links.
|
// Add Google Analytics Event Tracking to resource download links.
|
||||||
ckan.module("google-analytics", function(jQuery, _) {
|
ckan.module("google-analytics", function(jQuery, _) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
return {
|
return {
|
||||||
options: {
|
options: {
|
||||||
googleanalytics_resource_prefix: ""
|
googleanalytics_resource_prefix: ""
|
||||||
},
|
},
|
||||||
initialize: function() {
|
initialize: function() {
|
||||||
jQuery("a.resource-url-analytics").on("click", function() {
|
jQuery("a.resource-url-analytics").on("click", function() {
|
||||||
|
|
||||||
var resource_url = encodeURIComponent(jQuery(this).prop("href"));
|
var resource_url = encodeURIComponent(jQuery(this).prop("href"));
|
||||||
if (resource_url) {
|
if (resource_url) {
|
||||||
ga("send", "event", "Resource", "Download", resource_url);
|
ga("send", "event", "Resource", "Download", resource_url);
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
import ast
|
||||||
|
|
||||||
|
import ckan.plugins.toolkit as tk
|
||||||
|
|
||||||
|
|
||||||
|
def get_helpers():
|
||||||
|
return {
|
||||||
|
"googleanalytics_header": header,
|
||||||
|
}
|
||||||
|
|
||||||
|
def header():
|
||||||
|
"""Render the googleanalytics_header snippet for CKAN 2.0 templates.
|
||||||
|
|
||||||
|
This is a template helper function that renders the
|
||||||
|
googleanalytics_header jinja snippet. To be called from the jinja
|
||||||
|
templates in this extension, see ITemplateHelpers.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
fields = _fields()
|
||||||
|
|
||||||
|
if _enable_user_id() and tk.c.user:
|
||||||
|
fields["userId"] = str(tk.c.userobj.id)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
"googleanalytics_id": _id(),
|
||||||
|
"googleanalytics_domain": _domain(),
|
||||||
|
"googleanalytics_fields": str(fields),
|
||||||
|
"googleanalytics_linked_domains": _linked_domains(),
|
||||||
|
}
|
||||||
|
return tk.render_snippet(
|
||||||
|
"googleanalytics/snippets/googleanalytics_header.html", data
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _id():
|
||||||
|
return tk.config["googleanalytics.id"]
|
||||||
|
|
||||||
|
def _domain():
|
||||||
|
return tk.config.get(
|
||||||
|
"googleanalytics.domain", "auto"
|
||||||
|
)
|
||||||
|
|
||||||
|
def _fields():
|
||||||
|
fields = ast.literal_eval(
|
||||||
|
tk.config.get("googleanalytics.fields", "{}")
|
||||||
|
)
|
||||||
|
|
||||||
|
if _linked_domains():
|
||||||
|
fields["allowLinker"] = "true"
|
||||||
|
|
||||||
|
return fields
|
||||||
|
|
||||||
|
def _linked_domains():
|
||||||
|
googleanalytics_linked_domains = tk.config.get(
|
||||||
|
"googleanalytics.linked_domains", ""
|
||||||
|
)
|
||||||
|
return [
|
||||||
|
x.strip() for x in googleanalytics_linked_domains.split(",") if x
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _enable_user_id():
|
||||||
|
return tk.asbool(
|
||||||
|
tk.config.get("googleanalytics.enable_user_id", False)
|
||||||
|
)
|
|
@ -2,18 +2,17 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from six.moves.urllib.parse import urlencode
|
from six.moves.urllib.parse import urlencode
|
||||||
import ast
|
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
import ckan.lib.helpers as h
|
|
||||||
import ckan.plugins as p
|
import ckan.plugins as p
|
||||||
import ckan.plugins.toolkit as tk
|
import ckan.plugins.toolkit as tk
|
||||||
|
|
||||||
from ckan.exceptions import CkanVersionException
|
from ckan.exceptions import CkanConfigurationException, CkanVersionException
|
||||||
|
|
||||||
|
from ckanext.googleanalytics import helpers
|
||||||
|
|
||||||
DEFAULT_RESOURCE_URL_TAG = "/downloads/"
|
DEFAULT_RESOURCE_URL_TAG = "/downloads/"
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ else:
|
||||||
from ckanext.googleanalytics.plugin.flask_plugin import GAMixinPlugin
|
from ckanext.googleanalytics.plugin.flask_plugin import GAMixinPlugin
|
||||||
|
|
||||||
|
|
||||||
class GoogleAnalyticsException(Exception):
|
class GoogleAnalyticsException(CkanConfigurationException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -56,36 +55,26 @@ class AnalyticsPostThread(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin):
|
class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin):
|
||||||
|
|
||||||
p.implements(p.IConfigurable, inherit=True)
|
p.implements(p.IConfigurable, inherit=True)
|
||||||
p.implements(p.IConfigurer, inherit=True)
|
p.implements(p.IConfigurer, inherit=True)
|
||||||
p.implements(p.ITemplateHelpers)
|
p.implements(p.ITemplateHelpers)
|
||||||
|
|
||||||
|
|
||||||
def configure(self, config):
|
def configure(self, config):
|
||||||
"""Load config settings for this extension from config file.
|
# spawn a pool of 5 threads, and pass them queue instance
|
||||||
|
for _i in range(5):
|
||||||
|
t = AnalyticsPostThread(self.analytics_queue)
|
||||||
|
t.setDaemon(True)
|
||||||
|
t.start()
|
||||||
|
|
||||||
See IConfigurable.
|
def update_config(self, config):
|
||||||
|
tk.add_template_directory(config, "../templates")
|
||||||
|
tk.add_resource("../assets", "ckanext-googleanalytics")
|
||||||
|
|
||||||
"""
|
|
||||||
if "googleanalytics.id" not in config:
|
if "googleanalytics.id" not in config:
|
||||||
msg = "Missing googleanalytics.id in config"
|
msg = "Missing googleanalytics.id in config"
|
||||||
raise GoogleAnalyticsException(msg)
|
raise GoogleAnalyticsException(msg)
|
||||||
self.googleanalytics_id = config["googleanalytics.id"]
|
|
||||||
self.googleanalytics_domain = config.get(
|
|
||||||
"googleanalytics.domain", "auto"
|
|
||||||
)
|
|
||||||
self.googleanalytics_fields = ast.literal_eval(
|
|
||||||
config.get("googleanalytics.fields", "{}")
|
|
||||||
)
|
|
||||||
|
|
||||||
googleanalytics_linked_domains = config.get(
|
|
||||||
"googleanalytics.linked_domains", ""
|
|
||||||
)
|
|
||||||
self.googleanalytics_linked_domains = [
|
|
||||||
x.strip() for x in googleanalytics_linked_domains.split(",") if x
|
|
||||||
]
|
|
||||||
|
|
||||||
if self.googleanalytics_linked_domains:
|
|
||||||
self.googleanalytics_fields["allowLinker"] = "true"
|
|
||||||
|
|
||||||
# If resource_prefix is not in config file then write the default value
|
# If resource_prefix is not in config file then write the default value
|
||||||
# to the config dict, otherwise templates seem to get 'true' when they
|
# to the config dict, otherwise templates seem to get 'true' when they
|
||||||
|
@ -94,35 +83,6 @@ class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin):
|
||||||
config[
|
config[
|
||||||
"googleanalytics_resource_prefix"
|
"googleanalytics_resource_prefix"
|
||||||
] = DEFAULT_RESOURCE_URL_TAG
|
] = DEFAULT_RESOURCE_URL_TAG
|
||||||
self.googleanalytics_resource_prefix = config[
|
|
||||||
"googleanalytics_resource_prefix"
|
|
||||||
]
|
|
||||||
|
|
||||||
self.show_downloads = tk.asbool(
|
|
||||||
config.get("googleanalytics.show_downloads", True)
|
|
||||||
)
|
|
||||||
self.track_events = tk.asbool(
|
|
||||||
config.get("googleanalytics.track_events", False)
|
|
||||||
)
|
|
||||||
self.enable_user_id = tk.asbool(
|
|
||||||
config.get("googleanalytics.enable_user_id", False)
|
|
||||||
)
|
|
||||||
|
|
||||||
p.toolkit.add_resource("../assets", "ckanext-googleanalytics")
|
|
||||||
|
|
||||||
# spawn a pool of 5 threads, and pass them queue instance
|
|
||||||
for i in range(5):
|
|
||||||
t = AnalyticsPostThread(self.analytics_queue)
|
|
||||||
t.setDaemon(True)
|
|
||||||
t.start()
|
|
||||||
|
|
||||||
def update_config(self, config):
|
|
||||||
"""Change the CKAN (Pylons) environment configuration.
|
|
||||||
|
|
||||||
See IConfigurer.
|
|
||||||
|
|
||||||
"""
|
|
||||||
p.toolkit.add_template_directory(config, "../templates")
|
|
||||||
|
|
||||||
def get_helpers(self):
|
def get_helpers(self):
|
||||||
"""Return the CKAN 2.0 template helper functions this plugin provides.
|
"""Return the CKAN 2.0 template helper functions this plugin provides.
|
||||||
|
@ -130,26 +90,4 @@ class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin):
|
||||||
See ITemplateHelpers.
|
See ITemplateHelpers.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
return {"googleanalytics_header": self.googleanalytics_header}
|
return helpers.get_helpers()
|
||||||
|
|
||||||
def googleanalytics_header(self):
|
|
||||||
"""Render the googleanalytics_header snippet for CKAN 2.0 templates.
|
|
||||||
|
|
||||||
This is a template helper function that renders the
|
|
||||||
googleanalytics_header jinja snippet. To be called from the jinja
|
|
||||||
templates in this extension, see ITemplateHelpers.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
if self.enable_user_id and tk.c.user:
|
|
||||||
self.googleanalytics_fields["userId"] = str(tk.c.userobj.id)
|
|
||||||
|
|
||||||
data = {
|
|
||||||
"googleanalytics_id": self.googleanalytics_id,
|
|
||||||
"googleanalytics_domain": self.googleanalytics_domain,
|
|
||||||
"googleanalytics_fields": str(self.googleanalytics_fields),
|
|
||||||
"googleanalytics_linked_domains": self.googleanalytics_linked_domains,
|
|
||||||
}
|
|
||||||
return p.toolkit.render_snippet(
|
|
||||||
"googleanalytics/snippets/googleanalytics_header.html", data
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
gdata>=2.0.0
|
|
||||||
google-api-python-client>=1.6.1, <1.7.0
|
|
||||||
pyOpenSSL>=16.2.0
|
|
||||||
rsa>=3.1.4, <=4.0
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
[metadata]
|
||||||
|
name = ckanext-googleanalytics
|
||||||
|
version = 2.0.8
|
||||||
|
description = Add GA tracking and reporting to CKAN instance
|
||||||
|
long_description = file: README.md
|
||||||
|
long_description_content_type = text/markdown
|
||||||
|
url = https://github.com/ckan/ckanext-googleanalytics
|
||||||
|
author = Seb Bacon
|
||||||
|
author_email = seb.bacon@gmail.com
|
||||||
|
license = AGPL
|
||||||
|
classifiers =
|
||||||
|
Development Status :: 4 - Beta
|
||||||
|
License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
|
||||||
|
Programming Language :: Python :: 2.7
|
||||||
|
Programming Language :: Python :: 3.7
|
||||||
|
Programming Language :: Python :: 3.8
|
||||||
|
Programming Language :: Python :: 3.9
|
||||||
|
Programming Language :: Python :: 3.10
|
||||||
|
keywords =
|
||||||
|
CKAN
|
||||||
|
|
||||||
|
[options]
|
||||||
|
# python_requires = >= 3.7
|
||||||
|
install_requires =
|
||||||
|
typing_extensions
|
||||||
|
|
||||||
|
packages = find:
|
||||||
|
namespace_packages = ckanext
|
||||||
|
include_package_data = True
|
||||||
|
|
||||||
|
[options.extras_require]
|
||||||
|
requirements =
|
||||||
|
gdata>=2.0.0
|
||||||
|
google-api-python-client>=1.6.1, <1.7.0
|
||||||
|
pyOpenSSL>=16.2.0
|
||||||
|
rsa>=3.1.4, <=4.0
|
||||||
|
|
||||||
|
[options.entry_points]
|
||||||
|
ckan.plugins =
|
||||||
|
googleanalytics = ckanext.googleanalytics.plugin:GoogleAnalyticsPlugin
|
||||||
|
paste.paster_command =
|
||||||
|
loadanalytics = ckanext.googleanalytics.commands:LoadAnalytics
|
||||||
|
initdb = ckanext.googleanalytics.commands:InitDB
|
||||||
|
|
||||||
|
babel.extractors =
|
||||||
|
ckan = ckan.lib.extract:extract_ckan
|
||||||
|
[extract_messages]
|
||||||
|
keywords = translate isPlural
|
||||||
|
add_comments = TRANSLATORS:
|
||||||
|
output_file = ckanext/googleanalytics/i18n/ckanext-googleanalytics.pot
|
||||||
|
width = 80
|
||||||
|
|
||||||
|
[init_catalog]
|
||||||
|
domain = ckanext-googleanalytics
|
||||||
|
input_file = ckanext/googleanalytics/i18n/ckanext-googleanalytics.pot
|
||||||
|
output_dir = ckanext/googleanalytics/i18n
|
||||||
|
|
||||||
|
[update_catalog]
|
||||||
|
domain = ckanext-googleanalytics
|
||||||
|
input_file = ckanext/googleanalytics/i18n/ckanext-googleanalytics.pot
|
||||||
|
output_dir = ckanext/googleanalytics/i18n
|
||||||
|
previous = true
|
||||||
|
|
||||||
|
[compile_catalog]
|
||||||
|
domain = ckanext-googleanalytics
|
||||||
|
directory = ckanext/googleanalytics/i18n
|
||||||
|
statistics = true
|
||||||
|
|
||||||
|
[tool:pytest]
|
||||||
|
filterwarnings =
|
||||||
|
ignore::sqlalchemy.exc.SADeprecationWarning
|
||||||
|
ignore::sqlalchemy.exc.SAWarning
|
||||||
|
ignore::DeprecationWarning
|
||||||
|
|
||||||
|
addopts = --ckan-ini test.ini
|
48
setup.py
48
setup.py
|
@ -1,47 +1,3 @@
|
||||||
import os
|
from setuptools import setup
|
||||||
from io import open
|
|
||||||
from setuptools import setup, find_packages
|
|
||||||
HERE = os.path.dirname(__file__)
|
|
||||||
|
|
||||||
version = "2.0.7"
|
setup()
|
||||||
|
|
||||||
extras_require = {}
|
|
||||||
_extras_groups = [
|
|
||||||
('requirements', 'requirements.txt'),
|
|
||||||
]
|
|
||||||
for group, filepath in _extras_groups:
|
|
||||||
with open(os.path.join(HERE, filepath), 'r') as f:
|
|
||||||
extras_require[group] = f.readlines()
|
|
||||||
|
|
||||||
# Get the long description from the relevant file
|
|
||||||
with open(os.path.join(HERE, 'README.md'), encoding='utf-8') as f:
|
|
||||||
long_description = f.read()
|
|
||||||
|
|
||||||
setup(
|
|
||||||
name="ckanext-googleanalytics",
|
|
||||||
version=version,
|
|
||||||
description="Add GA tracking and reporting to CKAN instance",
|
|
||||||
long_description=long_description,
|
|
||||||
long_description_content_type="text/markdown",
|
|
||||||
classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
|
|
||||||
keywords="",
|
|
||||||
author="Seb Bacon",
|
|
||||||
author_email="seb.bacon@gmail.com",
|
|
||||||
url="",
|
|
||||||
license="",
|
|
||||||
packages=find_packages(exclude=["ez_setup", "examples", "tests"]),
|
|
||||||
namespace_packages=["ckanext", "ckanext.googleanalytics"],
|
|
||||||
include_package_data=True,
|
|
||||||
zip_safe=False,
|
|
||||||
install_requires=[],
|
|
||||||
extras_require=extras_require,
|
|
||||||
entry_points="""
|
|
||||||
[ckan.plugins]
|
|
||||||
# Add plugins here, eg
|
|
||||||
googleanalytics=ckanext.googleanalytics.plugin:GoogleAnalyticsPlugin
|
|
||||||
|
|
||||||
[paste.paster_command]
|
|
||||||
loadanalytics = ckanext.googleanalytics.commands:LoadAnalytics
|
|
||||||
initdb = ckanext.googleanalytics.commands:InitDB
|
|
||||||
""",
|
|
||||||
)
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
<ns0:feed ns1:etag="W/"CkQNRHo4fSp7I2A9WhZTEEw."" ns1:kind="analytics#accounts" xmlns:ns0="http://www.w3.org/2005/Atom" xmlns:ns1="http://schemas.google.com/g/2005"><ns0:updated>2011-03-13T01:59:55.435-08:00</ns0:updated><ns0:id>http://www.google.com/analytics/feeds/accounts/seb.bacon@okfn.org</ns0:id><ns0:generator version="1.0">Google Analytics</ns0:generator><ns0:author><ns0:name>Google Analytics</ns0:name></ns0:author><ns0:link href="https://www.google.com/analytics/feeds/accounts/default?max-results=300" rel="self" type="application/atom+xml" /><ns2:segment id="gaid::-1" name="All Visits" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition> </ns2:definition></ns2:segment><ns2:segment id="gaid::-2" name="New Visitors" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:visitorType==New Visitor</ns2:definition></ns2:segment><ns2:segment id="gaid::-3" name="Returning Visitors" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:visitorType==Returning Visitor</ns2:definition></ns2:segment><ns2:segment id="gaid::-4" name="Paid Search Traffic" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==ppc</ns2:definition></ns2:segment><ns2:segment id="gaid::-5" name="Non-paid Search Traffic" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:medium==organic</ns2:definition></ns2:segment><ns2:segment id="gaid::-6" name="Search Traffic" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:medium==cpa,ga:medium==cpc,ga:medium==cpm,ga:medium==cpp,ga:medium==cpv,ga:medium==organic,ga:medium==ppc</ns2:definition></ns2:segment><ns2:segment id="gaid::-7" name="Direct Traffic" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:medium==(none)</ns2:definition></ns2:segment><ns2:segment id="gaid::-8" name="Referral Traffic" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:medium==referral</ns2:definition></ns2:segment><ns2:segment id="gaid::-9" name="Visits with Conversions" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:goalCompletionsAll>0</ns2:definition></ns2:segment><ns2:segment id="gaid::-10" name="Visits with Transactions" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:transactions>0</ns2:definition></ns2:segment><ns2:segment id="gaid::-11" name="Mobile Traffic" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:isMobile==Yes</ns2:definition></ns2:segment><ns2:segment id="gaid::-12" name="Non-bounce Visits" xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:definition>ga:bounces==0</ns2:definition></ns2:segment><ns2:startIndex xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">1</ns2:startIndex><ns2:totalResults xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">1</ns2:totalResults><ns2:itemsPerPage xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">300</ns2:itemsPerPage><ns0:entry ns1:etag="W/"CkQNRHo4fSp7I2A9WhZTEEw."" ns1:kind="analytics#account"><ns0:id>http://www.google.com/analytics/feeds/accounts/ga:42156377</ns0:id><ns2:tableId xmlns:ns2="http://schemas.google.com/analytics/2009">ga:42156377</ns2:tableId><ns0:updated>2011-03-13T01:59:55.435-08:00</ns0:updated><ns2:property name="ga:accountId" value="21313878" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:property name="ga:accountName" value="borf" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:property name="ga:profileId" value="42156377" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:property name="ga:webPropertyId" value="UA-borf-1" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:property name="ga:currency" value="USD" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:property name="ga:timezone" value="Europe/London" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:title>borf</ns0:title><ns0:link href="http://www.google.com/analytics" rel="alternate" type="text/html" /></ns0:entry><ns0:title>Profile list for seb.bacon@okfn.org</ns0:title></ns0:feed>
|
|
|
@ -1,8 +0,0 @@
|
||||||
<ns0:feed ns1:etag="W/"AkYHSXo5eCp7I2A9WhZSGUQ."" ns1:kind="analytics#data" xmlns:ns0="http://www.w3.org/2005/Atom" xmlns:ns1="http://schemas.google.com/g/2005"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&dimensions=ga:pagePath&metrics=ga:newVisits,ga:uniquePageviews,ga:visitors,ga:visits&filters=ga:pagePath%3D~%5E/downloads/&start-date=2011-03-22&end-date=2011-04-05</ns0:id><ns2:dataSource xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:tableName>datagm.staging.ckan.net/</ns2:tableName><ns2:tableId>ga:42156377</ns2:tableId><ns2:property name="ga:profileId" value="42156377" /><ns2:property name="ga:webPropertyId" value="UA-21313878-1" /><ns2:property name="ga:accountName" value="http://datagm.staging.ckan.net/" /></ns2:dataSource><ns2:aggregates xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:metric confidenceInterval="0.0" name="ga:visits" type="integer" value="2" /><ns2:metric confidenceInterval="0.0" name="ga:visitors" type="integer" value="157" /><ns2:metric confidenceInterval="0.0" name="ga:newVisits" type="integer" value="0" /><ns2:metric confidenceInterval="0.0" name="ga:uniquePageviews" type="integer" value="164" /></ns2:aggregates><ns0:updated>2011-04-05T03:08:58.420-07:00</ns0:updated><ns2:containsSampledData xmlns:ns2="http://schemas.google.com/analytics/2009">false</ns2:containsSampledData>
|
|
||||||
|
|
||||||
<ns0:entry ns1:etag="W/"C0EEQX47eSp7I2A9WhZSGUs."" ns1:kind="analytics#datarow"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&ga:pagePath=/downloads/http%3A%2F%2Fwww.annakarenina.com%2Findex.json&filters=ga:pagePath%3D~%5E/downloads/&start-date=2011-03-22&end-date=2011-04-05</ns0:id><ns0:updated>2011-04-04T17:00:00.001-07:00</ns0:updated><ns2:dimension name="ga:pagePath" value="/downloads/http://www.annakarenina.com/index.json" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:title>ga:pagePath=/downloads/http%3A%2F%2Fwww.annakarenina.com%2Findex.json</ns0:title><ns2:metric confidenceInterval="0.0" name="ga:visits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:visitors" type="integer" value="4" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:newVisits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:uniquePageviews" type="integer" value="4" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:link href="http://www.google.com/analytics" rel="alternate" type="text/html" /></ns0:entry>
|
|
||||||
|
|
||||||
|
|
||||||
<ns0:entry ns1:etag="W/"C0EEQX47eSp7I2A9WhZSGUs."" ns1:kind="analytics#datarow"><ns0:id>missingthing</ns0:id><ns0:updated>2011-04-04T17:00:00.001-07:00</ns0:updated><ns2:dimension name="ga:pagePath" value="/downloads/missingthing" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:title>ga:pagePath=/downloads/missingthing</ns0:title><ns2:metric confidenceInterval="0.0" name="ga:visits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:visitors" type="integer" value="3" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:newVisits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:uniquePageviews" type="integer" value="4" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:link href="http://www.google.com/analytics" rel="alternate" type="text/html" /></ns0:entry>
|
|
||||||
|
|
||||||
<ns0:generator version="1.0">Google Analytics</ns0:generator><ns2:startIndex xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">1</ns2:startIndex><ns0:title>Google Analytics Data for Profile 42156377</ns0:title><ns0:author><ns0:name>Google Analytics</ns0:name></ns0:author><ns0:link href="https://www.google.com/analytics/feeds/data?max-results=10000&sort=-ga%3AnewVisits&end-date=2011-04-05&start-date=2011-03-22&metrics=ga%3Avisits%2Cga%3Avisitors%2Cga%3AnewVisits%2Cga%3AuniquePageviews&ids=ga%3A42156377&dimensions=ga%3ApagePath&filters=ga%3ApagePath%3D%7E%5E%2Fdownloads%2F" rel="self" type="application/atom+xml" /><ns2:endDate xmlns:ns2="http://schemas.google.com/analytics/2009">2011-04-05</ns2:endDate><ns2:totalResults xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">43</ns2:totalResults><ns2:startDate xmlns:ns2="http://schemas.google.com/analytics/2009">2011-03-22</ns2:startDate><ns2:itemsPerPage xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">10000</ns2:itemsPerPage></ns0:feed>
|
|
|
@ -1,61 +0,0 @@
|
||||||
import os
|
|
||||||
import BaseHTTPServer
|
|
||||||
import threading
|
|
||||||
|
|
||||||
here_dir = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
|
|
||||||
|
|
||||||
class MockHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|
||||||
def do_GET(self):
|
|
||||||
if "feeds/accounts/default" in self.path:
|
|
||||||
self.send_response(200)
|
|
||||||
self.end_headers()
|
|
||||||
fixture = os.path.join(here_dir, "accountsfixture.xml")
|
|
||||||
content = open(fixture, "r").read()
|
|
||||||
elif "analytics/feeds/data" in self.path:
|
|
||||||
if "dataset" in self.path:
|
|
||||||
fixture = os.path.join(here_dir, "packagefixture.xml")
|
|
||||||
elif "download" in self.path:
|
|
||||||
fixture = os.path.join(here_dir, "downloadfixture.xml")
|
|
||||||
self.send_response(200)
|
|
||||||
self.end_headers()
|
|
||||||
content = open(fixture, "r").read()
|
|
||||||
else:
|
|
||||||
self.send_response(200)
|
|
||||||
self.end_headers()
|
|
||||||
content = "empty"
|
|
||||||
self.wfile.write(content)
|
|
||||||
|
|
||||||
def do_POST(self):
|
|
||||||
if "ClientLogin" in self.path:
|
|
||||||
self.send_response(200)
|
|
||||||
self.end_headers()
|
|
||||||
content = "Auth=blah"
|
|
||||||
else:
|
|
||||||
self.send_response(200)
|
|
||||||
self.end_headers()
|
|
||||||
content = "empty"
|
|
||||||
self.wfile.write(content)
|
|
||||||
|
|
||||||
def do_QUIT(self):
|
|
||||||
self.send_response(200)
|
|
||||||
self.end_headers()
|
|
||||||
self.server.stop = True
|
|
||||||
|
|
||||||
|
|
||||||
class ReusableServer(BaseHTTPServer.HTTPServer):
|
|
||||||
allow_reuse_address = 1
|
|
||||||
|
|
||||||
def serve_til_quit(self):
|
|
||||||
self.stop = False
|
|
||||||
while not self.stop:
|
|
||||||
self.handle_request()
|
|
||||||
|
|
||||||
|
|
||||||
def runmockserver():
|
|
||||||
server_address = ("localhost", 6969)
|
|
||||||
httpd = ReusableServer(server_address, MockHandler)
|
|
||||||
httpd_thread = threading.Thread(target=httpd.serve_til_quit)
|
|
||||||
httpd_thread.setDaemon(True)
|
|
||||||
httpd_thread.start()
|
|
||||||
return httpd_thread
|
|
|
@ -1,9 +0,0 @@
|
||||||
<ns0:feed ns1:etag="W/"AkYHRn87fip7I2A9WhZSGUQ."" ns1:kind="analytics#data" xmlns:ns0="http://www.w3.org/2005/Atom" xmlns:ns1="http://schemas.google.com/g/2005"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&dimensions=ga:pagePath&metrics=ga:newVisits,ga:uniquePageviews,ga:visitors,ga:visits&filters=ga:pagePath%3D~%5E/dataset/&start-date=2011-03-22&end-date=2011-04-05</ns0:id><ns2:dataSource xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:tableName>datagm.staging.ckan.net/</ns2:tableName><ns2:tableId>ga:42156377</ns2:tableId><ns2:property name="ga:profileId" value="42156377" /><ns2:property name="ga:webPropertyId" value="UA-21313878-1" /><ns2:property name="ga:accountName" value="http://datagm.staging.ckan.net/" /></ns2:dataSource><ns2:aggregates xmlns:ns2="http://schemas.google.com/analytics/2009"><ns2:metric confidenceInterval="0.0" name="ga:visits" type="integer" value="122" /><ns2:metric confidenceInterval="0.0" name="ga:visitors" type="integer" value="526" /><ns2:metric confidenceInterval="0.0" name="ga:newVisits" type="integer" value="83" /><ns2:metric confidenceInterval="0.0" name="ga:uniquePageviews" type="integer" value="606" /></ns2:aggregates><ns0:updated>2011-04-05T03:08:57.106-07:00</ns0:updated><ns2:containsSampledData xmlns:ns2="http://schemas.google.com/analytics/2009">false</ns2:containsSampledData>
|
|
||||||
|
|
||||||
<ns0:entry ns1:etag="W/"C0EEQX47eSp7I2A9WhZSGUs."" ns1:kind="analytics#datarow"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&ga:pagePath=/dataset/annakarenina&filters=ga:pagePath%3D~%5E/dataset/&start-date=2011-03-22&end-date=2011-04-05</ns0:id><ns0:updated>2011-04-04T17:00:00.001-07:00</ns0:updated><ns2:dimension name="ga:pagePath" value="/dataset/annakarenina" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:title>ga:pagePath=/dataset/annakarenina</ns0:title><ns2:metric confidenceInterval="0.0" name="ga:visits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:visitors" type="integer" value="2" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:newVisits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:uniquePageviews" type="integer" value="2" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:link href="http://www.google.com/analytics" rel="alternate" type="text/html" /></ns0:entry>
|
|
||||||
|
|
||||||
<ns0:entry ns1:etag="W/"C0EEQX47eSp7I2A9WhZSGUs."" ns1:kind="analytics#datarow"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&ga:pagePath=/dataset/annakarenina/invalid&filters=ga:pagePath%3D~%5E/dataset/&start-date=2011-03-22&end-date=2011-04-05</ns0:id><ns0:updated>2011-04-04T17:00:00.001-07:00</ns0:updated><ns2:dimension name="ga:pagePath" value="/dataset/annakarenina/invalid" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:title>ga:pagePath=/dataset/annakarenina/invalid</ns0:title><ns2:metric confidenceInterval="0.0" name="ga:visits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:visitors" type="integer" value="2" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:newVisits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:uniquePageviews" type="integer" value="2" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:link href="http://www.google.com/analytics" rel="alternate" type="text/html" /></ns0:entry>
|
|
||||||
|
|
||||||
<ns0:entry ns1:etag="W/"C0EEQX47eSp7I2A9WhZSGUs."" ns1:kind="analytics#datarow"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&ga:pagePath=/dataset/annakarenina-invalid&filters=ga:pagePath%3D~%5E/dataset/&start-date=2011-03-22&end-date=2011-04-05</ns0:id><ns0:updated>2011-04-04T17:00:00.001-07:00</ns0:updated><ns2:dimension name="ga:pagePath" value="/dataset/annakarenina-invalid" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:title>ga:pagePath=/dataset/annakarenina-invalid</ns0:title><ns2:metric confidenceInterval="0.0" name="ga:visits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:visitors" type="integer" value="2" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:newVisits" type="integer" value="0" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns2:metric confidenceInterval="0.0" name="ga:uniquePageviews" type="integer" value="2" xmlns:ns2="http://schemas.google.com/analytics/2009" /><ns0:link href="http://www.google.com/analytics" rel="alternate" type="text/html" /></ns0:entry>
|
|
||||||
|
|
||||||
<ns0:generator version="1.0">Google Analytics</ns0:generator><ns2:startIndex xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">1</ns2:startIndex><ns0:title>Google Analytics Data for Profile 42156377</ns0:title><ns0:author><ns0:name>Google Analytics</ns0:name></ns0:author><ns0:link href="https://www.google.com/analytics/feeds/data?max-results=10000&sort=-ga%3AnewVisits&end-date=2011-04-05&start-date=2011-03-22&metrics=ga%3Avisits%2Cga%3Avisitors%2Cga%3AnewVisits%2Cga%3AuniquePageviews&ids=ga%3A42156377&dimensions=ga%3ApagePath&filters=ga%3ApagePath%3D%7E%5E%2Fdataset%2F" rel="self" type="application/atom+xml" /><ns2:endDate xmlns:ns2="http://schemas.google.com/analytics/2009">2011-04-05</ns2:endDate><ns2:totalResults xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">152</ns2:totalResults><ns2:startDate xmlns:ns2="http://schemas.google.com/analytics/2009">2011-03-22</ns2:startDate><ns2:itemsPerPage xmlns:ns2="http://a9.com/-/spec/opensearchrss/1.0/">10000</ns2:itemsPerPage></ns0:feed>
|
|
|
@ -1,122 +0,0 @@
|
||||||
import httplib
|
|
||||||
from unittest import TestCase
|
|
||||||
|
|
||||||
from ckan.config.middleware import make_app
|
|
||||||
from paste.deploy import appconfig
|
|
||||||
import paste.fixture
|
|
||||||
from ckan.tests import conf_dir, url_for, CreateTestData
|
|
||||||
|
|
||||||
from mockgoogleanalytics import runmockserver
|
|
||||||
from ckanext.googleanalytics.commands import LoadAnalytics
|
|
||||||
from ckanext.googleanalytics.commands import InitDB
|
|
||||||
from ckanext.googleanalytics import dbutil
|
|
||||||
import ckanext.googleanalytics.gasnippet as gasnippet
|
|
||||||
|
|
||||||
|
|
||||||
class MockClient(httplib.HTTPConnection):
|
|
||||||
def request(self, http_request):
|
|
||||||
filters = http_request.uri.query.get("filters")
|
|
||||||
path = http_request.uri.path
|
|
||||||
if filters:
|
|
||||||
if "dataset" in filters:
|
|
||||||
path += "/dataset"
|
|
||||||
else:
|
|
||||||
path += "/download"
|
|
||||||
httplib.HTTPConnection.request(self, http_request.method, path)
|
|
||||||
resp = self.getresponse()
|
|
||||||
return resp
|
|
||||||
|
|
||||||
|
|
||||||
class TestConfig(TestCase):
|
|
||||||
def test_config(self):
|
|
||||||
config = appconfig("config:test.ini", relative_to=conf_dir)
|
|
||||||
config.local_conf["ckan.plugins"] = "googleanalytics"
|
|
||||||
config.local_conf["googleanalytics.id"] = ""
|
|
||||||
command = LoadAnalytics("loadanalytics")
|
|
||||||
command.CONFIG = config.local_conf
|
|
||||||
self.assertRaises(Exception, command.run, [])
|
|
||||||
|
|
||||||
|
|
||||||
class TestLoadCommand(TestCase):
|
|
||||||
@classmethod
|
|
||||||
def setup_class(cls):
|
|
||||||
InitDB("initdb").run([]) # set up database tables
|
|
||||||
|
|
||||||
config = appconfig("config:test.ini", relative_to=conf_dir)
|
|
||||||
config.local_conf["ckan.plugins"] = "googleanalytics"
|
|
||||||
config.local_conf["googleanalytics.username"] = "borf"
|
|
||||||
config.local_conf["googleanalytics.password"] = "borf"
|
|
||||||
config.local_conf["googleanalytics.id"] = "UA-borf-1"
|
|
||||||
config.local_conf["googleanalytics.show_downloads"] = "true"
|
|
||||||
cls.config = config.local_conf
|
|
||||||
wsgiapp = make_app(config.global_conf, **config.local_conf)
|
|
||||||
env = {
|
|
||||||
"HTTP_ACCEPT": (
|
|
||||||
"text/html;q=0.9,text/plain;" "q=0.8,image/png,*/*;q=0.5"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
cls.app = paste.fixture.TestApp(wsgiapp, extra_environ=env)
|
|
||||||
CreateTestData.create()
|
|
||||||
runmockserver()
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def teardown_class(cls):
|
|
||||||
CreateTestData.delete()
|
|
||||||
conn = httplib.HTTPConnection("localhost:%d" % 6969)
|
|
||||||
conn.request("QUIT", "/")
|
|
||||||
conn.getresponse()
|
|
||||||
|
|
||||||
def test_analytics_snippet(self):
|
|
||||||
response = self.app.get(url_for(controller="tag", action="index"))
|
|
||||||
code = gasnippet.header_code % (
|
|
||||||
self.config["googleanalytics.id"],
|
|
||||||
"auto",
|
|
||||||
)
|
|
||||||
assert code in response.body
|
|
||||||
|
|
||||||
def test_top_packages(self):
|
|
||||||
command = LoadAnalytics("loadanalytics")
|
|
||||||
command.TEST_HOST = MockClient("localhost", 6969)
|
|
||||||
command.CONFIG = self.config
|
|
||||||
command.run([])
|
|
||||||
packages = dbutil.get_top_packages()
|
|
||||||
resources = dbutil.get_top_resources()
|
|
||||||
self.assertEquals(packages[0][1], 2)
|
|
||||||
self.assertEquals(resources[0][1], 4)
|
|
||||||
|
|
||||||
def test_download_count_inserted(self):
|
|
||||||
command = LoadAnalytics("loadanalytics")
|
|
||||||
command.TEST_HOST = MockClient("localhost", 6969)
|
|
||||||
command.CONFIG = self.config
|
|
||||||
command.run([])
|
|
||||||
response = self.app.get(
|
|
||||||
url_for(controller="package", action="read", id="annakarenina")
|
|
||||||
)
|
|
||||||
assert "[downloaded 4 times]" in response.body
|
|
||||||
|
|
||||||
def test_js_inserted_resource_view(self):
|
|
||||||
from nose import SkipTest
|
|
||||||
|
|
||||||
raise SkipTest("Test won't work until CKAN 1.5.2")
|
|
||||||
|
|
||||||
from ckan.logic.action import get
|
|
||||||
from ckan import model
|
|
||||||
|
|
||||||
context = {"model": model, "ignore_auth": True}
|
|
||||||
data = {"id": "annakarenina"}
|
|
||||||
pkg = get.package_show(context, data)
|
|
||||||
resource_id = pkg["resources"][0]["id"]
|
|
||||||
|
|
||||||
command = LoadAnalytics("loadanalytics")
|
|
||||||
command.TEST_HOST = MockClient("localhost", 6969)
|
|
||||||
command.CONFIG = self.config
|
|
||||||
command.run([])
|
|
||||||
response = self.app.get(
|
|
||||||
url_for(
|
|
||||||
controller="package",
|
|
||||||
action="resource_read",
|
|
||||||
id="annakarenina",
|
|
||||||
resource_id=resource_id,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
assert 'onclick="javascript: _gaq.push(' in response.body
|
|
Loading…
Reference in New Issue