Repository URL to install this package:
|
Version:
0.1.9 ▾
|
from __future__ import unicode_literals
from django.core.cache import cache
from django.db import models
from django.db.models import Q
from django.utils.translation import ugettext_lazy as _
import logging
import six
logger = logging.getLogger(__name__)
class BrandException(Exception):
pass
@six.python_2_unicode_compatible
class Brand(models.Model):
name = models.CharField(_('brand name'), max_length=64, unique=True)
sources = models.ManyToManyField('provider_network.ProviderSource', verbose_name=_('provided sources'), blank=True)
def __unicode__(self):
return self.name
def __str__(self):
return self.name
@classmethod
def from_request(cls, request, raise_exceptions=True):
client_brand_param = request.GET.get('override_brand', '').lower()
client_brand_header = request.META.get('HTTP_BRAND', '').lower()
client_brand = client_brand_param or client_brand_header
if not client_brand:
logger.info('A request with no brand was sent!')
if raise_exceptions:
raise BrandException('No brand set')
return None
try:
brand = cls.objects.get(name__iexact=client_brand)
except cls.DoesNotExist:
msg = 'Invalid brand: {}'.format(client_brand)
logger.info(msg)
if raise_exceptions:
raise BrandException(msg)
return None
return brand
@six.python_2_unicode_compatible
class Policy(models.Model):
number = models.CharField(_('policy number'), max_length=64, unique=True, help_text=_(
"Policies with this number will have access to certain booking backends. If this field is set to `*`, all "
"'policies will match, even empty ones. If it's set to `+`, all non-empty policies will match."
))
description = models.CharField(
_('Description'),
max_length=50,
help_text=_("Helpful description to make it easier to distinguish between policies"),
null=True,
blank=True
)
booking_backends = models.ManyToManyField('provider_network.OnlineBookingBackend', verbose_name='booking_backends',
blank=True, related_name='policies_with_access')
class Meta:
verbose_name = _('policy')
verbose_name_plural = _('policies')
def match(self, policy):
if self.number == '*':
return True
if self.number == '+':
return policy is not None and len(policy) > 0
return policy == self.number
def __eq__(self, other):
return isinstance(other, Policy) and self.number == other.number
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash(self.number)
def __str__(self):
if self.description:
return "{} ({})".format(self.description, self.number)
return self.number
@six.python_2_unicode_compatible
class FeatureAccess(models.Model):
keyword = models.CharField(max_length=20, help_text=_("Keyword used to identify this permission"))
description = models.CharField(max_length=200, help_text=_("Description that explains the purpose of this access permission"), editable=False)
policies = models.ManyToManyField(Policy, blank=True)
brands = models.ManyToManyField(Brand, blank=True)
@staticmethod
def has_access(permission, policy='*', brand='*'):
if isinstance(policy, Policy):
policy = policy.number
if isinstance(brand, Brand):
brand = brand.name
cached_access = cache.get("featureaccess_{}_{}_{}".format(permission, policy, brand))
if cached_access is None:
cached_access = FeatureAccess.objects.filter(
Q(keyword=permission) &
(Q(policies__number='*') | Q(policies__number=policy)) &
(Q(brands__name='*') | Q(brands__name=brand))
).count() > 0
cache.set("featureaccess_{}_{}_{}".format(permission, policy, brand), cached_access, 30)
return cached_access
def __str__(self):
return self.keyword