import time from django.db.models import F from personalisation.models import AbstractBaseRule, Segment class BaseSegmentsAdapter(object): def setup(self): return None def _test_rules(self, rules, request): if len(rules) > 0: for rule in rules: result = rule.test_user(request) if result is False: return False return True return False class Meta: abstract = True class SessionSegmentsAdapter(BaseSegmentsAdapter): def setup(self, request): self.request = request self.request.session.setdefault('segments', []) def get_all_segments(self): return self.request.session['segments'] def get_segment(self, segment_id): return next(item for item in self.request.session['segments'] if item.id == segment_id) def add(self, segment): def check_if_segmented(item): """Check if the user has been segmented""" return any(seg['encoded_name'] == item.encoded_name for seg in self.request.session['segments']) 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): current_segments = self.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']] self.request.session['segments'] = current_segments segments = Segment.objects.filter(status='enabled').prefetch_related('rules') for segment in segments: rules = AbstractBaseRule.__subclasses__() segment_rules = [] for rule in rules: segment_rules += rule.objects.filter(segment=segment) result = self._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 = F('visit_count') + 1 segment.save() def check_segment_exists(self, segment): segments = self.request.session['segments'] return any(item for item in segments if segment.pk == item.id)