Esempio n. 1
0
class Migration(migrations.Migration):

    dependencies = [
        ('dbmail', '0013_auto_20160923_2201'),
    ]

    operations = [
        migrations.AlterField(
            model_name='maillog',
            name='backend',
            field=models.CharField(choices=SORTED_BACKEND_CHOICES, db_index=True, default=b'mail', editable=False, max_length=25, verbose_name='Backend'),
        ),
        migrations.AlterField(
            model_name='mailsubscription',
            name='address',
            field=models.CharField(db_index=True, help_text='Must be phone number/email/token', max_length=350, verbose_name='Address'),
        ),
        migrations.AlterField(
            model_name='mailsubscription',
            name='backend',
            field=models.CharField(choices=BACKENDS_MODEL_CHOICES, default=BACKEND.get('mail'), max_length=50, verbose_name='Backend'),
        ),
        migrations.AlterField(
            model_name='mailsubscription',
            name='data',
            field=SubscriptionDataField(blank=True, default=dict, null=True),
        ),
        migrations.AlterField(
            model_name='mailsubscription',
            name='title',
            field=models.CharField(blank=True, max_length=350, null=True),
        ),
        migrations.AlterField(
            model_name='mailtemplate',
            name='category',
            field=models.ForeignKey(blank=True, default=2, null=True, on_delete=django.db.models.deletion.CASCADE, to='dbmail.MailCategory', verbose_name='Category'),
        ),
        migrations.AlterField(
            model_name='mailtemplate',
            name='from_email',
            field=models.ForeignKey(blank=True, default=2, help_text='If not specified, then used default.', null=True, on_delete=django.db.models.deletion.SET_NULL, to='dbmail.MailFromEmail', verbose_name='Message from'),
        ),
    ]
Esempio n. 2
0
class MailLog(models.Model):
    is_sent = models.BooleanField(_('Is sent'), default=True, db_index=True)
    template = models.ForeignKey(MailTemplate, verbose_name=_('Template'))
    created = models.DateTimeField(_('Created'), auto_now_add=True)
    user = models.ForeignKey(AUTH_USER_MODEL,
                             verbose_name=_('User'),
                             null=True,
                             blank=True)
    error_message = models.TextField(_('Error message'), null=True, blank=True)
    error_exception = models.ForeignKey(MailLogException,
                                        null=True,
                                        blank=True,
                                        verbose_name=_('Exception'))
    num_of_retries = models.PositiveIntegerField(_('Number of retries'),
                                                 default=1)
    log_id = models.CharField(_('Log ID'),
                              max_length=60,
                              editable=False,
                              db_index=True)
    backend = models.CharField(_('Backend'),
                               max_length=25,
                               editable=False,
                               db_index=True,
                               choices=BACKEND.items(),
                               default='mail')
    provider = models.CharField(_('Provider'),
                                max_length=250,
                                editable=False,
                                db_index=True,
                                default=None,
                                null=True,
                                blank=True)

    @staticmethod
    def store_email_log(log, email_list, mail_type):
        if log and email_list:
            for email in email_list:
                MailLogEmail.objects.create(log=log,
                                            email=email,
                                            mail_type=mail_type)

    @classmethod
    def store(cls,
              to,
              cc,
              bcc,
              is_sent,
              template,
              user,
              num,
              msg='',
              ex=None,
              log_id=None,
              backend=None,
              provider=None):
        if ex is not None:
            ex = MailLogException.objects.get_or_create(name=ex)[0]

        log = cls.objects.create(template=template,
                                 is_sent=is_sent,
                                 user=user,
                                 log_id=log_id,
                                 num_of_retries=num,
                                 error_message=msg,
                                 error_exception=ex,
                                 backend=_BACKEND[backend],
                                 provider=provider)
        cls.store_email_log(log, to, 'to')
        cls.store_email_log(log, cc, 'cc')
        cls.store_email_log(log, bcc, 'bcc')

    @classmethod
    def cleanup(cls, days=7):
        date = now() - datetime.timedelta(days=days)
        cls.objects.filter(created__lte=date).delete()

    def __unicode__(self):
        return self.template.name

    class Meta:
        verbose_name = _('Mail log')
        verbose_name_plural = _('Mail logs')
