adds adapter logic to wagtail hook
This commit is contained in:
@@ -30,7 +30,7 @@ To change the segments adapter, first make a new one based on the ``BaseSegments
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
class YourSegmentsAdapter(BaseSegmentsAdapter):
|
class YourSegmentsAdapter(BaseSegmentsAdapter):
|
||||||
# Add your own logic here
|
# Add your own logic here
|
||||||
|
|
||||||
Add the ``PERSONALISATION_SEGMENTS_ADAPTER`` setting to your settings.py and choose your own adapter.
|
Add the ``PERSONALISATION_SEGMENTS_ADAPTER`` setting to your settings.py and choose your own adapter.
|
||||||
|
@@ -1,8 +1,10 @@
|
|||||||
from personalisation.models import Segment
|
import time
|
||||||
|
|
||||||
|
from personalisation.models import AbstractBaseRule, Segment
|
||||||
|
|
||||||
class BaseSegmentsAdapter(object):
|
class BaseSegmentsAdapter(object):
|
||||||
"""Base adapter with required functions predefined"""
|
"""Base adapter with required functions predefined"""
|
||||||
def __init__(self):
|
def setup(self):
|
||||||
return
|
return
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
@@ -24,7 +26,7 @@ class BaseSegmentsAdapter(object):
|
|||||||
class SessionSegmentsAdapter(BaseSegmentsAdapter):
|
class SessionSegmentsAdapter(BaseSegmentsAdapter):
|
||||||
"""Segments adapter that uses Django's SessionMiddleware to store segments"""
|
"""Segments adapter that uses Django's SessionMiddleware to store segments"""
|
||||||
# Setup
|
# Setup
|
||||||
def __init__(self, request):
|
def setup(self, request):
|
||||||
self.request = request
|
self.request = request
|
||||||
|
|
||||||
# Set up segments dictionary object in the session
|
# Set up segments dictionary object in the session
|
||||||
@@ -37,7 +39,21 @@ class SessionSegmentsAdapter(BaseSegmentsAdapter):
|
|||||||
|
|
||||||
# Add segments
|
# Add segments
|
||||||
def add(self, segment):
|
def add(self, segment):
|
||||||
self.request.session['segments'].append(segment)
|
def check_if_segmented(item):
|
||||||
|
"""Check if the user has been segmented"""
|
||||||
|
for seg in self.request.session['segments']:
|
||||||
|
if seg['encoded_name'] == item.encoded_name():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not check_if_segmented(segment):
|
||||||
|
segdict = {
|
||||||
|
"encoded_name": segment.encoded_name(),
|
||||||
|
"id": segment.pk,
|
||||||
|
"timestamp": int(time.time()),
|
||||||
|
"persistent": segment.persistent,
|
||||||
|
}
|
||||||
|
self.request.session['segments'].append(segdict)
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
current_segments = self.request.session['segments']
|
current_segments = self.request.session['segments']
|
||||||
@@ -48,8 +64,41 @@ class SessionSegmentsAdapter(BaseSegmentsAdapter):
|
|||||||
|
|
||||||
self.request.session['segments'] = current_segments
|
self.request.session['segments'] = current_segments
|
||||||
|
|
||||||
|
segments = Segment.objects.all().filter(status='enabled')
|
||||||
|
|
||||||
|
for segment in segments:
|
||||||
|
rules = AbstractBaseRule.__subclasses__()
|
||||||
|
segment_rules = []
|
||||||
|
for rule in rules:
|
||||||
|
queried_rules = rule.objects.filter(segment=segment)
|
||||||
|
for result in queried_rules:
|
||||||
|
segment_rules.append(result)
|
||||||
|
result = _test_rules(segment_rules, self.request)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
self.add(segment)
|
||||||
|
|
||||||
|
|
||||||
|
for seg in self.request.session['segments']:
|
||||||
|
segment = Segment.objects.get(pk=seg['id'])
|
||||||
|
segment.visit_count = segment.visit_count + 1
|
||||||
|
segment.save()
|
||||||
|
|
||||||
# Quick checking logic to see if a segment exists
|
# Quick checking logic to see if a segment exists
|
||||||
def check_segment_exists(self, segment):
|
def check_segment_exists(self, segment):
|
||||||
segments = self.request.session['segments']
|
segments = self.request.session['segments']
|
||||||
|
|
||||||
return any(item for item in self.request.session['segments'] if segment.pk == item.id)
|
return any(item for item in self.request.session['segments'] if segment.pk == item.id)
|
||||||
|
|
||||||
|
|
||||||
|
def _test_rules(rules, request):
|
||||||
|
"""Test whether the user matches a segment's rules'"""
|
||||||
|
if len(rules) > 0:
|
||||||
|
for rule in rules:
|
||||||
|
result = rule.test_user(request)
|
||||||
|
|
||||||
|
if result is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
@@ -2,6 +2,5 @@ from django.conf import settings
|
|||||||
|
|
||||||
from personalisation.adapters import SessionSegmentsAdapter
|
from personalisation.adapters import SessionSegmentsAdapter
|
||||||
|
|
||||||
settings_adapter = getattr(settings, 'PERSONALISATION_SEGMENTS_ADAPTER', SessionSegmentsAdapter)
|
segments_adapter = getattr(settings, 'PERSONALISATION_SEGMENTS_ADAPTER', SessionSegmentsAdapter)
|
||||||
|
|
||||||
segments_adapter = settings_adapter()
|
|
||||||
|
@@ -13,11 +13,13 @@ from wagtail.wagtailadmin.widgets import (
|
|||||||
from wagtail.wagtailcore import hooks
|
from wagtail.wagtailcore import hooks
|
||||||
|
|
||||||
from personalisation import admin_urls
|
from personalisation import admin_urls
|
||||||
|
from personalisation.app_settings import segments_adapter
|
||||||
from personalisation.models import (AbstractBaseRule, PersonalisablePage,
|
from personalisation.models import (AbstractBaseRule, PersonalisablePage,
|
||||||
Segment)
|
Segment)
|
||||||
from personalisation.utils import impersonate_other_page
|
from personalisation.utils import impersonate_other_page
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
|
adapter = segments_adapter()
|
||||||
|
|
||||||
|
|
||||||
@hooks.register('register_admin_urls')
|
@hooks.register('register_admin_urls')
|
||||||
@@ -78,71 +80,9 @@ def set_visit_count(page, request, serve_args, serve_kwargs):
|
|||||||
|
|
||||||
@hooks.register('before_serve_page')
|
@hooks.register('before_serve_page')
|
||||||
def segment_user(page, request, serve_args, serve_kwargs):
|
def segment_user(page, request, serve_args, serve_kwargs):
|
||||||
if 'segments' not in request.session:
|
# Always run setup first on each segment, should have logic to not overwrite
|
||||||
request.session['segments'] = []
|
adapter.setup(request)
|
||||||
|
adapter.refresh()
|
||||||
current_segments = request.session['segments']
|
|
||||||
persistent_segments = Segment.objects.filter(persistent=True)
|
|
||||||
|
|
||||||
current_segments = [item for item in current_segments if any(seg.pk for seg in persistent_segments) == item['id']]
|
|
||||||
|
|
||||||
request.session['segments'] = current_segments
|
|
||||||
|
|
||||||
segments = Segment.objects.all().filter(status='enabled')
|
|
||||||
|
|
||||||
for segment in segments:
|
|
||||||
rules = AbstractBaseRule.__subclasses__()
|
|
||||||
segment_rules = []
|
|
||||||
for rule in rules:
|
|
||||||
queried_rules = rule.objects.filter(segment=segment)
|
|
||||||
for result in queried_rules:
|
|
||||||
segment_rules.append(result)
|
|
||||||
result = _test_rules(segment_rules, request)
|
|
||||||
|
|
||||||
if result:
|
|
||||||
_add_segment_to_user(segment, request)
|
|
||||||
|
|
||||||
if request.session['segments']:
|
|
||||||
logger.info("User has been added to the following segments: {}"
|
|
||||||
.format(request.session['segments']))
|
|
||||||
|
|
||||||
for seg in request.session['segments']:
|
|
||||||
segment = Segment.objects.get(pk=seg['id'])
|
|
||||||
segment.visit_count = segment.visit_count + 1
|
|
||||||
segment.save()
|
|
||||||
|
|
||||||
|
|
||||||
def _test_rules(rules, request):
|
|
||||||
"""Test whether the user matches a segment's rules'"""
|
|
||||||
if len(rules) > 0:
|
|
||||||
for rule in rules:
|
|
||||||
result = rule.test_user(request)
|
|
||||||
|
|
||||||
if result is False:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _add_segment_to_user(segment, request):
|
|
||||||
"""Save the segment in the user session"""
|
|
||||||
|
|
||||||
def check_if_segmented(segment):
|
|
||||||
"""Check if the user has been segmented"""
|
|
||||||
for seg in request.session['segments']:
|
|
||||||
if seg['encoded_name'] == segment.encoded_name():
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
if not check_if_segmented(segment):
|
|
||||||
segdict = {
|
|
||||||
"encoded_name": segment.encoded_name(),
|
|
||||||
"id": segment.pk,
|
|
||||||
"timestamp": int(time.time()),
|
|
||||||
"persistent": segment.persistent,
|
|
||||||
}
|
|
||||||
request.session['segments'].append(segdict)
|
|
||||||
|
|
||||||
|
|
||||||
@hooks.register('before_serve_page')
|
@hooks.register('before_serve_page')
|
||||||
|
Reference in New Issue
Block a user