Merge branch 'master' into feature/WXP-53-front-end-segment-bouwer
# Conflicts: # src/personalisation/wagtail_hooks.py
This commit is contained in:
2
Makefile
2
Makefile
@ -25,7 +25,7 @@ flake8:
|
|||||||
|
|
||||||
isort:
|
isort:
|
||||||
pip install isort
|
pip install isort
|
||||||
isort --recursive --check-only --diff src tests
|
isort --recursive src tests
|
||||||
|
|
||||||
|
|
||||||
dist:
|
dist:
|
||||||
|
@ -2,15 +2,19 @@ from django.contrib import admin
|
|||||||
|
|
||||||
from personalisation import models
|
from personalisation import models
|
||||||
|
|
||||||
|
|
||||||
class TimeRuleAdmin(admin.ModelAdmin):
|
class TimeRuleAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'start_time', 'end_time')
|
list_display = ('name', 'start_time', 'end_time')
|
||||||
|
|
||||||
class TimeRuleAdminInline(admin.TabularInline):
|
class TimeRuleAdminInline(admin.TabularInline):
|
||||||
model = models.TimeRule
|
model = models.TimeRule
|
||||||
|
|
||||||
|
class ReferralRuleAdminInline(admin.TabularInline):
|
||||||
|
model = models.ReferralRule
|
||||||
|
|
||||||
class SegmentAdmin(admin.ModelAdmin):
|
class SegmentAdmin(admin.ModelAdmin):
|
||||||
list_display = ['name']
|
list_display = ['name']
|
||||||
inlines = (TimeRuleAdminInline,)
|
inlines = (TimeRuleAdminInline, ReferralRuleAdminInline)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(models.TimeRule, TimeRuleAdmin)
|
admin.site.register(models.TimeRule, TimeRuleAdmin)
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
|
||||||
from personalisation import views
|
from personalisation import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^segment/(\d+)/$', views.overview, name='overview'),
|
url(r'^segment/(\d+)/$', views.overview, name='overview'),
|
||||||
]
|
]
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
from personalisation.models import Segment, AbstractBaseRule, TimeRule
|
from personalisation.models import AbstractBaseRule, Segment
|
||||||
|
|
||||||
|
|
||||||
class SegmentMiddleware(object):
|
class SegmentMiddleware(object):
|
||||||
"""Middleware for testing and putting a user in a segment"""
|
"""Middleware for testing and putting a user in a segment"""
|
||||||
@ -12,16 +13,31 @@ class SegmentMiddleware(object):
|
|||||||
chosen_segments = []
|
chosen_segments = []
|
||||||
|
|
||||||
for segment in segments:
|
for segment in segments:
|
||||||
result = False
|
|
||||||
rules = AbstractBaseRule.objects.filter(segment=segment).select_subclasses()
|
rules = AbstractBaseRule.objects.filter(segment=segment).select_subclasses()
|
||||||
for rule in rules:
|
result = self.test_rules(rules, request)
|
||||||
result = rule.test_user()
|
|
||||||
if result:
|
if result:
|
||||||
chosen_segments.append(segment.encoded_name())
|
self.add_segment_to_user(segment, request)
|
||||||
|
|
||||||
request.session['segments'] = chosen_segments
|
|
||||||
response = self.get_response(request)
|
response = self.get_response(request)
|
||||||
|
|
||||||
print(request.session['segments'])
|
print(request.session['segments'])
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def test_rules(self, rules, request):
|
||||||
|
for rule in rules:
|
||||||
|
result = rule.test_user(request)
|
||||||
|
|
||||||
|
if result is False:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def add_segment_to_user(self, segment, request):
|
||||||
|
if 'segments' not in request.session:
|
||||||
|
request.session['segments'] = []
|
||||||
|
|
||||||
|
if segment not in request.session['segments']:
|
||||||
|
request.session['segments'].append(segment.encoded_name())
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
# Generated by Django 1.10.3 on 2016-11-07 13:53
|
# Generated by Django 1.10.3 on 2016-11-07 13:53
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
# Generated by Django 1.10.3 on 2016-11-07 14:12
|
# Generated by Django 1.10.3 on 2016-11-07 14:12
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
24
src/personalisation/migrations/0005_referralrule.py
Normal file
24
src/personalisation/migrations/0005_referralrule.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.3 on 2016-11-08 07:47
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('personalisation', '0004_segment_status'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ReferralRule',
|
||||||
|
fields=[
|
||||||
|
('abstractbaserule_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='personalisation.AbstractBaseRule')),
|
||||||
|
('regex_string', models.TextField()),
|
||||||
|
],
|
||||||
|
bases=('personalisation.abstractbaserule',),
|
||||||
|
),
|
||||||
|
]
|
@ -1,14 +1,13 @@
|
|||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
from datetime import datetime, time
|
import re
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from modelcluster.models import ClusterableModel
|
|
||||||
from model_utils.managers import InheritanceManager
|
from model_utils.managers import InheritanceManager
|
||||||
|
from modelcluster.models import ClusterableModel
|
||||||
from wagtail.wagtailadmin.edit_handlers import FieldPanel
|
from wagtail.wagtailadmin.edit_handlers import FieldPanel
|
||||||
|
|
||||||
|
|
||||||
@ -36,7 +35,6 @@ class Segment(ClusterableModel):
|
|||||||
return "".join(self.name.lower().split())
|
return "".join(self.name.lower().split())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Base for creating rules to segment users with
|
Base for creating rules to segment users with
|
||||||
"""
|
"""
|
||||||
@ -57,7 +55,7 @@ class AbstractBaseRule(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Time rule to segment users with
|
Time rule to segment users based on a start and end time
|
||||||
"""
|
"""
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class TimeRule(AbstractBaseRule):
|
class TimeRule(AbstractBaseRule):
|
||||||
@ -67,9 +65,32 @@ class TimeRule(AbstractBaseRule):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(TimeRule, self).__init__(*args, **kwargs)
|
super(TimeRule, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def test_user(self, request=None):
|
def test_user(self, request):
|
||||||
current_time = datetime.now().time()
|
current_time = self.get_current_time()
|
||||||
starting_time = self.start_time
|
starting_time = self.start_time
|
||||||
ending_time = self.end_time
|
ending_time = self.end_time
|
||||||
|
|
||||||
return starting_time <= current_time <= ending_time
|
return starting_time <= current_time <= ending_time
|
||||||
|
|
||||||
|
def get_current_time(self):
|
||||||
|
"""Mockable function for testing purposes"""
|
||||||
|
return datetime.now().time()
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Referral rule to segment users based on a regex test
|
||||||
|
"""
|
||||||
|
class ReferralRule(AbstractBaseRule):
|
||||||
|
regex_string = models.TextField()
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super(ReferralRule, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def test_user(self, request):
|
||||||
|
pattern = re.compile(self.regex_string)
|
||||||
|
|
||||||
|
if 'HTTP_REFERER' in request.META:
|
||||||
|
referer = request.META['HTTP_REFERER']
|
||||||
|
if pattern.search(referer):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
@ -7,4 +7,4 @@ from django.shortcuts import render
|
|||||||
Segments overview
|
Segments overview
|
||||||
"""
|
"""
|
||||||
def overview(request):
|
def overview(request):
|
||||||
return render(request, 'wagtailadmin/segment.html')
|
return render(request, 'wagtailadmin/segment.html')
|
||||||
|
@ -1,15 +1,21 @@
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.conf.urls import include, url
|
from django.conf.urls import include, url
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
<<<<<<< HEAD
|
||||||
from wagtail.wagtailadmin import widgets
|
from wagtail.wagtailadmin import widgets
|
||||||
from wagtail.wagtailadmin.menu import MenuItem
|
from wagtail.wagtailadmin.menu import MenuItem
|
||||||
from wagtail.wagtailadmin.modal_workflow import render_modal_workflow
|
from wagtail.wagtailadmin.modal_workflow import render_modal_workflow
|
||||||
|
|
||||||
from personalisation import admin_urls
|
from personalisation import admin_urls
|
||||||
|
=======
|
||||||
|
>>>>>>> master
|
||||||
from wagtail.contrib.modeladmin.helpers import ButtonHelper
|
from wagtail.contrib.modeladmin.helpers import ButtonHelper
|
||||||
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
||||||
|
from wagtail.wagtailadmin import widgets
|
||||||
|
from wagtail.wagtailadmin.menu import MenuItem
|
||||||
from wagtail.wagtailcore import hooks
|
from wagtail.wagtailcore import hooks
|
||||||
|
|
||||||
|
from personalisation import admin_urls
|
||||||
from personalisation.models import Segment
|
from personalisation.models import Segment
|
||||||
|
|
||||||
|
|
||||||
|
12
tests/test_models.py
Normal file
12
tests/test_models.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from personalisation.models import TimeRule
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_create_time_rule():
|
||||||
|
time_rule = TimeRule(name='test', start_time="08:00:00", end_time="23:00:00")
|
||||||
|
|
||||||
|
with mock.patch('TimeRule.get_current_time', return_value=datetime.time(10, 00, 00)):
|
||||||
|
assert time_rule.test_user() is True
|
Reference in New Issue
Block a user