Esempio n. 3
0
class MailSubscriptionAbstract(models.Model):
    title = models.CharField(null=True, max_length=350, blank=True)

    user = models.ForeignKey(
        AUTH_USER_MODEL, verbose_name=_('User'), null=True, blank=True)
    backend = models.CharField(
        _('Backend'), choices=BACKENDS_MODEL_CHOICES, max_length=50,
        default=BACKEND.get('mail'))
    start_hour = models.CharField(
        _('Start hour'), default='00:00', max_length=5)
    end_hour = models.CharField(_('End hour'), default='23:59', max_length=5)
    is_enabled = models.BooleanField(
        _('Is enabled'), default=True, db_index=True)
    is_checked = models.BooleanField(
        _('Is checked'), default=False, db_index=True)
    defer_at_allowed_hours = models.BooleanField(
        _('Defer at allowed hours'), default=False)
    address = models.CharField(
        _('Address'), max_length=350, db_index=True,
        help_text=_('Must be phone number/email/token'))
    data = SubscriptionDataField(null=True, blank=True)

    def send_confirmation_link(
            self, slug='subs-confirmation', *args, **kwargs):

        from dbmail import db_sender

        kwargs['backend'] = self.backend
        db_sender(slug, self.address, *args, **kwargs)

    @staticmethod
    def get_now():
        d = timezone.now()
        if d.tzinfo:
            return timezone.localtime(timezone.now())
        return d

    @staticmethod
    def get_current_hour():
        current = MailSubscriptionAbstract.get_now()
        return datetime.timedelta(hours=current.hour, minutes=current.minute)

    @staticmethod
    def convert_to_date(value):
        hour, minute = value.split(':')
        return datetime.timedelta(hours=int(hour), minutes=int(minute))

    @classmethod
    def mix_hour_with_date(cls, value):
        return datetime.datetime.strptime(
            cls.get_now().strftime('%Y-%m-%d ') + value, '%Y-%m-%d %H:%M')

    @classmethod
    def get_notification_list(cls, user_id, **kwargs):
        kwargs.update({
            'is_enabled': True,
            'is_checked': True,
        })
        if user_id is not None:
            kwargs.update({
                'user_id': user_id,
            })
        return cls.objects.filter(**kwargs)

    @classmethod
    def notify(cls, slug, user_id=None, sub_filter=None, **kwargs):

        from dbmail import db_sender

        now_hour = cls.get_current_hour()

        context_dict = kwargs.pop('context', {})
        context_instance = kwargs.pop('context_instance', None)

        sub_filter = sub_filter if isinstance(sub_filter, dict) else {}

        for method_id in cls.get_notification_list(
                user_id, **sub_filter).values_list('pk', flat=True):

            method = cls.objects.get(pk=method_id)
            method_kwargs = kwargs.copy()

            method_kwargs['send_at_date'] = None
            start_hour = cls.convert_to_date(method.start_hour)
            end_hour = cls.convert_to_date(method.end_hour)

            if not (start_hour <= now_hour <= end_hour):
                if (method.defer_at_allowed_hours and
                        method_kwargs['use_celery']):

                    method_kwargs['send_at_date'] = cls.mix_hour_with_date(
                        method.start_hour)
                else:
                    continue
            method_kwargs['backend'] = method.backend
            method_kwargs = method.update_notify_kwargs(**method_kwargs)

            use_slug = method.get_final_slug(slug, method.get_short_type())

            db_sender(use_slug, method.address, context_dict,
                      context_instance, **method_kwargs)

    def update_notify_kwargs(self, **kwargs):
        return kwargs

    def get_final_slug(self, slug, _):
        for extra_slug in self.get_extra_slugs(slug):
            try:
                if MailTemplate.get_template(slug=extra_slug):
                    slug = extra_slug
                    break
            except MailTemplate.DoesNotExist:
                pass

        return slug

    def get_extra_slugs(self, slug):
        return [
            u'{}-{}'.format(slug, self.get_short_type()),
        ]

    def get_short_type(self):
        return self.backend.split('.')[-1]

    class Meta:
        abstract = True