Skip to content

Commit 79d373f

Browse files
committed
checkpoint.
- Legacy-Id: 10011
1 parent 15538de commit 79d373f

14 files changed

Lines changed: 106 additions & 44 deletions

ietf/doc/mails.py

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,12 @@ def email_state_changed(request, doc, text):
3030

3131
def email_stream_changed(request, doc, old_stream, new_stream, text=""):
3232
"""Email the change text to the notify group and to the stream chairs"""
33-
to = [x.strip() for x in doc.notify.replace(';', ',').split(',')]
34-
35-
# These use comprehension to deal with conditions when there might be more than one chair listed for a stream
33+
streams = []
3634
if old_stream:
37-
to.extend([r.formatted_email() for r in Role.objects.filter(group__acronym=old_stream.slug, name='chair')])
35+
streams.append(old_stream.slug)
3836
if new_stream:
39-
to.extend([r.formatted_email() for r in Role.objects.filter(group__acronym=new_stream.slug, name='chair')])
37+
streams.append(new_stream.slug)
38+
to = gather_addresses('doc_stream_changed',doc=doc,streams=streams)
4039

4140
if not to:
4241
return
@@ -124,8 +123,8 @@ def generate_last_call_announcement(request, doc):
124123
dict(doc=doc,
125124
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url() + "ballot/",
126125
expiration_date=expiration_date.strftime("%Y-%m-%d"), #.strftime("%B %-d, %Y"),
127-
to=",\n ".join(gather_addresses('last_call_issued',doc=doc)),
128-
cc=",\n ".join(gather_addresses('last_call_issued_cc',doc=doc)),
126+
to=gather_addresses('last_call_issued',doc=doc),
127+
cc=gather_addresses('last_call_issued_cc',doc=doc),
129128
group=group,
130129
docs=[ doc ],
131130
urls=[ settings.IDTRACKER_BASE_URL + doc.get_absolute_url() ],
@@ -169,9 +168,6 @@ def generate_approval_mail_approved(request, doc):
169168
else:
170169
action_type = "Document"
171170

172-
to = gather_addresses('ballot_approved_ietf_stream',doc=doc)
173-
cc = gather_addresses('ballot_approved_ietf_stream_cc',doc=doc)
174-
175171
# the second check catches some area working groups (like
176172
# Transport Area Working Group)
177173
if doc.group.type_id not in ("area", "individ", "ag") and not doc.group.name.endswith("Working Group"):
@@ -202,8 +198,8 @@ def generate_approval_mail_approved(request, doc):
202198
dict(doc=doc,
203199
docs=[doc],
204200
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
205-
to=",\n ".join(to),
206-
cc=",\n ".join(cc),
201+
to = gather_addresses('ballot_approved_ietf_stream',doc=doc),
202+
cc = gather_addresses('ballot_approved_ietf_stream_cc',doc=doc),
207203
doc_type=doc_type,
208204
made_by=made_by,
209205
contacts=contacts,
@@ -215,16 +211,13 @@ def generate_approval_mail_rfc_editor(request, doc):
215211
disapproved = doc.get_state_slug("draft-iesg") in DO_NOT_PUBLISH_IESG_STATES
216212
doc_type = "RFC" if doc.get_state_slug() == "rfc" else "Internet Draft"
217213

218-
to = gather_addresses('ballot_approved_conflrev', doc=doc)
219-
cc = gather_addresses('ballot_approved_conflrev_cc', doc=doc)
220-
221214
return render_to_string("doc/mail/approval_mail_rfc_editor.txt",
222215
dict(doc=doc,
223216
doc_url=settings.IDTRACKER_BASE_URL + doc.get_absolute_url(),
224217
doc_type=doc_type,
225218
disapproved=disapproved,
226-
to=",\n ".join(to),
227-
cc=",\n ".join(cc),
219+
to = gather_addresses('ballot_approved_conflrev', doc=doc),
220+
cc = gather_addresses('ballot_approved_conflrev_cc', doc=doc),
228221
)
229222
)
230223

ietf/doc/tests_ballot.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
from ietf.utils.mail import outbox
1616
from ietf.utils.test_data import make_test_data
1717
from ietf.utils.test_utils import login_testing_unauthorized
18-
from ietf.mailtoken.utils import gather_addresses
1918

2019

2120
class EditPositionTests(TestCase):
@@ -171,8 +170,8 @@ def test_send_ballot_comment(self):
171170
r = self.client.post(url, dict(cc=""))
172171
self.assertEqual(r.status_code, 302)
173172
self.assertEqual(len(outbox), mailbox_before + 2)
174-
m = outbox[-1]
175-
self.assertEqual(m['Cc'],','.join(gather_addresses('ballot_saved_cc',doc=draft)))
173+
#TODO this would be a good place to test actual mailtoken expansions
174+
#if we can find a way to get the real, or at least representative, data in place.
176175

177176

178177
class BallotWriteupsTests(TestCase):

ietf/doc/tests_conflict_review.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ def test_start_review_as_secretary(self):
7070
self.assertTrue(review_doc.latest_event(DocEvent,type="added_comment").desc.startswith("IETF conflict review requested"))
7171
self.assertTrue(doc.latest_event(DocEvent,type="added_comment").desc.startswith("IETF conflict review initiated"))
7272
self.assertTrue('Conflict Review requested' in outbox[-1]['Subject'])
73-
self.assertTrue(settings.IANA_EVAL_EMAIL in outbox[-1]['To'])
7473

7574
# verify you can't start a review when a review is already in progress
7675
r = self.client.post(url,dict(ad="Aread Irector",create_in_state="Needs Shepherd",notify='ipu@ietf.org'))
@@ -118,8 +117,8 @@ def test_start_review_as_stream_owner(self):
118117
self.assertTrue(doc in [x.target.document for x in review_doc.relateddocument_set.filter(relationship__slug='conflrev')])
119118
self.assertEqual(len(outbox), messages_before + 2)
120119
self.assertTrue('Conflict Review requested' in outbox[-1]['Subject'])
121-
self.assertTrue(any('iesg-secretary@ietf.org' in x['To'] for x in outbox[-2:]))
122-
self.assertTrue(any(settings.IANA_EVAL_EMAIL in x['To'] for x in outbox[-2:]))
120+
#self.assertTrue(any('iesg-secretary@ietf.org' in x['To'] for x in outbox[-2:]))
121+
#self.assertTrue(any(settings.IANA_EVAL_EMAIL in x['To'] for x in outbox[-2:]))
123122

124123

125124
def test_change_state(self):

ietf/doc/utils_charter.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ def default_action_text(group, charter, by):
127127
techadv=group.role_set.filter(name="techadv"),
128128
milestones=group.groupmilestone_set.filter(state="charter"),
129129
action_type=action,
130-
to=",\n ".join(gather_addresses('ballot_approved_charter',doc=charter,group=group)),
131-
cc=",\n ".join(gather_addresses('ballot_approved_charter_cc',doc=charter,group=group)),
130+
to=gather_addresses('ballot_approved_charter',doc=charter,group=group),
131+
cc=gather_addresses('ballot_approved_charter_cc',doc=charter,group=group),
132132
))
133133

