def test_digest_unsubscribe(self): # type: () -> None """ We provide one-click unsubscribe links in digest e-mails that you can click even when logged out to stop receiving them. Unsubscribing from these emails also dequeues any digest email jobs that have been queued. """ email = "*****@*****.**" user_profile = get_user_profile_by_email("*****@*****.**") self.assertTrue(user_profile.enable_digest_emails) # Enqueue a fake digest email. send_digest_email(user_profile, "", "") self.assertEqual(1, len(ScheduledJob.objects.filter( type=ScheduledJob.EMAIL, filter_string__iexact=email))) # Simulate unsubscribing from digest e-mails. unsubscribe_link = one_click_unsubscribe_link(user_profile, "digest") result = self.client_get(urllib.parse.urlparse(unsubscribe_link).path) # The setting is toggled off, and scheduled jobs have been removed. self.assertEqual(result.status_code, 200) # Circumvent user_profile caching. user_profile = UserProfile.objects.get(email="*****@*****.**") self.assertFalse(user_profile.enable_digest_emails) self.assertEqual(0, len(ScheduledJob.objects.filter( type=ScheduledJob.EMAIL, filter_string__iexact=email)))
def test_missedmessage_unsubscribe(self): """ We provide one-click unsubscribe links in missed message e-mails that you can click even when logged out to update your email notification settings. """ user_profile = get_user_profile_by_email("*****@*****.**") user_profile.enable_offline_email_notifications = True user_profile.save() unsubscribe_link = one_click_unsubscribe_link(user_profile, "missed_messages") result = self.client.get(urllib.parse.urlparse(unsubscribe_link).path) self.assertEqual(result.status_code, 200) # Circumvent user_profile caching. user_profile = UserProfile.objects.get(email="*****@*****.**") self.assertFalse(user_profile.enable_offline_email_notifications)
def test_welcome_unsubscribe(self): """ We provide one-click unsubscribe links in welcome e-mails that you can click even when logged out to stop receiving them. """ email = "*****@*****.**" user_profile = get_user_profile_by_email("*****@*****.**") # Simulate a new user signing up, which enqueues 2 welcome e-mails. enqueue_welcome_emails(email, "King Hamlet") self.assertEqual(2, len(ScheduledJob.objects.filter( type=ScheduledJob.EMAIL, filter_string__iexact=email))) # Simulate unsubscribing from the welcome e-mails. unsubscribe_link = one_click_unsubscribe_link(user_profile, "welcome") result = self.client.get(urllib.parse.urlparse(unsubscribe_link).path) # The welcome email jobs are no longer scheduled. self.assertEqual(result.status_code, 200) self.assertEqual(0, len(ScheduledJob.objects.filter( type=ScheduledJob.EMAIL, filter_string__iexact=email)))
def handle_digest_email(user_profile_id, cutoff): # type: (int, int) -> None user_profile=UserProfile.objects.get(id=user_profile_id) # Convert from epoch seconds to a datetime object. cutoff_date = datetime.datetime.utcfromtimestamp(int(cutoff)) all_messages = UserMessage.objects.filter( user_profile=user_profile, message__pub_date__gt=cutoff_date).order_by("message__pub_date") # Start building email template data. template_payload = { 'name': user_profile.full_name, 'external_host': settings.EXTERNAL_HOST, 'external_uri_scheme': settings.EXTERNAL_URI_SCHEME, 'server_uri': settings.SERVER_URI, 'realm_uri': user_profile.realm.uri, 'unsubscribe_link': one_click_unsubscribe_link(user_profile, "digest") } # type: Dict[str, Any] # Gather recent missed PMs, re-using the missed PM email logic. # You can't have an unread message that you sent, but when testing # this causes confusion so filter your messages out. pms = all_messages.filter( ~Q(message__recipient__type=Recipient.STREAM) & \ ~Q(message__sender=user_profile)) # Show up to 4 missed PMs. pms_limit = 4 template_payload['unread_pms'] = build_message_list( user_profile, [pm.message for pm in pms[:pms_limit]]) template_payload['remaining_unread_pms_count'] = min(0, len(pms) - pms_limit) home_view_recipients = [sub.recipient for sub in \ Subscription.objects.filter( user_profile=user_profile, active=True, in_home_view=True)] stream_messages = all_messages.filter( message__recipient__type=Recipient.STREAM, message__recipient__in=home_view_recipients) # Gather hot conversations. template_payload["hot_conversations"] = gather_hot_conversations( user_profile, stream_messages) # Gather new streams. new_streams_count, new_streams = gather_new_streams( user_profile, cutoff_date) template_payload["new_streams"] = new_streams template_payload["new_streams_count"] = new_streams_count # Gather users who signed up recently. new_users_count, new_users = gather_new_users( user_profile, cutoff_date) template_payload["new_users"] = new_users text_content = loader.render_to_string( 'zerver/emails/digest/digest_email.txt', template_payload) html_content = loader.render_to_string( 'zerver/emails/digest/digest_email_html.txt', template_payload) # We don't want to send emails containing almost no information. if enough_traffic(template_payload["unread_pms"], template_payload["hot_conversations"], new_streams_count, new_users_count): logger.info("Sending digest email for %s" % (user_profile.email,)) send_digest_email(user_profile, html_content, text_content)
def handle_digest_email(user_profile_id: int, cutoff: float) -> None: user_profile = get_user_profile_by_id(user_profile_id) # We are disabling digest emails for soft deactivated users for the time. # TODO: Find an elegant way to generate digest emails for these users. if user_profile.long_term_idle: return None # Convert from epoch seconds to a datetime object. cutoff_date = datetime.datetime.fromtimestamp(int(cutoff), tz=pytz.utc) all_messages = UserMessage.objects.filter( user_profile=user_profile, message__pub_date__gt=cutoff_date).order_by("message__pub_date") context = common_context(user_profile) # Start building email template data. context.update({ 'realm_name': user_profile.realm.name, 'name': user_profile.full_name, 'unsubscribe_link': one_click_unsubscribe_link(user_profile, "digest") }) # Gather recent missed PMs, re-using the missed PM email logic. # You can't have an unread message that you sent, but when testing # this causes confusion so filter your messages out. pms = all_messages.filter( ~Q(message__recipient__type=Recipient.STREAM) & ~Q(message__sender=user_profile)) # Show up to 4 missed PMs. pms_limit = 4 context['unread_pms'] = build_message_list( user_profile, [pm.message for pm in pms[:pms_limit]]) context['remaining_unread_pms_count'] = min(0, len(pms) - pms_limit) home_view_recipients = [sub.recipient for sub in Subscription.objects.filter( user_profile=user_profile, active=True, in_home_view=True)] stream_messages = all_messages.filter( message__recipient__type=Recipient.STREAM, message__recipient__in=home_view_recipients) # Gather hot conversations. context["hot_conversations"] = gather_hot_conversations( user_profile, stream_messages) # Gather new streams. new_streams_count, new_streams = gather_new_streams( user_profile, cutoff_date) context["new_streams"] = new_streams context["new_streams_count"] = new_streams_count # Gather users who signed up recently. new_users_count, new_users = gather_new_users( user_profile, cutoff_date) context["new_users"] = new_users # We don't want to send emails containing almost no information. if enough_traffic(context["unread_pms"], context["hot_conversations"], new_streams_count, new_users_count): logger.info("Sending digest email for %s" % (user_profile.email,)) # Send now, as a ScheduledEmail send_future_email('zerver/emails/digest', user_profile.realm, to_user_id=user_profile.id, from_name="Zulip Digest", from_address=FromAddress.NOREPLY, context=context)
def handle_digest_email(user_profile_id, cutoff): user_profile = UserProfile.objects.get(id=user_profile_id) # Convert from epoch seconds to a datetime object. cutoff = datetime.datetime.utcfromtimestamp(int(cutoff)) all_messages = UserMessage.objects.filter( user_profile=user_profile, message__pub_date__gt=cutoff).order_by("message__pub_date") # Start building email template data. template_payload = { 'name': user_profile.full_name, 'external_host': settings.EXTERNAL_HOST, 'unsubscribe_link': one_click_unsubscribe_link(user_profile, "digest") } # Gather recent missed PMs, re-using the missed PM email logic. # You can't have an unread message that you sent, but when testing # this causes confusion so filter your messages out. pms = all_messages.filter( ~Q(message__recipient__type=Recipient.STREAM) & \ ~Q(message__sender=user_profile)) # Show up to 4 missed PMs. pms_limit = 4 template_payload['unread_pms'] = build_message_list( user_profile, [pm.message for pm in pms[:pms_limit]]) template_payload['remaining_unread_pms_count'] = min( 0, len(pms) - pms_limit) home_view_recipients = [sub.recipient for sub in \ Subscription.objects.filter( user_profile=user_profile, active=True, in_home_view=True)] stream_messages = all_messages.filter( message__recipient__type=Recipient.STREAM, message__recipient__in=home_view_recipients) # Gather hot conversations. template_payload["hot_conversations"] = gather_hot_conversations( user_profile, stream_messages) # Gather new streams. new_streams_count, new_streams = gather_new_streams(user_profile, cutoff) template_payload["new_streams"] = new_streams template_payload["new_streams_count"] = new_streams_count # Gather users who signed up recently. new_users_count, new_users = gather_new_users(user_profile, cutoff) template_payload["new_users"] = new_users text_content = loader.render_to_string( 'zerver/emails/digest/digest_email.txt', template_payload) html_content = loader.render_to_string( 'zerver/emails/digest/digest_email_html.txt', template_payload) # We don't want to send emails containing almost no information. if enough_traffic(template_payload["unread_pms"], template_payload["hot_conversations"], new_streams_count, new_users_count): logger.info("Sending digest email for %s" % (user_profile.email, )) send_digest_email(user_profile, html_content, text_content)
def handle_digest_email(user_profile_id, cutoff): # type: (int, float) -> None user_profile = UserProfile.objects.get(id=user_profile_id) # Convert from epoch seconds to a datetime object. cutoff_date = datetime.datetime.fromtimestamp(int(cutoff), tz=pytz.utc) all_messages = UserMessage.objects.filter( user_profile=user_profile, message__pub_date__gt=cutoff_date).order_by("message__pub_date") context = common_context(user_profile) # Start building email template data. context.update({ 'name': user_profile.full_name, 'unsubscribe_link': one_click_unsubscribe_link(user_profile, "digest") }) # Gather recent missed PMs, re-using the missed PM email logic. # You can't have an unread message that you sent, but when testing # this causes confusion so filter your messages out. pms = all_messages.filter(~Q(message__recipient__type=Recipient.STREAM) & ~Q(message__sender=user_profile)) # Show up to 4 missed PMs. pms_limit = 4 context['unread_pms'] = build_message_list( user_profile, [pm.message for pm in pms[:pms_limit]]) context['remaining_unread_pms_count'] = min(0, len(pms) - pms_limit) home_view_recipients = [ sub.recipient for sub in Subscription.objects.filter( user_profile=user_profile, active=True, in_home_view=True) ] stream_messages = all_messages.filter( message__recipient__type=Recipient.STREAM, message__recipient__in=home_view_recipients) # Gather hot conversations. context["hot_conversations"] = gather_hot_conversations( user_profile, stream_messages) # Gather new streams. new_streams_count, new_streams = gather_new_streams( user_profile, cutoff_date) context["new_streams"] = new_streams context["new_streams_count"] = new_streams_count # Gather users who signed up recently. new_users_count, new_users = gather_new_users(user_profile, cutoff_date) context["new_users"] = new_users # We don't want to send emails containing almost no information. if enough_traffic(context["unread_pms"], context["hot_conversations"], new_streams_count, new_users_count): logger.info("Sending digest email for %s" % (user_profile.email, )) # Send now, as a ScheduledJob send_future_email('zerver/emails/digest', display_email(user_profile), context=context)