emailnotification.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. from django.utils.translation import gettext as _
  2. from misago.acl import useracl
  3. from misago.core.mail import build_mail, send_messages
  4. from misago.threads.permissions import can_see_post, can_see_thread
  5. from . import PostingEndpoint, PostingMiddleware
  6. class EmailNotificationMiddleware(PostingMiddleware):
  7. def __init__(self, **kwargs):
  8. super().__init__(**kwargs)
  9. self.previous_last_post_on = self.thread.last_post_on
  10. def use_this_middleware(self):
  11. return self.mode == PostingEndpoint.REPLY
  12. def post_save(self, serializer):
  13. queryset = (
  14. self.thread.subscription_set.filter(
  15. send_email=True, last_read_on__gte=self.previous_last_post_on
  16. )
  17. .exclude(user=self.user)
  18. .select_related("user")
  19. )
  20. notifications = []
  21. for subscription in queryset.iterator():
  22. if self.subscriber_can_see_post(subscription.user):
  23. notifications.append(self.build_mail(subscription.user))
  24. if notifications:
  25. send_messages(notifications)
  26. def subscriber_can_see_post(self, subscriber):
  27. user_acl = useracl.get_user_acl(subscriber, self.request.cache_versions)
  28. see_thread = can_see_thread(user_acl, self.thread)
  29. see_post = can_see_post(user_acl, self.post)
  30. return see_thread and see_post
  31. def build_mail(self, subscriber):
  32. if subscriber.id == self.thread.starter_id:
  33. subject = _('%(user)s has replied to your thread "%(thread)s"')
  34. else:
  35. subject = _(
  36. '%(user)s has replied to thread "%(thread)s" that you are watching'
  37. )
  38. subject_formats = {"user": self.user.username, "thread": self.thread.title}
  39. return build_mail(
  40. subscriber,
  41. subject % subject_formats,
  42. "misago/emails/thread/reply",
  43. sender=self.user,
  44. context={
  45. "settings": self.request.settings,
  46. "thread": self.thread,
  47. "post": self.post,
  48. },
  49. )