7

Per page visit counting!

This commit is contained in:
Jasper Berghoef
2016-11-10 16:02:47 +01:00
parent 173c6b6b34
commit f74dad0b8b
5 changed files with 110 additions and 10 deletions

View File

@ -16,9 +16,11 @@ class SegmentMiddleware(object):
if request.path.startswith('/admin/') or request.path.startswith('/django-admin/'):
return self.get_response(request)
if 'visit_count' not in request.session:
request.session['visit_count'] = []
if 'segments' not in request.session:
request.session['segments'] = []
request.session['visit_count'] = 1
segments = Segment.objects.all().filter(status='enabled')
@ -30,6 +32,7 @@ class SegmentMiddleware(object):
self.add_segment_to_user(segment, request)
response = self.get_response(request)
logger.info("User has been added to the following segments: {}".format(request.session['segments']))
return response
@ -39,6 +42,19 @@ class SegmentMiddleware(object):
for rule in rules:
result = rule.test_user(request)
# Debug
if result and rule.__class__.__name__ == "TimeRule":
print("User segmented. Time between {} and {}.".format(
rule.start_time,
rule.end_time))
if result and rule.__class__.__name__ == "ReferralRule":
print("User segmented. Referral matches {}.".format(rule.regex_string))
if result and rule.__class__.__name__ == "VisitCountRule":
print("User segmented. Visited {} {} {} times.".format(
rule.counted_page,
rule.operator,
rule.count))
if result is False:
return False
@ -55,7 +71,6 @@ class SegmentMiddleware(object):
return False
if not check_if_segmented(segment):
# Clear segments session on browser close.
segdict = {
"encoded_name": segment.encoded_name(),
"id": segment.pk,

View File

@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-11-10 12:39
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('wagtailcore', '0030_index_on_pagerevision_created_at'),
('personalisation', '0021_auto_20161110_1325'),
]
operations = [
migrations.AddField(
model_name='visitcountrule',
name='counted_page',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='wagtailcore.Page'),
),
]

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.3 on 2016-11-10 13:54
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('personalisation', '0022_visitcountrule_counted_page'),
]
operations = [
migrations.AlterField(
model_name='visitcountrule',
name='counted_page',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='wagtailcore.Page'),
),
]

View File

@ -11,7 +11,7 @@ from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from modelcluster.models import ClusterableModel
from modelcluster.fields import ParentalKey
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, PageChooserPanel
from polymorphic.models import PolymorphicModel
@ -140,10 +140,18 @@ class VisitCountRule(AbstractBaseRule):
)
operator = models.CharField(max_length=20, choices=OPERATOR_CHOICES, default="ht")
count = models.PositiveSmallIntegerField(default=0, null=True)
counted_page = models.ForeignKey(
'wagtailcore.Page',
null=False,
blank=False,
on_delete=models.CASCADE,
related_name='+',
)
panels = [
FieldPanel('operator'),
FieldPanel('count'),
PageChooserPanel('counted_page'),
]
def __init__(self, *args, **kwargs):
@ -152,15 +160,26 @@ class VisitCountRule(AbstractBaseRule):
def test_user(self, request):
operator = self.operator
segment_count = self.count
visit_count = request.session.get('visit_count')
if operator == "more_than":
# TODO: Figure out a way to have a correct count before the middleware
# initiates the test function
def get_visit_count(request):
"""Search through the sessions to get the page visit count
corresponding to the request."""
for page in request.session['visit_count']:
if page['path'] == request.path:
return page['count']
visit_count = get_visit_count(request)
if visit_count and operator == "more_than":
if visit_count > segment_count:
return True
elif operator == "less_than":
elif visit_count and operator == "less_than":
if visit_count < segment_count:
return True
elif operator == "equal_to":
elif visit_count and operator == "equal_to":
if visit_count == segment_count:
return True
return False

View File

@ -1,3 +1,5 @@
import time
from django.conf.urls import include, url
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
from wagtail.contrib.modeladmin.views import IndexView
@ -34,12 +36,33 @@ modeladmin_register(SegmentModelAdmin)
@hooks.register('before_serve_page')
def set_visit_count(page, request, serve_args, serve_kwargs):
"""Update the users visit count before each page visit."""
# Update the segment visit count
for seg in request.session['segments']:
segment = Segment.objects.get(pk=seg['id'])
segment.visit_count = segment.visit_count + 1
segment.save()
if 'visit_count' not in request.session:
request.session['visit_count'] = 1
# Update the page visit count
def create_new_counter(page):
"""Create a new counter dict and place it in session storage."""
countdict = {
"slug": page.slug,
"id": page.pk,
"path": page.url,
"count": 1,
}
request.session['visit_count'].append(countdict)
if len(request.session['visit_count']) > 0:
for index, counter in enumerate(request.session['visit_count']):
if counter['id'] == page.pk:
# Counter already exisits. Increase the count value by 1.
newcount = counter['count'] + 1
request.session['visit_count'][index]['count'] = newcount
request.session.modified = True
else:
# Counter doesn't exist. Create a new counter with count value 1.
create_new_counter(page)
else:
request.session['visit_count'] = request.session.get('visit_count') + 1
# No counters exist. Create a new counter with count value 1.
create_new_counter(page)