mirror of
https://github.com/jazzband/django-analytical.git
synced 2026-03-16 22:20:25 +00:00
Added conditional tracking consent for Matomo
Modified utils.build_paq_cmd to remove the trailing comma and white space as well as add a semi colon to the end of the push command. Added context_providers directory with matomo.py file with a context provider that builds the tracking consent code and adds it to the context. Modified matomo.MatomoNode.render. Removed original ugly settings check code with simply rendering the 'consent_script' context variable and adding it to the html variable only if its length is greater than 1. NOTE: The context provider and rendering it (line 110 templatetags/matomo.py) are untested. Both utils.build_paq_cmd and utils.get_event_bind_js are tested but need need more rigorous testing to be sure it won't break.
This commit is contained in:
parent
3a514444f3
commit
d1d1be189a
3 changed files with 54 additions and 29 deletions
34
analytical/context_providers/matomo.py
Normal file
34
analytical/context_providers/matomo.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import utils
|
||||
from django.conf import settings
|
||||
|
||||
def matomo_consent_provider(request):
|
||||
"""
|
||||
Add Mamoto consent script to the requests context.
|
||||
:Cases:
|
||||
- If MATOMO_REQURE_CONSENT is True OR If ALWAYS_TRACK_REGISTERED True == continue on
|
||||
- If ALWAYS_TRACK_REGISTERED is True AND the user is authenticated
|
||||
"""
|
||||
# Do we require consent?
|
||||
if getattr(settings, 'MATOMO_REQUIRE_CONSENT', False):
|
||||
provide_script = True
|
||||
if request.user.is_authenticated and not getattr(settings, "ALWAYS_TRACK_REGISTERED", True):
|
||||
provide_script = False
|
||||
if provide_script:
|
||||
grant_class_name = getattr(settings, 'GRANT_CONSENT_TAG_CLASSNAME')
|
||||
revoke_class_name = getattr(settings, 'REVOKE_CONSENT_CLASSNAME')
|
||||
return {"consent_script":"""
|
||||
%s;
|
||||
%s
|
||||
%s
|
||||
""" % (
|
||||
utils.build_paq_cmd('requireConsent'),
|
||||
utils.get_event_bind_js(
|
||||
class_name=grant_class_name,
|
||||
matomo_event="rememberConsentGiven",
|
||||
),
|
||||
utils.get_event_bind_js(
|
||||
class_name=revoke_class_name,
|
||||
matomo_event="forgetConsentGiven",
|
||||
)
|
||||
)}
|
||||
return {'consent_script': ""}
|
||||
|
|
@ -7,15 +7,12 @@ from collections import namedtuple
|
|||
from itertools import chain
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import Library, Node, TemplateSyntaxError
|
||||
|
||||
from django.template import Library, Node, TemplateSyntaxError, Template
|
||||
from analytical.utils import (
|
||||
disable_html,
|
||||
get_identity,
|
||||
get_required_setting,
|
||||
is_internal_ip,
|
||||
build_paq_cmd,
|
||||
get_event_bind_js
|
||||
is_internal_ip
|
||||
)
|
||||
|
||||
# domain name (characters separated by a dot), optional port, optional URI path, no slash
|
||||
|
|
@ -97,19 +94,6 @@ class MatomoNode(Node):
|
|||
if getattr(settings, 'MATOMO_DISABLE_COOKIES', False):
|
||||
commands.append(DISABLE_COOKIES_CODE)
|
||||
|
||||
if getattr(settings, "MATOMO_REQUIRE_CONSENT", False):
|
||||
grant_class_name = settings.GRANT_CONSENT_TAG_CLASSNAME
|
||||
revoke_class_name = settings.REVOKE_CONSENT_CLASSNAME
|
||||
commands.append(build_paq_cmd('requireConsent'))
|
||||
commands.append(get_event_bind_js(
|
||||
class_name=grant_class_name,
|
||||
matomo_event="rememberConsentGiven",
|
||||
))
|
||||
commands.append(get_event_bind_js(
|
||||
class_name=revoke_class_name,
|
||||
matomo_event="forgetConsentGiven",
|
||||
))
|
||||
|
||||
userid = get_identity(context, 'matomo')
|
||||
if userid is not None:
|
||||
variables_code = chain(variables_code, (
|
||||
|
|
@ -122,8 +106,14 @@ class MatomoNode(Node):
|
|||
'variables': '\n '.join(variables_code),
|
||||
'commands': '\n '.join(commands)
|
||||
}
|
||||
# Force the consent script to render so we can inject it into the template
|
||||
consent_script = Template("{{consent_script}}").render(context)
|
||||
if len(consent_script) > 1:
|
||||
html += consent_script
|
||||
|
||||
if is_internal_ip(context, 'MATOMO'):
|
||||
html = disable_html(html, 'Matomo')
|
||||
|
||||
return html
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -167,8 +167,8 @@ class AnalyticalException(Exception):
|
|||
def build_paq_cmd(cmd, args=[]):
|
||||
"""
|
||||
:Args:
|
||||
- cmd -> The command to be pushed to paq (i.e enableHeartbeatTimer or contentInteraction)
|
||||
- args -> Arguments to be added to the paq command. This is mainly
|
||||
- cmd: The command to be pushed to paq (i.e enableHeartbeatTimer or contentInteraction)
|
||||
- args: Arguments to be added to the paq command. This is mainly
|
||||
used when building commands to be used on manual event trigger.
|
||||
|
||||
:Returns:
|
||||
|
|
@ -176,12 +176,12 @@ def build_paq_cmd(cmd, args=[]):
|
|||
"""
|
||||
def __to_js_arg(arg):
|
||||
"""
|
||||
Turn 'arg' into its javascript counter-part
|
||||
:Args:
|
||||
- arg: The variable (Matomo argument) to be converted to JS.
|
||||
- arg: the argument that's to be passed to the array in _paq.push()
|
||||
:Return:
|
||||
Javascript version of the passed arg parameter
|
||||
The javascript counter-part to the argument that was passed
|
||||
"""
|
||||
# Recursively handle dictionaries
|
||||
if isinstance(arg, dict):
|
||||
arg_cpy = deepcopy(arg)
|
||||
for k, v in arg_cpy.items():
|
||||
|
|
@ -196,18 +196,20 @@ def build_paq_cmd(cmd, args=[]):
|
|||
elif isinstance(arg, list):
|
||||
for elem_idx in range(len(arg)):
|
||||
arg[elem_idx] = __to_js_arg(arg[elem_idx])
|
||||
|
||||
return arg
|
||||
|
||||
paq = "_paq.push(['%s', " % (cmd)
|
||||
paq = "_paq.push(['%s'" % (cmd)
|
||||
if len(args) > 0:
|
||||
paq += ", "
|
||||
for arg_idx in range(len(args)):
|
||||
current_arg = __to_js_arg(args[arg_idx])
|
||||
no_quotes = type(current_arg) in [bool, dict, list]
|
||||
no_quotes = type(current_arg) in [bool, int, dict, list]
|
||||
if arg_idx == len(args)-1:
|
||||
if no_quotes:
|
||||
segment = "%s])" % (current_arg)
|
||||
segment = "%s]);" % (current_arg)
|
||||
else:
|
||||
segment = "'%s'])" % (current_arg)
|
||||
segment = "'%s']);" % (current_arg)
|
||||
else:
|
||||
if no_quotes:
|
||||
segment = "%s, "% (current_arg)
|
||||
|
|
@ -215,7 +217,7 @@ def build_paq_cmd(cmd, args=[]):
|
|||
segment = "'%s', " % (current_arg)
|
||||
paq += segment
|
||||
else:
|
||||
paq += "])"
|
||||
paq += "]);"
|
||||
return paq
|
||||
|
||||
def get_event_bind_js(
|
||||
|
|
@ -248,4 +250,3 @@ def get_event_bind_js(
|
|||
}}
|
||||
""" % (class_name, js_event, build_paq_cmd(matomo_event, matomo_args))
|
||||
return script
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue