diff --git a/ietf/doc/lastcall.py b/ietf/doc/lastcall.py index fa6446780..a00fc16d2 100644 --- a/ietf/doc/lastcall.py +++ b/ietf/doc/lastcall.py @@ -9,7 +9,7 @@ from ietf.doc.models import IESG_SUBSTATE_TAGS from ietf.person.models import Person from ietf.doc.utils import add_state_change_event from ietf.doc.mails import generate_ballot_writeup, generate_approval_mail, generate_last_call_announcement -from ietf.doc.mails import send_last_call_request, email_last_call_expired +from ietf.doc.mails import send_last_call_request, email_last_call_expired, email_last_call_expired_with_downref def request_last_call(request, doc): if not doc.latest_event(type="changed_ballot_writeup_text"): @@ -65,3 +65,8 @@ def expire_last_call(doc): doc.save_with_history([e]) email_last_call_expired(doc) + + if doc.type_id == 'draft': + lc_text = doc.latest_event(LastCallDocEvent, type="sent_last_call").desc + if "document makes the following downward references" in lc_text: + email_last_call_expired_with_downref(doc, lc_text) \ No newline at end of file diff --git a/ietf/doc/mails.py b/ietf/doc/mails.py index 9737e73be..afd1c00fa 100644 --- a/ietf/doc/mails.py +++ b/ietf/doc/mails.py @@ -504,6 +504,18 @@ def email_last_call_expired(doc): url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url()), cc = addrs.cc) +def email_last_call_expired_with_downref(doc, last_call_text): + if doc.type_id != 'draft': + return + send_mail(None, + (doc.ad.email().address, ), + "DraftTracker Mail System ", + "Review Downrefs From Expired Last Call: %s" % doc.file_tag(), + "doc/mail/downrefs_notice.txt", + dict(last_call_text=last_call_text, + doc=doc, + url=settings.IDTRACKER_BASE_URL + "/downref/add/")) + def email_intended_status_changed(request, doc, text): (to,cc) = gather_address_lists('doc_intended_status_changed',doc=doc) diff --git a/ietf/doc/tests_draft.py b/ietf/doc/tests_draft.py index 0b2d8327e..945d0e9bd 100644 --- a/ietf/doc/tests_draft.py +++ b/ietf/doc/tests_draft.py @@ -794,6 +794,31 @@ class ExpireLastCallTests(TestCase): self.assertTrue('aread@' in outbox[-1]['To']) self.assertTrue('draft-ietf-mars-test@' in outbox[-1]['To']) + def test_expire_last_call_with_downref(self): + from ietf.doc.lastcall import get_expired_last_calls, expire_last_call + + secretary = Person.objects.get(name="Sec Retary") + ad = Person.objects.get(user__username='ad') + draft = WgDraftFactory(ad=ad,name='draft-ietf-mars-test') + draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="lc")) + + e = LastCallDocEvent(doc=draft, rev=draft.rev, type="sent_last_call", by=secretary) + e.text = "Last call sent" + e.desc = "Blah, blah, blah.\n\nThis document makes the following downward references (downrefs):\n ** Downref: Normative reference to an Experimental RFC: RFC 4764" + e.expires = datetime.datetime.now() + e.save() + + drafts = list(get_expired_last_calls()) + self.assertEqual(len(drafts), 1) + + mailbox_before = len(outbox) + expire_last_call(drafts[0]) + + d = Document.objects.get(name=draft.name) + self.assertEqual(len(outbox), mailbox_before + 2) + self.assertTrue("Review Downrefs From Expired Last Call" in outbox[-1]["Subject"]) + self.assertTrue(d.ad.email().address in outbox[-1]['To']) + class IndividualInfoFormsTests(TestCase): def setUp(self): diff --git a/ietf/templates/doc/mail/downrefs_notice.txt b/ietf/templates/doc/mail/downrefs_notice.txt new file mode 100644 index 000000000..f4eefd2fb --- /dev/null +++ b/ietf/templates/doc/mail/downrefs_notice.txt @@ -0,0 +1,15 @@ +{% autoescape off %} +Please DO NOT reply to this email. + +I-D: {{ doc.file_tag|safe }} + +IETF Last Call recently ended for this Internet-Draft, and the Last Call +included downward references (downrefs). + +If the Last Call consensus is that these RFCs are to be added to the +downref registry, then please do so by going to {{ url }}. + +The Last Call announcement said... + +{{ last_call_text }} +{% endautoescape%}