"""Notification app models.""" from django.conf import settings from django.db import models from django.utils.translation import ugettext_lazy as _ from account.models import User from utils.methods import generate_string_code from utils.models import ProjectBaseMixin # todo: associate user & subscriber after users registration class SubscriberManager(models.Manager): """Extended manager for Subscriber model.""" def make_subscriber(self, email=None, user=None, ip_address=None, country_code=None, locale=None, *args, **kwargs): """Make subscriber and update info.""" # search existing object if not user: user = User.objects.filter(email=email).first() if user: obj = self.model.objects.filter(models.Q(user=user) | models.Q( email=user.email)).first() else: obj = self.model.objects.filter(email=email).first() # update or create if obj: if user: obj.user = user obj.email = None else: obj.email = email obj.ip_address = ip_address obj.country_code = country_code obj.locale = locale obj.state = self.model.USABLE obj.update_code = generate_string_code() obj.save() else: obj = self.model.objects.create(user=user, email=email, ip_address=ip_address, country_code=country_code, locale=locale) return obj def associate_user(self, user): """Associate user.""" obj = self.model.objects.filter(user=user).first() if obj is None: obj = self.model.objects.filter(email=user.email_confirmed, user__isnull=True).first() if obj: obj.user = user obj.email = None obj.save() return obj class SubscriberQuerySet(models.QuerySet): """Extended queryset for Subscriber model.""" def by_usable(self, switcher=True): if switcher: return self.filter(state=self.model.USABLE) else: return self.filter(state=self.model.UNUSABLE) class Subscriber(ProjectBaseMixin): """Subscriber model.""" UNUSABLE = 0 USABLE = 1 STATE_CHOICES = ( (UNUSABLE, _('Unusable')), (USABLE, _('Usable')), ) user = models.OneToOneField(User, blank=True, null=True, default=None, on_delete=models.SET_NULL, related_name='subscriber', verbose_name=_('User')) email = models.EmailField(blank=True, null=True, default=None, unique=True, verbose_name=_('Email')) ip_address = models.GenericIPAddressField(blank=True, null=True, default=None, verbose_name=_('IP address')) country_code = models.CharField(max_length=10, blank=True, null=True, default=None, verbose_name=_('Country code')) locale = models.CharField(blank=True, null=True, default=None, max_length=10, verbose_name=_('Locale identifier')) state = models.PositiveIntegerField(choices=STATE_CHOICES, default=USABLE, verbose_name=_('State')) update_code = models.CharField(max_length=254, blank=True, null=True, default=None, db_index=True, verbose_name=_('Token')) objects = SubscriberManager.from_queryset(SubscriberQuerySet)() class Meta: """Meta class.""" verbose_name = _('Subscriber') verbose_name_plural = _('Subscribers') def save(self, *args, **kwargs): """Overrided save method.""" if self.update_code is None: self.update_code = generate_string_code() return super(Subscriber, self).save(*args, **kwargs) def unsubscribe(self): """Unsubscribe user.""" self.state = self.UNUSABLE self.save() @property def send_to(self): """Actual email.""" return self.user.email if self.user else self.email @property def link_to_unsubscribe(self): """Link to unsubscribe.""" schema = settings.SCHEMA_URI site_domain = settings.SITE_DOMAIN_URI url = settings.SITE_REDIRECT_URL_UNSUBSCRIBE query = f'?code={self.update_code}' return f'{schema}://{site_domain}{url}{query}'