From 1709428cfff54e8db23ed52a0a1ff950566b89ad Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Bodas Date: Wed, 7 Jul 2021 20:25:25 +0530 Subject: [PATCH] models: Create MissedMessageEmailEntry table. This will be used to store the missedmessage events received during the waiting time for email notifications (which is currently 2 minutes, hardcoded). The change in `test_retention` is because we've set `on_delete=CASCADE` for the message field this table. The new query is like so: ``` DELETE FROM "zerver_missedmessageemailentry" WHERE "zerver_missedmessageemailentry"."message_id" IN ( 1545, 1546, 1547, 1548, 1549, 1550, 1551, 1552, 1553 ) ``` --- zerver/lib/export.py | 3 + .../0331_scheduledmessagenotificationemail.py | 58 +++++++++++++++++++ zerver/models.py | 27 +++++++++ zerver/tests/test_retention.py | 2 +- 4 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 zerver/migrations/0331_scheduledmessagenotificationemail.py diff --git a/zerver/lib/export.py b/zerver/lib/export.py index f9be12ec65..5bf477a70f 100644 --- a/zerver/lib/export.py +++ b/zerver/lib/export.py @@ -146,6 +146,7 @@ ALL_ZULIP_TABLES = { "zerver_scheduledemail", "zerver_scheduledemail_users", "zerver_scheduledmessage", + "zerver_scheduledmessagenotificationemail", "zerver_service", "zerver_stream", "zerver_submessage", @@ -182,6 +183,8 @@ NON_EXPORTED_TABLES = { # missed-message email addresses include the server's hostname and # expire after a few days. "zerver_missedmessageemailaddress", + # Scheduled message notification email data is for internal use by the server. + "zerver_scheduledmessagenotificationemail", # When switching servers, clients will need to re-log in and # reregister for push notifications anyway. "zerver_pushdevicetoken", diff --git a/zerver/migrations/0331_scheduledmessagenotificationemail.py b/zerver/migrations/0331_scheduledmessagenotificationemail.py new file mode 100644 index 0000000000..18b2106da7 --- /dev/null +++ b/zerver/migrations/0331_scheduledmessagenotificationemail.py @@ -0,0 +1,58 @@ +# Generated by Django 3.2.5 on 2021-07-09 11:08 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("zerver", "0330_linkifier_pattern_validator"), + ] + + operations = [ + migrations.CreateModel( + name="ScheduledMessageNotificationEmail", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, primary_key=True, serialize=False, verbose_name="ID" + ), + ), + ( + "trigger", + models.TextField( + choices=[ + ("private_message", "Private message"), + ("mentioned", "Mention"), + ("wildcard_mentioned", "Wildcard mention"), + ("stream_email_notify", "Stream notifications enabled"), + ] + ), + ), + ("scheduled_timestamp", models.DateTimeField(db_index=True)), + ( + "mentioned_user_group", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="zerver.usergroup", + ), + ), + ( + "message", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="zerver.message" + ), + ), + ( + "user_profile", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL + ), + ), + ], + ), + ] diff --git a/zerver/models.py b/zerver/models.py index a8c420f9ae..bf2aa46df4 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -3340,6 +3340,33 @@ class NotificationTriggers: STREAM_EMAIL = "stream_email_notify" +class ScheduledMessageNotificationEmail(models.Model): + """Stores planned outgoing message notification emails. They may be + processed earlier should Zulip choose to batch multiple messages + in a single email, but typically will be processed just after + scheduled_timestamp. + """ + + user_profile: UserProfile = models.ForeignKey(UserProfile, on_delete=CASCADE) + message: Message = models.ForeignKey(Message, on_delete=CASCADE) + + EMAIL_NOTIFICATION_TRIGGER_CHOICES = [ + (NotificationTriggers.PRIVATE_MESSAGE, "Private message"), + (NotificationTriggers.MENTION, "Mention"), + (NotificationTriggers.WILDCARD_MENTION, "Wildcard mention"), + (NotificationTriggers.STREAM_EMAIL, "Stream notifications enabled"), + ] + + trigger: str = models.TextField(choices=EMAIL_NOTIFICATION_TRIGGER_CHOICES) + mentioned_user_group: Optional[UserGroup] = models.ForeignKey( + UserGroup, null=True, on_delete=CASCADE + ) + + # Timestamp for when the notification should be processed and sent. + # Calculated from the time the event was received and the batching period. + scheduled_timestamp: datetime.datetime = models.DateTimeField(db_index=True) + + class ScheduledMessage(models.Model): id: int = models.AutoField(auto_created=True, primary_key=True, verbose_name="ID") sender: UserProfile = models.ForeignKey(UserProfile, on_delete=CASCADE) diff --git a/zerver/tests/test_retention.py b/zerver/tests/test_retention.py index 177064af83..1e52f61f19 100644 --- a/zerver/tests/test_retention.py +++ b/zerver/tests/test_retention.py @@ -1056,7 +1056,7 @@ class TestDoDeleteMessages(ZulipTestCase): with queries_captured() as queries: do_delete_messages(realm, messages) self.assertFalse(Message.objects.filter(id__in=message_ids).exists()) - self.assert_length(queries, 18) + self.assert_length(queries, 19) archived_messages = ArchivedMessage.objects.filter(id__in=message_ids) self.assertEqual(archived_messages.count(), len(message_ids))