Skip to content

Commit 5d07b03

Browse files
committed
Avoid skipping notification-sending for new entities created in gap-time
1 parent 78647bf commit 5d07b03

2 files changed

Lines changed: 45 additions & 18 deletions

File tree

api/management/commands/index_and_notify.py

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,18 @@
2525
from deployments.models import ERU, Personnel, PersonnelDeployment
2626
from main.sentry import SentryMonitor
2727
from notifications.hello import get_hello
28-
from notifications.models import RecordType, Subscription, SubscriptionType, SurgeAlert
28+
from notifications.models import (
29+
NotificationGUID,
30+
RecordType,
31+
Subscription,
32+
SubscriptionType,
33+
SurgeAlert,
34+
)
2935
from notifications.notification import send_notification
3036
from utils.elasticsearch import construct_es_data
3137

32-
time_5_minutes = timedelta(minutes=5)
38+
# avoid skipping new entities that were created during 2 consecutive runs, scheduled to every 5 minutes:
39+
time_9_minutes = timedelta(minutes=9)
3340
time_1_day = timedelta(days=1)
3441
time_1_week = timedelta(days=7) # for digest mode
3542
digest_time = int(10314) # weekday - hour - min for digest timing (5 minutes once a week, Monday dawn)
@@ -72,23 +79,23 @@ class Command(BaseCommand):
7279

7380
# Digest mode duration is 5 minutes once a week
7481
def is_digest_mode(self):
75-
today = datetime.utcnow().replace(tzinfo=timezone.utc)
82+
today = datetime.now(timezone.utc)
7683
weekdayhourmin = int(today.strftime("%w%H%M"))
7784
return digest_time <= weekdayhourmin and weekdayhourmin < digest_time + 5
7885

7986
def is_daily_checkup_time(self):
80-
today = datetime.utcnow().replace(tzinfo=timezone.utc)
87+
today = datetime.now(timezone.utc)
8188
hourmin = int(today.strftime("%H%M"))
8289
return daily_retro <= hourmin and hourmin < daily_retro + 5
8390

84-
def diff_5_minutes(self):
85-
return datetime.utcnow().replace(tzinfo=timezone.utc) - time_5_minutes
91+
def diff_9_minutes(self):
92+
return datetime.now(timezone.utc) - time_9_minutes
8693

8794
def diff_1_day(self):
88-
return datetime.utcnow().replace(tzinfo=timezone.utc) - time_1_day
95+
return datetime.now(timezone.utc) - time_1_day
8996

9097
def diff_1_week(self):
91-
return datetime.utcnow().replace(tzinfo=timezone.utc) - time_1_week
98+
return datetime.now(timezone.utc) - time_1_week
9299

93100
def gather_country_and_region(self, records):
94101
# Appeals only, since these have a single country/region
@@ -337,7 +344,7 @@ def get_record_display(self, rtype, count):
337344
return display
338345

339346
def get_weekly_digest_data(self, field):
340-
today = datetime.utcnow().replace(tzinfo=timezone.utc)
347+
today = datetime.now(timezone.utc)
341348
if field == "dref":
342349
return Appeal.objects.filter(end_date__gt=today, atype=0).count()
343350
elif field == "ea":
@@ -709,6 +716,11 @@ def construct_template_record(self, rtype, record):
709716
}
710717
return rec_obj
711718

719+
def has_recent_notificationguid_entry(self, mailtypes, since):
720+
if not mailtypes:
721+
return False
722+
return NotificationGUID.objects.filter(created_at__gte=since, email_type__in=mailtypes).exists()
723+
712724
def notify(self, records, rtype, stype, uid=None):
713725
record_count = 0
714726
if records:
@@ -781,6 +793,21 @@ def notify(self, records, rtype, stype, uid=None):
781793
if self.is_daily_checkup_time():
782794
subject += " [daily followup]"
783795

796+
mailtype_prefixes = [f"{RTYPE_NAMES[rtype]} notification"]
797+
if uid is None and rtype == RecordType.FIELD_REPORT:
798+
mailtype_prefixes = [
799+
f"{RTYPE_NAMES[rtype]} notification (non_ifrc)",
800+
f"{RTYPE_NAMES[rtype]} notification (ifrc)",
801+
]
802+
803+
mailtype_variants = [f"{prefix} - {subject}" for prefix in mailtype_prefixes]
804+
if record_count == 1 and rtype != RecordType.WEEKLY_DIGEST:
805+
mailtype_variants.extend([f"{prefix} - {subject}: {record_entries[0]['title']}" for prefix in mailtype_prefixes])
806+
807+
if self.has_recent_notificationguid_entry(mailtype_variants, self.diff_9_minutes()):
808+
logger.info("Skipping notification – already sent recently.")
809+
return
810+
784811
template_path = self.get_template()
785812
if rtype == RecordType.FIELD_REPORT or rtype == RecordType.APPEAL or rtype == RecordType.WEEKLY_DIGEST:
786813
template_path = self.get_template(rtype)
@@ -995,7 +1022,7 @@ def handle(self, *args, **options):
9951022
if self.is_digest_mode():
9961023
time_diff = self.diff_1_week() # in digest mode (once a week, for new_entities only) we use a bigger interval
9971024
else:
998-
time_diff = self.diff_5_minutes()
1025+
time_diff = self.diff_9_minutes()
9991026
time_diff_1_day = self.diff_1_day()
10001027