134134
e.save()
@@ -149,6 +149,8 @@ def default_review_text(group, charter, by):
149149
milestones=group.groupmilestone_set.filter(state="charter"),
150150
review_date=(datetime.date.today() + datetime.timedelta(weeks=1)).isoformat(),
151151
review_type="new" if group.state_id == "proposed" else "recharter",
152+
to=gather_addresses('charter_external_review',group=group),
153+
cc=gather_addresses('charter_external_review_cc',group=group)
152154
)
153155
)
154156
e.save()

ietf/doc/views_ballot.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
from ietf.name.models import BallotPositionName
2828
from ietf.person.models import Person
2929
from ietf.utils.mail import send_mail_text, send_mail_preformatted
30-
from ietf.mailtoken.utils import gather_addresses
30+
from ietf.mailtoken.utils import gather_addresses, gather_address_list
3131

3232
BALLOT_CHOICES = (("yes", "Yes"),
3333
("noobj", "No Objection"),
@@ -288,7 +288,7 @@ def send_ballot_comment(request, name, ballot_id):
288288
to = gather_addresses('ballot_saved',doc=doc)
289289

290290
if request.method == 'POST':
291-
cc = gather_addresses('ballot_saved_cc',doc=doc)
291+
cc = gather_address_list('ballot_saved_cc',doc=doc)
292292
explicit_cc = [x.strip() for x in request.POST.get("cc", "").split(',') if x.strip()]
293293
if explicit_cc:
294294
cc.extend(explicit_cc)
@@ -716,7 +716,7 @@ def approve_ballot(request, name):
716716

717717
if action == "to_announcement_list":
718718
send_mail_preformatted(request, announcement, extra=extra_automation_headers(doc),
719-
override={ "To": ",".join(gather_addresses('ballot_approved_ietf_stream_iana')), "CC": None, "Bcc": None, "Reply-To": None})
719+
override={ "To": gather_addresses('ballot_approved_ietf_stream_iana'), "CC": None, "Bcc": None, "Reply-To": None})
720720

