Skip to content

Commit 179c151

Browse files
author
Sasha Romijn
committed
Fix ietf-tools#2231 - Send reminders before long UnavailabilityPeriods expire
A notification is sent to the team secretary and reviewer, if an unavailability period lasting 30 days or more will end in 3 days. Commit ready for merge. - Legacy-Id: 16704
1 parent 296b126 commit 179c151

4 files changed

Lines changed: 90 additions & 3 deletions

File tree

ietf/bin/send-review-reminders

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import datetime
2424
from ietf.review.utils import (
2525
review_assignments_needing_reviewer_reminder, email_reviewer_reminder,
2626
review_assignments_needing_secretary_reminder, email_secretary_reminder,
27-
)
27+
email_unavaibility_period_ending_reminder)
2828

2929
today = datetime.date.today()
3030

@@ -37,3 +37,5 @@ for assignment, secretary_role in review_assignments_needing_secretary_reminder(
3737
email_secretary_reminder(assignment.review_request, secretary_role)
3838
review_req = assignment.review_request
3939
print("Emailed reminder to {} for review of {} in {} (req. id {})".format(secretary_role.email.address, review_req.doc_id, review_req.team.acronym, review_req.pk))
40+
41+
print('\n'.join(email_unavaibility_period_ending_reminder(today)))

ietf/group/tests_review.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
review_assignments_needing_reviewer_reminder, email_reviewer_reminder,
2424
review_assignments_needing_secretary_reminder, email_secretary_reminder,
2525
reviewer_rotation_list,
26-
)
26+
email_unavaibility_period_ending_reminder)
2727
from ietf.name.models import ReviewResultName, ReviewRequestStateName, ReviewAssignmentStateName
2828
import ietf.group.views
2929
from ietf.utils.mail import outbox, empty_outbox
@@ -493,6 +493,58 @@ def test_review_reminders(self):
493493
self.assertEqual(len(outbox), 1)
494494
self.assertTrue(review_req.doc.name in outbox[0].get_payload(decode=True).decode("utf-8"))
495495

496+
def test_email_unavaibility_period_ending_reminder(self):
497+
review_team = ReviewTeamFactory(acronym="reviewteam", name="Review Team", type_id="review",
498+
list_email="reviewteam@ietf.org")
499+
reviewer = RoleFactory(group=review_team, person__user__username='reviewer',
500+
person__user__email='reviewer@example.com',
501+
person__name='Some Reviewer', name_id='reviewer')
502+
secretary = RoleFactory(group=review_team, person__user__username='reviewsecretary',
503+
person__user__email='reviewsecretary@example.com', name_id='secr')
504+
empty_outbox()
505+
today = datetime.date.today()
506+
UnavailablePeriod.objects.create(
507+
team=review_team,
508+
person=reviewer.person,
509+
start_date=today - datetime.timedelta(days=40),
510+
end_date=today + datetime.timedelta(days=3),
511+
availability="unavailable",
512+
)
513+
UnavailablePeriod.objects.create(
514+
team=review_team,
515+
person=reviewer.person,
516+
# This object should be ignored, length is too short
517+
start_date=today - datetime.timedelta(days=20),
518+
end_date=today + datetime.timedelta(days=3),
519+
availability="unavailable",
520+
)
521+
UnavailablePeriod.objects.create(
522+
team=review_team,
523+
person=reviewer.person,
524+
start_date=today - datetime.timedelta(days=40),
525+
# This object should be ignored, end date is too far away
526+
end_date=today + datetime.timedelta(days=4),
527+
availability="unavailable",
528+
)
529+
UnavailablePeriod.objects.create(
530+
team=review_team,
531+
person=reviewer.person,
532+
# This object should be ignored, end date is too close
533+
start_date=today - datetime.timedelta(days=40),
534+
end_date=today + datetime.timedelta(days=2),
535+
availability="unavailable",
536+
)
537+
log = email_unavaibility_period_ending_reminder(today)
538+
539+
self.assertEqual(len(outbox), 1)
540+
self.assertTrue(reviewer.person.email_address() in outbox[0]["To"])
541+
self.assertTrue(secretary.person.email_address() in outbox[0]["To"])
542+
message = outbox[0].get_payload(decode=True).decode("utf-8")
543+
self.assertTrue(reviewer.person.name in message)
544+
self.assertTrue(review_team.acronym in message)
545+
self.assertEqual(len(log), 1)
546+
self.assertTrue(reviewer.person.name in log[0])
547+
self.assertTrue(review_team.acronym in log[0])
496548

497549

498550
class BulkAssignmentTests(TestCase):

ietf/review/utils.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,6 @@ def email_reviewer_availability_change(request, team, reviewer_role, msg, by):
395395
"reviewer_overview_url": url,
396396
"reviewer": reviewer_role.person,
397397
"team": team,
398-
"msg": msg,
399398
"by": by,
400399
}, cc=cc)
401400

@@ -932,6 +931,33 @@ def format_period(p):
932931

933932
return [(r["email"].pk, r["label"]) for r in ranking]
934933

934+
935+
def email_unavaibility_period_ending_reminder(remind_date):
936+
reminder_days = 3
937+
end_date = remind_date + datetime.timedelta(days=reminder_days)
938+
min_start_date = end_date - datetime.timedelta(days=30)
939+
periods = UnavailablePeriod.objects.filter(start_date__lte=min_start_date, end_date=end_date)
940+
log = []
941+
for period in periods:
942+
(to, cc) = gather_address_lists('review_availability_changed', group=period.team, reviewer=period.person)
943+
domain = Site.objects.get_current().domain
944+
url = urlreverse("ietf.group.views.reviewer_overview", kwargs={ "group_type": period.team.type_id, "acronym": period.team.acronym })
945+
946+
subject = "Reminder: unavailability period of {} is ending soon".format(period.person)
947+
send_mail(None, to, None, subject, "review/reviewer_unavailability_ending.txt", {
948+
"reviewer_overview_url": "https://{}{}".format(domain, url),
949+
"reviewer": period.person,
950+
"team": period.team,
951+
"reminder_days": reminder_days,
952+
"period_start": period.start_date.isoformat(),
953+
"period_end": period.end_date.isoformat(),
954+
}, cc=cc)
955+
log.append("Emailed reminder to {} for ending of unavailability "
956+
"of {} in {} soon (unavailability period id {})".format(
957+
to, period.person, period.team.acronym,period.pk))
958+
return log
959+
960+
935961
def review_assignments_needing_reviewer_reminder(remind_date):
936962
assignment_qs = ReviewAssignment.objects.filter(
937963
state__in=("assigned", "accepted"),
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{% load ietf_filters %}{% autoescape off %}{% filter wordwrap:78 %}
2+
Reviewer {{ reviewer }} in {{ team.acronym }} will become available again in {{ reminder_days }} days.
3+
This ends their unavailability which lasted from {{ period_start }} until {{ period_end }}.
4+
5+
{{ reviewer_overview_url }}
6+
7+
{% endfilter %}{% endautoescape %}

0 commit comments

Comments
 (0)