10011028
cond1 = Q(created_at__gte=time_diff)

api/test_scrapers.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def test_new_record_subscription(self):
4747
)
4848
notify = Notify()
4949
emails = notify.gather_subscribers(
50-
FieldReport.objects.filter(created_at__gte=notify.diff_5_minutes()),
50+
FieldReport.objects.filter(created_at__gte=notify.diff_9_minutes()),
5151
RecordType.NEW_EMERGENCIES, # FIELD_REPORT,
5252
SubscriptionType.NEW,
5353
)
@@ -70,7 +70,7 @@ def test_country_subscription(self):
7070
)
7171
notify = Notify()
7272
emails = notify.gather_subscribers(
73-
FieldReport.objects.filter(created_at__gte=notify.diff_5_minutes()),
73+
FieldReport.objects.filter(created_at__gte=notify.diff_9_minutes()),
7474
RecordType.NEW_EMERGENCIES, # FIELD_REPORT,
7575
SubscriptionType.NEW,
7676
)
@@ -93,7 +93,7 @@ def test_region_subscription(self):
9393
)
9494
notify = Notify()
9595
emails = notify.gather_subscribers(
96-
FieldReport.objects.filter(created_at__gte=notify.diff_5_minutes()),
96+
FieldReport.objects.filter(created_at__gte=notify.diff_9_minutes()),
9797
RecordType.NEW_EMERGENCIES, # FIELD_REPORT,
9898
SubscriptionType.NEW,
9999
)
@@ -116,7 +116,7 @@ def test_dtype_subscription(self):
116116
)
117117
notify = Notify()
118118
emails = notify.gather_subscribers(
119-
FieldReport.objects.filter(created_at__gte=notify.diff_5_minutes()),
119+
FieldReport.objects.filter(created_at__gte=notify.diff_9_minutes()),
120120
RecordType.NEW_EMERGENCIES, # FIELD_REPORT,
121121
SubscriptionType.NEW,
122122
)
@@ -165,7 +165,7 @@ def test_multiple_subscription(self):
165165

166166
notify = Notify()
167167
emails = notify.gather_subscribers(
168-
FieldReport.objects.filter(created_at__gte=notify.diff_5_minutes()),
168+
FieldReport.objects.filter(created_at__gte=notify.diff_9_minutes()),
169169
RecordType.NEW_EMERGENCIES, # FIELD_REPORT,
170170
SubscriptionType.NEW,
171171
)
@@ -197,7 +197,7 @@ def test_region_subscription(self):
197197
Subscription.objects.create(user=user, region=r, lookup_id="r%s" % r.id)
198198
notify = Notify()
199199
emails = notify.gather_subscribers(
200-
Appeal.objects.filter(created_at__gte=notify.diff_5_minutes()),
200+
Appeal.objects.filter(created_at__gte=notify.diff_9_minutes()),
201201
RecordType.APPEAL,
202202
SubscriptionType.NEW,
203203
)
@@ -217,7 +217,7 @@ def test_region_and_country_subscription(self):
217217
Subscription.objects.create(user=user, country=c, lookup_id="c%s" % c.id)
218218
notify = Notify()
219219
emails = notify.gather_subscribers(
220-
Appeal.objects.filter(created_at__gte=notify.diff_5_minutes()),
220+
Appeal.objects.filter(created_at__gte=notify.diff_9_minutes()),
221221
RecordType.APPEAL,
222222
SubscriptionType.NEW,
223223
)
@@ -239,6 +239,6 @@ def setUp(self):
239239

240240
def test_filter_just_created(self):
241241
notify = Notify()
242-
filtered = notify.filter_just_created(Appeal.objects.filter(created_at__gte=notify.diff_5_minutes()))
242+
filtered = notify.filter_just_created(Appeal.objects.filter(created_at__gte=notify.diff_9_minutes()))
243243
self.assertEqual(len(filtered), 1)
244244
self.assertEqual(filtered[0].aid, "test2")

0 commit comments

Comments
 (0)