mirror of
https://github.com/jazzband/django-analytical.git
synced 2026-03-16 22:20:25 +00:00
Add Reinvigorate service
This commit also contains a number of typo fixes in the documentation and bumps the version.
This commit is contained in:
parent
327157d610
commit
8f9b5104da
15 changed files with 324 additions and 16 deletions
|
|
@ -10,6 +10,6 @@ Django_ project. See the ``docs`` directory for more information.
|
|||
|
||||
__author__ = "Joost Cassee"
|
||||
__email__ = "joost@cassee.net"
|
||||
__version__ = "0.5.1"
|
||||
__version__ = "0.6.0"
|
||||
__copyright__ = "Copyright (C) 2011 Joost Cassee"
|
||||
__license__ = "MIT License"
|
||||
|
|
|
|||
80
analytical/templatetags/reinvigorate.py
Normal file
80
analytical/templatetags/reinvigorate.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
"""
|
||||
Reinvigorate template tags and filters.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import re
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
from django.utils import simplejson
|
||||
|
||||
from analytical.utils import get_identity, is_internal_ip, disable_html, \
|
||||
get_required_setting
|
||||
|
||||
|
||||
TRACKING_ID_RE = re.compile(r'^[\w\d]{5}-[\w\d]{10}$')
|
||||
TRACKING_CODE = """
|
||||
<script type="text/javascript">
|
||||
document.write(unescape("%%3Cscript src='" + (("https:" == document.location.protocol) ? "https://ssl-" : "http://") + "include.reinvigorate.net/re_.js' type='text/javascript'%%3E%%3C/script%%3E"));
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
try {
|
||||
%(tags)s
|
||||
reinvigorate.track("%(tracking_id)s");
|
||||
} catch(err) {}
|
||||
</script>
|
||||
"""
|
||||
|
||||
|
||||
register = Library()
|
||||
|
||||
|
||||
@register.tag
|
||||
def reinvigorate(parser, token):
|
||||
"""
|
||||
Reinvigorate tracking template tag.
|
||||
|
||||
Renders Javascript code to track page visits. You must supply
|
||||
your Reinvigorate tracking ID (as a string) in the
|
||||
``REINVIGORATE_TRACKING_ID`` setting.
|
||||
"""
|
||||
bits = token.split_contents()
|
||||
if len(bits) > 1:
|
||||
raise TemplateSyntaxError("'%s' takes no arguments" % bits[0])
|
||||
return ReinvigorateNode()
|
||||
|
||||
class ReinvigorateNode(Node):
|
||||
def __init__(self):
|
||||
self.tracking_id = get_required_setting('REINVIGORATE_TRACKING_ID',
|
||||
TRACKING_ID_RE,
|
||||
"must be a string looking like XXXXX-XXXXXXXXXX")
|
||||
|
||||
def render(self, context):
|
||||
re_vars = {}
|
||||
for dict_ in context:
|
||||
for var, val in dict_.items():
|
||||
if var.startswith('reinvigorate_'):
|
||||
re_vars[var[13:]] = val
|
||||
if 'name' not in re_vars:
|
||||
identity = get_identity(context, 'reinvigorate',
|
||||
lambda u: u.get_full_name())
|
||||
if identity is not None:
|
||||
re_vars['name'] = identity
|
||||
if 'context' not in re_vars:
|
||||
email = get_identity(context, 'reinvigorate', lambda u: u.email)
|
||||
if email is not None:
|
||||
re_vars['context'] = email
|
||||
tags = " ".join("var re_%s_tag = %s;" % (tag, simplejson.dumps(value))
|
||||
for tag, value in re_vars.items())
|
||||
|
||||
html = TRACKING_CODE % {'tracking_id': self.tracking_id,
|
||||
'tags': tags}
|
||||
if is_internal_ip(context, 'REINVIGORATE'):
|
||||
html = disable_html(html, 'Reinvigorate')
|
||||
return html
|
||||
|
||||
|
||||
def contribute_to_analytical(add_node):
|
||||
ReinvigorateNode() # ensure properly configured
|
||||
add_node('body_bottom', ReinvigorateNode)
|
||||
|
|
@ -13,4 +13,5 @@ from analytical.tests.test_tag_kiss_metrics import *
|
|||
from analytical.tests.test_tag_mixpanel import *
|
||||
from analytical.tests.test_tag_optimizely import *
|
||||
from analytical.tests.test_tag_performable import *
|
||||
from analytical.tests.test_tag_reinvigorate import *
|
||||
from analytical.tests.test_utils import *
|
||||
|
|
|
|||
65
analytical/tests/test_tag_reinvigorate.py
Normal file
65
analytical/tests/test_tag_reinvigorate.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
"""
|
||||
Tests for the Reinvigorate template tags and filters.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.http import HttpRequest
|
||||
from django.template import Context
|
||||
|
||||
from analytical.templatetags.reinvigorate import ReinvigorateNode
|
||||
from analytical.tests.utils import TagTestCase
|
||||
from analytical.utils import AnalyticalException
|
||||
|
||||
|
||||
class ReinvigorateTagTestCase(TagTestCase):
|
||||
"""
|
||||
Tests for the ``reinvigorate`` template tag.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(ReinvigorateTagTestCase, self).setUp()
|
||||
self.settings_manager.set(REINVIGORATE_TRACKING_ID='12345-abcdefghij')
|
||||
|
||||
def test_tag(self):
|
||||
r = self.render_tag('reinvigorate', 'reinvigorate')
|
||||
self.assertTrue('reinvigorate.track("12345-abcdefghij");' in r, r)
|
||||
|
||||
def test_node(self):
|
||||
r = ReinvigorateNode().render(Context({}))
|
||||
self.assertTrue('reinvigorate.track("12345-abcdefghij");' in r, r)
|
||||
|
||||
def test_no_tracking_id(self):
|
||||
self.settings_manager.delete('REINVIGORATE_TRACKING_ID')
|
||||
self.assertRaises(AnalyticalException, ReinvigorateNode)
|
||||
|
||||
def test_wrong_tracking_id(self):
|
||||
self.settings_manager.set(REINVIGORATE_TRACKING_ID='12345-abcdefghi')
|
||||
self.assertRaises(AnalyticalException, ReinvigorateNode)
|
||||
self.settings_manager.set(REINVIGORATE_TRACKING_ID='12345-abcdefghijk')
|
||||
self.assertRaises(AnalyticalException, ReinvigorateNode)
|
||||
|
||||
def test_identify(self):
|
||||
self.settings_manager.set(ANALYTICAL_AUTO_IDENTIFY=True)
|
||||
r = ReinvigorateNode().render(Context({'user':
|
||||
User(username='test', first_name='Test', last_name='User',
|
||||
email='test@example.com')}))
|
||||
self.assertTrue('var re_name_tag = "Test User";' in r, r)
|
||||
self.assertTrue('var re_context_tag = "test@example.com";' in r, r)
|
||||
|
||||
def test_tags(self):
|
||||
r = ReinvigorateNode().render(Context({'reinvigorate_var1': 'val1',
|
||||
'reinvigorate_var2': 2}))
|
||||
self.assertTrue(re.search('var re_var1_tag = "val1";', r), r)
|
||||
self.assertTrue(re.search('var re_var2_tag = 2;', r), r)
|
||||
|
||||
def test_render_internal_ip(self):
|
||||
self.settings_manager.set(ANALYTICAL_INTERNAL_IPS=['1.1.1.1'])
|
||||
req = HttpRequest()
|
||||
req.META['REMOTE_ADDR'] = '1.1.1.1'
|
||||
context = Context({'request': req})
|
||||
r = ReinvigorateNode().render(context)
|
||||
self.assertTrue(r.startswith(
|
||||
'<!-- Reinvigorate disabled on internal IP address'), r)
|
||||
self.assertTrue(r.endswith('-->'), r)
|
||||
|
|
@ -27,12 +27,14 @@ def get_required_setting(setting, value_re, invalid_msg):
|
|||
return value
|
||||
|
||||
|
||||
def get_identity(context, prefix=None):
|
||||
def get_identity(context, prefix=None, identity_func=None):
|
||||
"""
|
||||
Get the identity of a logged in user from a template context.
|
||||
|
||||
The `prefix` argument is used to provide different identities to
|
||||
different analytics services.
|
||||
different analytics services. The `identity_func` argument is a
|
||||
function that returns the identity of the user; by default the
|
||||
identity is the username.
|
||||
"""
|
||||
if prefix is not None:
|
||||
try:
|
||||
|
|
@ -51,7 +53,10 @@ def get_identity(context, prefix=None):
|
|||
request = context['request']
|
||||
user = request.user
|
||||
if user.is_authenticated():
|
||||
return user.username
|
||||
if identity_func is not None:
|
||||
return identity_func(user)
|
||||
else:
|
||||
return user.username
|
||||
except (KeyError, AttributeError):
|
||||
pass
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ django-analytical package and have added the ``analytical`` application
|
|||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the Clicky template tags to your templates. This
|
||||
Next you need to add the Clicky template tag to your templates. This
|
||||
step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`clicky-configuration`.
|
||||
|
|
@ -104,7 +104,7 @@ Just remember that if you set the same context variable in the
|
|||
:class:`~django.template.context.RequestContext` constructor and in a
|
||||
context processor, the latter clobbers the former.
|
||||
|
||||
Here is a table with the most important variables. All variable listed
|
||||
Here is a table with the most important variables. All variables listed
|
||||
on the `customized tracking`_ documentation page can be set by replacing
|
||||
``clicky_custom.`` with ``clicky_``.
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ django-analytical package and have added the ``analytical`` application
|
|||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the Crazy Egg template tags to your templates.
|
||||
Next you need to add the Crazy Egg template tag to your templates.
|
||||
This step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`crazy-egg-configuration`.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ the django-analytical package and have added the ``analytical``
|
|||
application to :const:`INSTALLED_APPS` in your project
|
||||
:file:`settings.py` file. See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the Google Analytics template tags to your
|
||||
Next you need to add the Google Analytics template tag to your
|
||||
templates. This step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`google-analytics-configuration`.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ django-analytical package and have added the ``analytical`` application
|
|||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the HubSpot template tags to your templates. This
|
||||
Next you need to add the HubSpot template tag to your templates. This
|
||||
step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`hubspot-configuration`.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ django-analytical package and have added the ``analytical`` application
|
|||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the KISSinsights template tags to your templates.
|
||||
Next you need to add the KISSinsights template tag to your templates.
|
||||
This step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`kiss-insights-configuration`.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ django-analytical package and have added the ``analytical`` application
|
|||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the KISSmetrics template tags to your templates.
|
||||
Next you need to add the KISSmetrics template tag to your templates.
|
||||
This step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`kiss-metrics-configuration`.
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ django-analytical package and have added the ``analytical`` application
|
|||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the Mixpanel template tags to your templates. This
|
||||
Next you need to add the Mixpanel template tag to your templates. This
|
||||
step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`mixpanel-configuration`.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ django-analytical package and have added the ``analytical`` application
|
|||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the Optimizely template tags to your templates.
|
||||
Next you need to add the Optimizely template tag to your templates.
|
||||
This step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`optimizely-configuration`.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ django-analytical package and have added the ``analytical`` application
|
|||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the Performable template tags to your templates.
|
||||
Next you need to add the Performable template tag to your templates.
|
||||
This step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`performable-configuration`.
|
||||
|
|
@ -69,8 +69,8 @@ Identifying authenticated users
|
|||
-------------------------------
|
||||
|
||||
If your websites identifies visitors, you can pass this information on
|
||||
to Performable so that you can track individual users. By default, the
|
||||
username of an authenticated user is passed to Performable
|
||||
to Performable so that you can track individual users. By default, the
|
||||
username of an authenticated user is passed to Performable
|
||||
automatically. See :ref:`identifying-visitors`.
|
||||
|
||||
You can also send the visitor identity yourself by adding either the
|
||||
|
|
|
|||
157
docs/services/reinvigorate.rst
Normal file
157
docs/services/reinvigorate.rst
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
================================
|
||||
Reinvigorate -- visitor tracking
|
||||
================================
|
||||
|
||||
Reinvigorate_ gives you real-time traffic analysis, visitor activity,
|
||||
search and referrer information and click heatmaps. A system tray /
|
||||
system status bar application for your desktop notifies you when
|
||||
interesting events occur.
|
||||
|
||||
.. _Reinvigorate: http://www.reinvigorate.com/
|
||||
|
||||
|
||||
.. reinvigorate-installation:
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To start using the Reinvigorate integration, you must have installed the
|
||||
django-analytical package and have added the ``analytical`` application
|
||||
to :const:`INSTALLED_APPS` in your project :file:`settings.py` file.
|
||||
See :doc:`../install` for details.
|
||||
|
||||
Next you need to add the Reinvigorate template tag to your templates.
|
||||
This step is only needed if you are not using the generic
|
||||
:ttag:`analytical.*` tags. If you are, skip to
|
||||
:ref:`reinvigorate-configuration`.
|
||||
|
||||
The Reinvigorate tracking code is inserted into templates using a
|
||||
template tag. Load the :mod:`reinvigorate` template tag library and
|
||||
insert the :ttag:`reinvigorate` tag. Because every page that you want
|
||||
to track must have the tag, it is useful to add it to your base
|
||||
template. Insert the tag somewhere within the HTML body::
|
||||
|
||||
{% load reinvigorate %}
|
||||
...
|
||||
{% reinvigorate %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
.. _reinvigorate-configuration:
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Before you can use the Reinvigorate integration, you must first set your
|
||||
tracking ID. You can also customize the data that Reinvigorate tracks.
|
||||
|
||||
|
||||
.. _reinvigorate-tracking-id:
|
||||
|
||||
Setting the tracking ID
|
||||
-----------------------
|
||||
|
||||
Every website you track with Reinvigorate gets a tracking ID, and the
|
||||
:ttag:`reinvigorate` tag will include it in the rendered Javascript
|
||||
code. You can find the tracking ID in the URL of your website report
|
||||
pages. The URL looks like this:
|
||||
|
||||
\https://report.reinvigorate.net/accounts/XXXXX-XXXXXXXXXX/
|
||||
|
||||
Here, ``XXXXX-XXXXXXXXXX`` is the tracking ID. Set
|
||||
:const:`REINVIGORATE_TRACKING_ID` in the project :file:`settings.py`
|
||||
file::
|
||||
|
||||
REINVIGORATE_TRACKING_ID = 'XXXXX-XXXXXXXXXX'
|
||||
|
||||
If you do not set a tracking ID, the tracking code will not be rendered.
|
||||
|
||||
|
||||
.. _reinvigorate-internal-ips:
|
||||
|
||||
Internal IP addresses
|
||||
---------------------
|
||||
|
||||
Usually you do not want to track clicks from your development or
|
||||
internal IP addresses. By default, if the tags detect that the client
|
||||
comes from any address in the :const:`REINVIGORATE_INTERNAL_IPS`
|
||||
setting, the tracking code is commented out. It takes the value of
|
||||
:const:`ANALYTICAL_INTERNAL_IPS` by default (which in turn is
|
||||
:const:`INTERNAL_IPS` by default). See :ref:`identifying-visitors` for
|
||||
important information about detecting the visitor IP address.
|
||||
|
||||
|
||||
.. _reinvigorate-tags:
|
||||
|
||||
Reinvigorate tags
|
||||
-----------------
|
||||
|
||||
As described in the Reinvigorate *NameTags* and *Snoop* pages,
|
||||
the data that is tracked by Reinvigorate can be customized by adding
|
||||
*tags* to the Javascript tracking code. (These should not be confused
|
||||
with Django template tags.) Using template context variables, you can
|
||||
let the :ttag:`reinvigorate` template tag pass reinvigorate tags to
|
||||
automatically. You can set the context variables in your view when your
|
||||
render a template containing the tracking code::
|
||||
|
||||
context = RequestContext({'reinvigorate_purchase': True,
|
||||
'reinvigorate_comment': 'Got discount'})
|
||||
return some_template.render(context)
|
||||
|
||||
If you have tags that are generated on every page, you may want to set
|
||||
them in a context processor that you add to the
|
||||
:data:`TEMPLATE_CONTEXT_PROCESSORS` list in :file:`settings.py`::
|
||||
|
||||
def reinvigorate_tags(request):
|
||||
try:
|
||||
return {'name': request.user.username}
|
||||
except AttributeError:
|
||||
return {}
|
||||
|
||||
Just remember that if you set the same context variable in the
|
||||
:class:`~django.template.context.RequestContext` constructor and in a
|
||||
context processor, the latter clobbers the former.
|
||||
|
||||
Here is a table with the most important tags. All tags listed on the
|
||||
Reinvigorate pages can be set by replacing ``re_XXX_tag`` with
|
||||
``reinvigorate_XXX``.
|
||||
|
||||
========================= =============================================
|
||||
Context variable Description
|
||||
========================= =============================================
|
||||
``reinvigorate_name`` The visitor name.
|
||||
------------------------- ---------------------------------------------
|
||||
``reinvigorate_context`` Some context information about the visitor,
|
||||
e.g. an e-mail address.
|
||||
------------------------- ---------------------------------------------
|
||||
``reinvigorate_purchase`` A boolean indicating whether the visitor has
|
||||
just made a purchase. Setting this variable
|
||||
triggers an event in the Snoop notification
|
||||
application.
|
||||
------------------------- ---------------------------------------------
|
||||
``reinvigorate_new_user`` A boolean indicating whether the visitor has
|
||||
just registered as a new user. Setting this
|
||||
variable triggers an event in the Snoop
|
||||
notification application.
|
||||
------------------------- ---------------------------------------------
|
||||
``reinvigorate_comment`` A comment, which is included in a Snoop
|
||||
event notification.
|
||||
========================= =============================================
|
||||
|
||||
|
||||
.. _reinvigorate-identify-user:
|
||||
|
||||
Identifying authenticated users
|
||||
-------------------------------
|
||||
|
||||
If you have not set the ``reinvigorate_name`` context variable
|
||||
explicitly, the full name of an authenticated user is passed to
|
||||
Reinvigorate automatically. Similarly, the e-mail address is passed
|
||||
automatically in the ``context`` tag. See :ref:`identifying-visitors`.
|
||||
|
||||
|
||||
----
|
||||
|
||||
Thanks go to Reinvigorate for their support with the development of this
|
||||
application.
|
||||
Loading…
Reference in a new issue