Prepare to v2.10

This commit is contained in:
Sergey Motornyuk 2022-05-06 17:29:58 +03:00
parent 4991ca7440
commit b70b26f392
13 changed files with 174 additions and 354 deletions

View File

@ -57,7 +57,6 @@ retrieves statistics from Google Analytics and inserts them into CKAN pages.
googleanalytics_resource_prefix = /downloads/
googleanalytics.domain = auto
googleanalytics.track_events = false
googleanalytics.fields = {}
googleanalytics.enable_user_id = false
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>`_
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>`.
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
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.
4. Restart CKAN (e.g. by restarting Apache)

View File

@ -1,17 +1,19 @@
// Add Google Analytics Event Tracking to resource download links.
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);
"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);
}
});
}
});
}
};
};
});

View File

@ -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)
)

View File

@ -2,18 +2,17 @@
from __future__ import absolute_import
from six.moves.urllib.parse import urlencode
import ast
import logging
import threading
import requests
import ckan.lib.helpers as h
import ckan.plugins as p
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/"
@ -27,7 +26,7 @@ else:
from ckanext.googleanalytics.plugin.flask_plugin import GAMixinPlugin
class GoogleAnalyticsException(Exception):
class GoogleAnalyticsException(CkanConfigurationException):
pass
@ -56,36 +55,26 @@ class AnalyticsPostThread(threading.Thread):
class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin):
p.implements(p.IConfigurable, inherit=True)
p.implements(p.IConfigurer, inherit=True)
p.implements(p.ITemplateHelpers)
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:
msg = "Missing googleanalytics.id in config"
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
# to the config dict, otherwise templates seem to get 'true' when they
@ -94,35 +83,6 @@ class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin):
config[
"googleanalytics_resource_prefix"
] = 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):
"""Return the CKAN 2.0 template helper functions this plugin provides.
@ -130,26 +90,4 @@ class GoogleAnalyticsPlugin(GAMixinPlugin, p.SingletonPlugin):
See ITemplateHelpers.
"""
return {"googleanalytics_header": self.googleanalytics_header}
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
)
return helpers.get_helpers()

View File

@ -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

75
setup.cfg Normal file
View File

@ -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

View File

@ -1,47 +1,3 @@
import os
from io import open
from setuptools import setup, find_packages
HERE = os.path.dirname(__file__)
from setuptools import setup
version = "2.0.7"
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
""",
)
setup()

View File

View File

@ -1 +0,0 @@
<ns0:feed ns1:etag="W/&quot;CkQNRHo4fSp7I2A9WhZTEEw.&quot;" 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&gt;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&gt;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/&quot;CkQNRHo4fSp7I2A9WhZTEEw.&quot;" 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>

View File

@ -1,8 +0,0 @@
<ns0:feed ns1:etag="W/&quot;AkYHSXo5eCp7I2A9WhZSGUQ.&quot;" 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&amp;dimensions=ga:pagePath&amp;metrics=ga:newVisits,ga:uniquePageviews,ga:visitors,ga:visits&amp;filters=ga:pagePath%3D~%5E/downloads/&amp;start-date=2011-03-22&amp;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/&quot;C0EEQX47eSp7I2A9WhZSGUs.&quot;" ns1:kind="analytics#datarow"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&amp;ga:pagePath=/downloads/http%3A%2F%2Fwww.annakarenina.com%2Findex.json&amp;filters=ga:pagePath%3D~%5E/downloads/&amp;start-date=2011-03-22&amp;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/&quot;C0EEQX47eSp7I2A9WhZSGUs.&quot;" 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&amp;sort=-ga%3AnewVisits&amp;end-date=2011-04-05&amp;start-date=2011-03-22&amp;metrics=ga%3Avisits%2Cga%3Avisitors%2Cga%3AnewVisits%2Cga%3AuniquePageviews&amp;ids=ga%3A42156377&amp;dimensions=ga%3ApagePath&amp;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>

View File

@ -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

View File

@ -1,9 +0,0 @@
<ns0:feed ns1:etag="W/&quot;AkYHRn87fip7I2A9WhZSGUQ.&quot;" 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&amp;dimensions=ga:pagePath&amp;metrics=ga:newVisits,ga:uniquePageviews,ga:visitors,ga:visits&amp;filters=ga:pagePath%3D~%5E/dataset/&amp;start-date=2011-03-22&amp;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/&quot;C0EEQX47eSp7I2A9WhZSGUs.&quot;" ns1:kind="analytics#datarow"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&amp;ga:pagePath=/dataset/annakarenina&amp;filters=ga:pagePath%3D~%5E/dataset/&amp;start-date=2011-03-22&amp;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/&quot;C0EEQX47eSp7I2A9WhZSGUs.&quot;" ns1:kind="analytics#datarow"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&amp;ga:pagePath=/dataset/annakarenina/invalid&amp;filters=ga:pagePath%3D~%5E/dataset/&amp;start-date=2011-03-22&amp;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/&quot;C0EEQX47eSp7I2A9WhZSGUs.&quot;" ns1:kind="analytics#datarow"><ns0:id>http://www.google.com/analytics/feeds/data?ids=ga:42156377&amp;ga:pagePath=/dataset/annakarenina-invalid&amp;filters=ga:pagePath%3D~%5E/dataset/&amp;start-date=2011-03-22&amp;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&amp;sort=-ga%3AnewVisits&amp;end-date=2011-04-05&amp;start-date=2011-03-22&amp;metrics=ga%3Avisits%2Cga%3Avisitors%2Cga%3AnewVisits%2Cga%3AuniquePageviews&amp;ids=ga%3A42156377&amp;dimensions=ga%3ApagePath&amp;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>

View File

@ -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