extensions-website/notifications/models.py

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)