721721
msg = infer_message(announcement)
722722
msg.by = login
@@ -758,7 +758,7 @@ def make_last_call(request, name):
758758
send_mail_preformatted(request, announcement)
759759
if doc.type.slug == 'draft':
760760
send_mail_preformatted(request, announcement, extra=extra_automation_headers(doc),
761-
override={ "To": ",\n ".join(gather_addresses('last_call_issued_iana',doc=doc)),
761+
override={ "To": gather_addresses('last_call_issued_iana',doc=doc),
762762
"CC": None, "Bcc": None, "Reply-To": None})
763763

764764
msg = infer_message(announcement)

ietf/doc/views_conflict_review.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from ietf.person.models import Person
2121
from ietf.utils.mail import send_mail_preformatted
2222
from ietf.utils.textupload import get_cleaned_text_file_content
23+
from ietf.mailtoken.utils import gather_addresses
2324

2425
class ChangeStateForm(forms.Form):
2526
review_state = forms.ModelChoiceField(State.objects.filter(used=True, type="conflrev"), label="Conflict review state", empty_label=None, required=True)
@@ -88,6 +89,8 @@ def change_state(request, name, option=None):
8889
def send_conflict_review_started_email(request, review):
8990
msg = render_to_string("doc/conflict_review/review_started.txt",
9091
dict(frm = settings.DEFAULT_FROM_EMAIL,
92+
to = gather_addresses('conflrev_requested',doc=review),
93+
cc = gather_addresses('conflrev_requested_cc',doc=review),
9194
by = request.user.person,
9295
review = review,
9396
reviewed_doc = review.relateddocument_set.get(relationship__slug='conflrev').target.document,
@@ -98,8 +101,8 @@ def send_conflict_review_started_email(request, review):
98101
send_mail_preformatted(request,msg)
99102
email_iana(request,
100103
review.relateddocument_set.get(relationship__slug='conflrev').target.document,
101-
settings.IANA_EVAL_EMAIL,
102-
msg)
104+
gather_addresses('conflrev_requested_iana',doc=review),
105+
msg)
103106

104107
def send_conflict_eval_email(request,review):
105108
msg = render_to_string("doc/eval_email.txt",

ietf/doc/views_draft.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,9 @@ def to_iesg(request,name):
583583
doc.save()
584584

585585
extra = {}
586-
extra['Cc'] = ",\n ".join(gather_addresses('pubreq_iesg_cc',doc=doc))
586+
extra['Cc'] = gather_addresses('pubreq_iesg_cc',doc=doc)
587587
send_mail(request=request,
588-
to = ",\n ".join(gather_addresses('pubreq_iesg',doc=doc)),
588+
to = gather_addresses('pubreq_iesg',doc=doc),
589589
frm = login.formatted_email(),
590590
subject = "Publication has been requested for %s-%s" % (doc.name,doc.rev),
591591
template = "doc/submit_to_iesg_email.txt",
@@ -1133,7 +1133,7 @@ def request_publication(request, name):
11331133

11341134
m = Message()
11351135
m.frm = request.user.person.formatted_email()
1136-
m.to = ",\n ".join(gather_addresses('pubreq_rfced',doc=doc))
1136+
m.to = gather_addresses('pubreq_rfced',doc=doc)
11371137
m.by = request.user.person
11381138

11391139
next_state = State.objects.get(used=True, type="draft-stream-%s" % doc.stream.slug, slug="rfc-edit")
@@ -1163,7 +1163,7 @@ def request_publication(request, name):
11631163
send_mail_message(request, m)
11641164

11651165
# IANA copy
1166-
m.to = ", ".join(gather_addresses('pubreq_rfced_iana',doc=doc))
1166+
m.to = gather_addresses('pubreq_rfced_iana',doc=doc)
11671167
send_mail_message(request, m, extra=extra_automation_headers(doc))
11681168

11691169
e = DocEvent(doc=doc, type="requested_publication", by=request.user.person)
@@ -1299,6 +1299,7 @@ def adopt_draft(request, name):
12991299

13001300
update_reminder(doc, "stream-s", e, due_date)
13011301

1302+
# TODO: Replace this with a message that's explicitly about the document adoption
13021303
email_stream_state_changed(request, doc, prev_state, new_state, by, comment)
13031304

13041305
# comment

ietf/doc/views_status_change.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,8 @@ def default_approval_text(status_change,relateddoc):
299299
approved_text = current_text,
300300
action=action,
301301
newstatus=newstatus(relateddoc),
302-
to=",\n ".join(gather_addresses('ballot_approved_status_change',doc=status_change)),
303-
cc=",\n ".join(gather_addresses('ballot_approved_status_change_cc',doc=status_change)),
302+
to=gather_addresses('ballot_approved_status_change',doc=status_change),
303+
cc=gather_addresses('ballot_approved_status_change_cc',doc=status_change),
304304
)
305305
)
306306

ietf/mailtoken/migrations/0002_auto_20150809_1314.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ def make_recipients(apps):
6363

6464
rc(slug='doc_stream_manager',
6565
desc="The manager of the document's stream",
66-
template='{% if doc.stream_id == "ise" %}<rfc-ise@rfc-editor.org>{% endif %}{% if doc.stream_id == "irtf" %}<irtf-chair@irtf.org>{% endif %}{% if doc.stream_id == "ietf" %}<iesg@ietf.org>{% endif %}')
66+
template=None )
67+
68+
rc(slug='stream_managers',
69+
desc="The managers of any related streams",
70+
template=None )
6771

6872
rc(slug='conflict_review_stream_manager',
6973
desc="The stream manager of a document being reviewed for IETF stream conflicts",
@@ -81,6 +85,10 @@ def make_recipients(apps):
8185
desc="IANA's draft last call address",
8286
template='IANA <drafts-lastcall@icann.org>')
8387

88+
rc(slug='iana_eval',
89+
desc="IANA's draft evaluation address",
90+
template='IANA <drafts-eval@icann.org>')
91+
8492
rc(slug='iana',
8593
desc="IANA",
8694
template='<iana@iana.org>')
@@ -97,6 +105,7 @@ def make_recipients(apps):
97105
desc="The group's chairs",
98106
template="{{group.acronym}}-chairs@ietf.org")
99107

