57 lines
2.2 KiB
Python
57 lines
2.2 KiB
Python
from actstream.models import Action
|
|
from django.contrib.auth import get_user_model
|
|
from django.db import models
|
|
|
|
from constants.activity import Verb
|
|
from utils import absolutify
|
|
|
|
User = get_user_model()
|
|
|
|
|
|
class Notification(models.Model):
|
|
"""Notification records are created in Action's post_save signal.
|
|
When a user marks a notification as read, read_at is set.
|
|
send_notification_emails management command runs periodically in background and sends all
|
|
notifications that haven't been processed yet, read_at is not checked when sending emails.
|
|
email_sent flag is used only to record the fact that we attempted to send an email.
|
|
A user can unsubscribe from notification emails in their profile settings.
|
|
"""
|
|
|
|
recipient = models.ForeignKey(User, null=False, on_delete=models.CASCADE)
|
|
action = models.ForeignKey(Action, null=False, on_delete=models.CASCADE)
|
|
email_sent = models.BooleanField(default=False, null=False)
|
|
processed_by_mailer_at = models.DateTimeField(default=None, null=True)
|
|
read_at = models.DateTimeField(default=None, null=True)
|
|
|
|
class Meta:
|
|
indexes = [
|
|
models.Index(fields=['processed_by_mailer_at']),
|
|
models.Index(fields=['recipient', 'read_at']),
|
|
]
|
|
unique_together = ['recipient', 'action']
|
|
|
|
def format_email(self):
|
|
action = self.action
|
|
subject = f'New Activity: {action.actor.full_name} {action.verb} {action.target}'
|
|
url = self.get_absolute_url()
|
|
mesage = f'{action.actor.full_name} {action.verb} {action.target}: {url}'
|
|
return (subject, mesage)
|
|
|
|
def get_absolute_url(self):
|
|
if self.action.verb == Verb.RATED_EXTENSION:
|
|
url = self.action.target.get_ratings_url()
|
|
elif self.action.verb in [
|
|
Verb.APPROVED,
|
|
Verb.COMMENTED,
|
|
Verb.REQUESTED_CHANGES,
|
|
Verb.REQUESTED_REVIEW,
|
|
]:
|
|
url = self.action.target.get_review_url()
|
|
elif self.action.action_object is not None:
|
|
url = self.action.action_object.get_absolute_url()
|
|
else:
|
|
url = self.action.target.get_absolute_url()
|
|
|
|
# TODO? url cloacking to mark visited notifications as read automatically
|
|
return absolutify(url)
|