Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
django-branding / branding / models.py
Size: Mime:
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