diff --git a/README.rst b/README.rst index cec30b6..d9e32b1 100644 --- a/README.rst +++ b/README.rst @@ -22,6 +22,7 @@ Currently supported services: * `Chartbeat`_ traffic analysis * `Clicky`_ traffic analysis * `Crazy Egg`_ visual click tracking +* `Gaug.es`_ realtime traffic tracking * `Google Analytics`_ traffic analysis * `GoSquared`_ traffic monitoring * `HubSpot`_ inbound marketing @@ -52,6 +53,7 @@ an issue to discuss your plans. .. _Clicky: http://getclicky.com/ .. _`Crazy Egg`: http://www.crazyegg.com/ .. _`Google Analytics`: http://www.google.com/analytics/ +.. _`Gaug.es`: http://www.gaug.es/ .. _GoSquared: http://www.gosquared.com/ .. _HubSpot: http://www.hubspot.com/ .. _KISSinsights: http://www.kissinsights.com/ diff --git a/analytical/__init__.py b/analytical/__init__.py index 344a739..9bd3a59 100644 --- a/analytical/__init__.py +++ b/analytical/__init__.py @@ -10,6 +10,6 @@ Django_ project. See the ``docs`` directory for more information. __author__ = "Joost Cassee" __email__ = "joost@cassee.net" -__version__ = "0.11.2" +__version__ = "0.11.3" __copyright__ = "Copyright (C) 2011 Joost Cassee and others" __license__ = "MIT License" diff --git a/analytical/templatetags/analytical.py b/analytical/templatetags/analytical.py index aa40099..4043219 100644 --- a/analytical/templatetags/analytical.py +++ b/analytical/templatetags/analytical.py @@ -18,6 +18,7 @@ TAG_MODULES = [ 'analytical.chartbeat', 'analytical.clicky', 'analytical.crazy_egg', + 'analytical.gauges', 'analytical.google_analytics', 'analytical.gosquared', 'analytical.hubspot', diff --git a/analytical/templatetags/gauges.py b/analytical/templatetags/gauges.py new file mode 100644 index 0000000..60b6586 --- /dev/null +++ b/analytical/templatetags/gauges.py @@ -0,0 +1,63 @@ +""" +Gaug.es template tags and filters. +""" + +from __future__ import absolute_import + +import re + +from django.template import Library, Node, TemplateSyntaxError + +from analytical.utils import is_internal_ip, disable_html, get_required_setting + +SITE_ID_RE = re.compile(r'[\da-f]+$') +TRACKING_CODE = """ + +""" + +register = Library() + + +@register.tag +def gauges(parser, token): + """ + Gaug.es template tag. + + Renders Javascript code to gaug.es testing. You must supply + your Site ID account number in the ``GAUGES_SITE_ID`` + setting. + """ + bits = token.split_contents() + if len(bits) > 1: + raise TemplateSyntaxError("'%s' takes no arguments" % bits[0]) + return GaugesNode() + + +class GaugesNode(Node): + def __init__(self): + self.site_id = get_required_setting( + 'GAUGES_SITE_ID', SITE_ID_RE, + "must be a string looking like 'XXXXXXX'") + + def render(self, context): + html = TRACKING_CODE % {'site_id': self.site_id} + if is_internal_ip(context, 'GAUGES'): + html = disable_html(html, 'Gauges') + return html + + +def contribute_to_analytical(add_node): + GaugesNode() + add_node('head_bottom', GaugesNode) diff --git a/analytical/templatetags/optimizely.py b/analytical/templatetags/optimizely.py index 55e138c..e5cd185 100644 --- a/analytical/templatetags/optimizely.py +++ b/analytical/templatetags/optimizely.py @@ -32,6 +32,7 @@ def optimizely(parser, token): raise TemplateSyntaxError("'%s' takes no arguments" % bits[0]) return OptimizelyNode() + class OptimizelyNode(Node): def __init__(self): self.account_number = get_required_setting( diff --git a/analytical/tests/__init__.py b/analytical/tests/__init__.py index 71a93b6..50c6ae6 100644 --- a/analytical/tests/__init__.py +++ b/analytical/tests/__init__.py @@ -6,6 +6,7 @@ from analytical.tests.test_tag_analytical import * from analytical.tests.test_tag_chartbeat import * from analytical.tests.test_tag_clicky import * from analytical.tests.test_tag_crazy_egg import * +from analytical.tests.test_tag_gauges import * from analytical.tests.test_tag_google_analytics import * from analytical.tests.test_tag_gosquared import * from analytical.tests.test_tag_hubspot import * diff --git a/analytical/tests/test_tag_gauges.py b/analytical/tests/test_tag_gauges.py new file mode 100644 index 0000000..95c0806 --- /dev/null +++ b/analytical/tests/test_tag_gauges.py @@ -0,0 +1,72 @@ +""" +Tests for the Gauges template tags and filters. +""" + +from django.http import HttpRequest +from django.template import Context + +from analytical.templatetags.gauges import GaugesNode +from analytical.tests.utils import TagTestCase, override_settings, SETTING_DELETED +from analytical.utils import AnalyticalException + + +@override_settings(GAUGES_SITE_ID='1234567890abcdef0123456789') +class GaugesTagTestCase(TagTestCase): + """ + Tests for the ``gauges`` template tag. + """ + + def test_tag(self): + self.assertEqual(""" + +""", + self.render_tag('gauges', 'gauges')) + + def test_node(self): + self.assertEqual( + """ + +""", + GaugesNode().render(Context())) + + @override_settings(GAUGES_SITE_ID=SETTING_DELETED) + def test_no_account_number(self): + self.assertRaises(AnalyticalException, GaugesNode) + + @override_settings(GAUGES_SITE_ID='123abQ') + def test_wrong_account_number(self): + self.assertRaises(AnalyticalException, GaugesNode) + + @override_settings(ANALYTICAL_INTERNAL_IPS=['1.1.1.1']) + def test_render_internal_ip(self): + req = HttpRequest() + req.META['REMOTE_ADDR'] = '1.1.1.1' + context = Context({'request': req}) + r = GaugesNode().render(context) + self.assertTrue(r.startswith( + ''), r) diff --git a/docs/install.rst b/docs/install.rst index cdb2ea6..2d3e24f 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -111,6 +111,10 @@ settings required to enable each service are listed here: CRAZY_EGG_ACCOUNT_NUMBER = '12345678' +* :doc:`Gaug.es `:: + + GAUGES_SITE_ID = '0123456789abcdef0123456789abcdef' + * :doc:`Google Analytics `:: GOOGLE_ANALYTICS_PROPERTY_ID = 'UA-1234567-8' diff --git a/docs/services/gauges.rst b/docs/services/gauges.rst new file mode 100644 index 0000000..7f81610 --- /dev/null +++ b/docs/services/gauges.rst @@ -0,0 +1,92 @@ +============================= +Gaug.es -- Real-time tracking +============================= + +Gaug.es_ is an easy way to implement real-time tracking for multiple websites. + +.. _Gaug.es: http://www.gaug.es/ + + +.. gauges-installation: + +Installation +============ + +To start using the Gaug.es 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 Gaug.es 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:`gauges-configuration`. + +The Gaug.es Javascript code is inserted into templates using a +template tag. Load the :mod:`gauges` template tag library and +insert the :ttag:`gauges` 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 at the top of the HTML head:: + + {% load gauges %} + + + {% gauges %} + ... + + +.. _gauges-configuration: + +Configuration +============= + +Before you can use the Gaug.es integration, you must first set your +site id. + + +.. _gauges-site-id: + +Setting the site id +-------------------------- + +Gaug.es gives you a unique site ide, and the :ttag:`gauges` +tag will include it in the rendered Javascript code. You can find your +site id by clicking the *Tracking Code* link when logged into +the on the gaug.es website. A page will display containing +HTML code looking like this:: + + + +The code ``XXXXXXXXXXXXXXXXXXXXXXX`` is your site id. Set +:const:`GAUGES_SITE_ID` in the project :file:`settings.py` +file:: + + GAUGES_SITE_ID = 'XXXXXXXXXXXXXXXXXXXXXXX' + +If you do not set an site id, the Javascript code will not be +rendered. + + +.. _gauges-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:`ANALYTICAL_INTERNAL_IPS` setting +(which is :const:`INTERNAL_IPS` by default,) the tracking code is +commented out. See :ref:`identifying-visitors` for important information +about detecting the visitor IP address.