Add support for Piwik user identity tracking

The 'piwik_identity' (or the default 'analytical_identity') context variables are used to call Piwik's 'setUserId' function.
If neither are found, use what is returned by get_identity.
This commit is contained in:
Alexandre Pocquet 2015-08-19 16:20:43 +02:00
parent 8af3181752
commit f27d946ccf
2 changed files with 56 additions and 7 deletions

View file

@ -8,8 +8,9 @@ from collections import namedtuple
import re
from django.template import Library, Node, TemplateSyntaxError
from django.conf import settings
from analytical.utils import is_internal_ip, disable_html, get_required_setting
from analytical.utils import is_internal_ip, disable_html, get_required_setting, get_identity
# domain name (characters separated by a dot), optional URI path, no slash
@ -35,11 +36,13 @@ TRACKING_CODE = """
<noscript><p><img src="http://%(url)s/piwik.php?idsite=%(siteid)s" style="border:0;" alt="" /></p></noscript>
""" # noqa
VARIABLE_CODE = '_paq.push([%(index)s, "%(name)s", "%(value)s", "%(scope)s"]);'
PiwikVar = namedtuple('PiwikVar', ('index', 'name', 'value', 'scope'))
VARIABLE_CODE = '_paq.push(["setCustomVariable", %(index)s, "%(name)s", "%(value)s", "%(scope)s"]);'
IDENTITY_CODE = '_paq.push(["setUserId", "%(userid)s"]);'
DEFAULT_SCOPE = 'page'
PiwikVar = namedtuple('PiwikVar', ('index', 'name', 'value', 'scope'))
register = Library()
@ -82,7 +85,13 @@ class PiwikNode(Node):
complete_variables = (var if len(var) >= 4 else var + (DEFAULT_SCOPE,) for var in custom_variables)
variables_code = (VARIABLE_CODE % PiwikVar(*var)._asdict() for var in complete_variables)
variables_code = [VARIABLE_CODE % PiwikVar(*var)._asdict() for var in complete_variables]
userid = get_identity(context, 'piwik')
if userid is not None:
variables_code.append(
IDENTITY_CODE % {'userid': userid}
)
html = TRACKING_CODE % {
'url': self.domain_path,

View file

@ -5,6 +5,7 @@ Tests for the Piwik template tags and filters.
from django.http import HttpRequest
from django.template import Context
from django.test.utils import override_settings
from django.contrib.auth.models import User
from analytical.templatetags.piwik import PiwikNode
from analytical.tests.utils import TagTestCase
@ -74,7 +75,46 @@ class PiwikTagTestCase(TagTestCase):
(3, 'spam', 'spam_val', 'visit')]})
r = PiwikNode().render(context)
msg = 'Incorrect Piwik custom variable rendering. Expected:\n%s\nIn:\n%s'
for var_code in ['_paq.push([1, "foo", "foo_val", "page"]);',
'_paq.push([2, "bar", "bar_val", "page"]);',
'_paq.push([3, "spam", "spam_val", "visit"]);']:
for var_code in ['_paq.push(["setCustomVariable", 1, "foo", "foo_val", "page"]);',
'_paq.push(["setCustomVariable", 2, "bar", "bar_val", "page"]);',
'_paq.push(["setCustomVariable", 3, "spam", "spam_val", "visit"]);']:
self.assertIn(var_code, r, msg % (var_code, r))
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_default_usertrack(self):
context = Context({
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum')
})
r = PiwikNode().render(context)
msg = 'Incorrect Piwik user tracking rendering. Expected:\n%s\nIn:\n%s'
var_code = '_paq.push(["setUserId", "BDFL"]);'
self.assertIn(var_code, r, msg % (var_code, r))
def test_piwik_usertrack(self):
context = Context({
'piwik_identity': 'BDFL'
})
r = PiwikNode().render(context)
msg = 'Incorrect Piwik user tracking rendering. Expected:\n%s\nIn:\n%s'
var_code = '_paq.push(["setUserId", "BDFL"]);'
self.assertIn(var_code, r, msg % (var_code, r))
def test_analytical_usertrack(self):
context = Context({
'analytical_identity': 'BDFL'
})
r = PiwikNode().render(context)
msg = 'Incorrect Piwik user tracking rendering. Expected:\n%s\nIn:\n%s'
var_code = '_paq.push(["setUserId", "BDFL"]);'
self.assertIn(var_code, r, msg % (var_code, r))
@override_settings(ANALYTICAL_AUTO_IDENTIFY=True)
def test_disable_usertrack(self):
context = Context({
'user': User(username='BDFL', first_name='Guido', last_name='van Rossum'),
'piwik_identity': None
})
r = PiwikNode().render(context)
msg = 'Incorrect Piwik user tracking rendering. Expected:\n%s\nIn:\n%s'
var_code = '_paq.push(["setUserId", "BDFL"]);'
self.assertNotIn(var_code, r, msg % (var_code, r))