108+
100109
def make_mailtokens(apps):
101110

102111
Recipient=apps.get_model('mailtoken','Recipient')
@@ -261,6 +270,38 @@ def mt_factory(slug,desc,recipient_slugs):
261270
desc='Recipients for IANA message when a non-IETF stream manager requests publication',
262271
recipient_slugs=['iana_approve',])
263272

273+
mt_factory(slug='charter_external_review',
274+
desc='Recipients for a charter external review',
275+
recipient_slugs=['ietf_announce',])
276+
277+
mt_factory(slug='charter_external_review_cc',
278+
desc='Copied on a charter external review',
279+
recipient_slugs=['group_mail_list',])
280+
281+
mt_factory(slug='conflrev_requested',
282+
desc="Recipients for a stream manager's request for an IETF conflict review",
283+
recipient_slugs=['iesg_secretary'])
284+
285+
mt_factory(slug='conflrev_requested_cc',
286+
desc="Copied on a stream manager's request for an IETF conflict review",
287+
recipient_slugs=['iesg',
288+
'doc_notify',
289+
'doc_affecteddoc_authors',
290+
'doc_affecteddoc_group_chairs',
291+
'doc_affecteddoc_notify',
292+
])
293+
294+
mt_factory(slug='conflrev_requested_iana',
295+
desc="Recipients for IANA message when a stream manager requests an IETF conflict review",
296+
recipient_slugs=['iana_eval',])
297+
298+
mt_factory(slug='doc_stream_changed',
299+
desc="Recipients for notification when a document's stream changes",
300+
recipient_slugs=['stream_managers',
301+
'doc_notify',
302+
])
303+
304+
264305
def forward(apps, schema_editor):
265306

266307
make_recipients(apps)

ietf/mailtoken/models.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,21 @@ def gather_group_steering_group(self,**kwargs):
9797
addrs.append(sg_map[kwargs['group'].type_id])
9898
return addrs
9999

100+
def gather_stream_managers(self, **kwargs):
101+
addrs = []
102+
manager_map = dict(ise = '<rfc-ise@rfc-editor.org>',
103+
irtf = '<irtf-chair@irtf.org>',
104+
ietf = '<iesg@ietf.org>',
105+
iab = '<iab-chair@iab.org>')
106+
if 'streams' in kwargs:
107+
for stream in kwargs['streams']:
108+
if stream in manager_map:
109+
addrs.append(manager_map[stream])
110+
return addrs
111+
112+
def gather_doc_stream_manager(self, **kwargs):
113+
addrs = []
114+
if 'doc' in kwargs:
115+
addrs.extend(Recipient.objects.get(slug='stream_managers').gather(**{'streams':[kwargs['doc'].stream_id]}))
116+
return addrs
100117

0 commit comments

Comments
 (0)