__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.fields import ArrayField
from .managers import MailLogQuerySet
MAIL_NOT_RENDERED, MAIL_RENDERED = 'not_rendered', 'rendered'
MAIL_SENT = 'sent'
MAIL_STATUSES = (
(MAIL_NOT_RENDERED, 'Not rendered'),
(MAIL_RENDERED, 'Rendered'),
(MAIL_SENT, 'Sent'),
)
[docs]class MailLog(models.Model):
"""
The MailLog table is meant as a container of mails.
Mails are not directly sent, but added to this table first.
Using a cronjob, the unsent messages are eventually sent using
the chosen MailBackend.
"""
processed = models.BooleanField(default=False)
status = models.CharField(max_length=16, choices=MAIL_STATUSES, default=MAIL_RENDERED)
mail_code = models.CharField(max_length=254, blank=True)
body = models.TextField()
body_html = models.TextField(blank=True)
to_recipients = ArrayField(
models.EmailField(),
blank=True, null=True)
bcc_recipients = ArrayField(
models.EmailField(),
blank=True, null=True)
from_email = models.CharField(max_length=254, blank=True)
subject = models.CharField(max_length=254, blank=True)
created = models.DateTimeField(auto_now_add=True)
latest_activity = models.DateTimeField(auto_now=True)
objects = MailLogQuerySet.as_manager()
def __str__(self):
return '{id}. {subject} ({count} recipients)'.format(
id=self.id,
subject=self.subject[:30],
count=len(self.to_recipients) + len(self.bcc_recipients))
[docs] def get_full_context(self):
"""Get the full template context needed to render the template."""
if hasattr(self, '_context'):
return self._context
self._context = {}
for relation in self.context.all():
self._context[relation.name] = relation.get_item()
return self._context
[docs]class MailLogRelation(models.Model):
"""
A template context item for the MailLog in case the a mail has delayed rendering.
This may be plain text or any relation within the database.
"""
mail = models.ForeignKey('mails.MailLog', on_delete=models.CASCADE, related_name='context')
name = models.CharField(max_length=254)
value = models.CharField(max_length=254, blank=True)
content_type = models.ForeignKey(ContentType, blank=True, null=True, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(blank=True, null=True)
content_object = GenericForeignKey('content_type', 'object_id')
[docs] def get_item(self):
if self.value:
return self.value
elif self.content_object:
return self.content_object
return None