def feeds_fanout_replied(action): """Distribute notifications about a comment being replied to.""" # Fan out notification to parent Comment followers for follower in models_actstream.followers( action.action_object.parent_comment): if action.actor == follower: # If the reply author is the same as the parent comment author log.debug('Skipping notification generation for comment owner') continue log.debug('Generating notification for user %i about reply %i' % (follower.id, action.action_object.id)) follower.feed_entries.create(action=action) # Email notification content_name = truncatechars(action.action_object.entity.title, 15) content_text = truncatechars(action.action_object.content, 25) reply_context = dillo.views.emails.CommentOrReplyContext( subject='Your comment has a new reply!', own_name=follower.profile.first_name_guess or follower.username, own_profile_absolute_url=follower.profile.absolute_url, action_author_name=action.actor.profile.first_name_guess or action.actor.username, action_author_absolute_url=action.actor.profile.absolute_url, content_name=content_name, content_absolute_url=action.action_object.absolute_url, content_text=content_text, ).as_dict send_notification_mail( f'Your comment has a new reply!', follower, template='reply', context=reply_context, )
def feeds_fanout_commented(action): # Fan out notification to Post followers for follower in models_actstream.followers(action.action_object.entity): if action.actor == follower: log.debug('Skipping notification generation post owner') continue log.debug('Generating notification for user %i about comment %i' % (follower.id, action.action_object.id)) follower.feed_entries.create(action=action) # Email notification content_name = truncatechars(action.action_object.entity.title, 15) content_text = truncatechars(action.action_object.content, 25) comment_context = dillo.views.emails.CommentOrReplyContext( subject='Your post has a new comment!', own_name=follower.profile.first_name_guess or follower.username, own_profile_absolute_url=follower.profile.absolute_url, action_author_name=action.actor.profile.first_name_guess or action.actor.username, action_author_absolute_url=action.actor.profile.absolute_url, content_name=content_name, content_absolute_url=action.action_object.absolute_url, content_text=content_text, ).as_dict send_notification_mail( f'Your post "{content_name}" has a new comment', follower, template='comment', context=comment_context, )
def preview_email_send(request, email_template): from dillo.tasks.emails import send_notification_mail log.debug("Sending '%s' mail message to %s" % (email_template, request.user.email)) send_notification_mail( subject=f'Test email for {email_template}', recipient=request.user, template=email_template, context=email_templates[email_template], ) message = f'Mail preview for {email_template} sent to {request.user.email}' messages.add_message(request, messages.INFO, message) log.debug(message) return redirect(reverse('preview_email_template_list'))
def feeds_fanout_liked(action): # Do not notify user of own activity content_type = ContentType.objects.get_for_model(action.action_object) if content_type.name not in {'post', 'comment'}: log.error('Attempting to fanout a %s' % content_type) return recipient: User = action.action_object.user if action.actor == recipient: return # Fanout like notifications (only to owner) log.debug('Update notification feed about like') dillo.models.feeds.FeedEntry.objects.create( user=recipient, action=action, ) # Email notifications log.debug('Sending notification email to user %i', recipient.id) if content_type.name == 'post': content_name = action.action_object.title else: # The only other possible case is 'comment' content_name = action.action_object.content # Prepare attributes content_name = truncatechars(content_name, 15) like_context = dillo.views.emails.LikeContext( subject=f'They love your {content_type.name}!', content_type=content_type.name, own_name=recipient.profile.first_name_guess or recipient.username, action_author_name=action.actor.profile.first_name_guess or action.actor.username, action_author_absolute_url=action.actor.profile.absolute_url, content_name=content_name, content_absolute_url=action.action_object.absolute_url, ).as_dict send_notification_mail( f'Your {content_type.name} has a new like!', recipient, template='like', context=like_context, )
def feeds_fanout_started_following(action): originally_target_content_type = ContentType.objects.get_for_model( action.target) originally_target = action.target # This addresses an issue in the actstream package. The 'started following' # activities uses the incorrect semantics <actor> <verb> <target> instead of # <actor> <verb> <object>. In order to fix this, and have notifications to # read correctly, we update the action object by moving the target to the # action_object property. We use the update method so we don't trigger a # new notification. log.debug('Moving misplaced target into action_object') models_actstream.Action.objects.filter(pk=action.id).update( target_object_id=None, target_content_type_id=None, action_object_object_id=originally_target.id, action_object_content_type_id=originally_target_content_type.id, ) # If user followed another user, notify the followed user # Notifications will only be generated from User-related activities if originally_target_content_type.model_class() != User: return # Count existing activities with the same actor and object actions_count = models_actstream.Action.objects.filter( action_object_object_id=originally_target.id, action_object_content_type_id=originally_target_content_type.id, actor_object_id=action.actor.id, actor_content_type_id=ContentType.objects.get_for_model( action.actor).id, ).count() # If the action already exists (i.e. user followed, then unfollowed a user) # do not generate another notification if actions_count > 1: log.debug( 'Skipping generation of follow notification, it exists already') return # Create notification log.debug('Generating follow notification for user %i' % action.target.id) action.target.feed_entries.create(action=action) # Email notification follow_context = dillo.views.emails.FollowContext( subject='You have a new follower!', own_name=action.target.profile.first_name_guess or action.target.username, own_profile_absolute_url=action.target.profile.absolute_url, action_author_name=action.actor.profile.first_name_guess or action.actor.username, action_author_absolute_url=action.actor.profile.absolute_url, ).as_dict send_notification_mail( f'You have a new follower!', action.target, template='follow', context=follow_context, )
def test_notification_with_no_valid_template(self): send_notification_mail('Fail mail', self.user_harry, 'invalid', context={}) self.assertEqual(len(mail.outbox), 0)