Skip to content

Commit 295a8e4

Browse files
committed
View for sending ballot discuss and comment to the IESG list
- Legacy-Id: 2277
1 parent d5aae59 commit 295a8e4

6 files changed

Lines changed: 125 additions & 18 deletions

File tree

branch/iesg-tracker/ietf/idrfc/tests.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,31 @@ def test_edit_position(self):
288288
self.assertTrue(not (pos.yes or pos.abstain or pos.recuse))
289289
self.assertTrue(pos.discuss == -1)
290290
self.assertEquals(draft.idinternal.comments().count(), comments_before + 1)
291-
self.assertTrue("Position" in draft.idinternal.comments()[0].comment_text)
291+
self.assertTrue("Position" in draft.idinternal.comments()[0].comment_text)
292292

293-
#self.assertTrue(len(mail_outbox) == 1)
294-
#self.assertTrue("updated" in mail_outbox[0]['Subject'])
295-
#self.assertTrue(draft.filename in mail_outbox[0]['Subject'])
293+
def test_send_ballot_comment(self):
294+
draft = InternetDraft.objects.get(filename="draft-ietf-mipshop-pfmipv6")
295+
url = urlreverse('doc_send_ballot_comment', kwargs=dict(name=draft.filename))
296+
login_as = "rhousley"
297+
login_testing_unauthorized(self, login_as, url)
298+
299+
# normal get
300+
r = self.client.get(url)
301+
self.assertEquals(r.status_code, 200)
302+
q = PyQuery(r.content)
303+
self.assertTrue(len(q('form input[name="cc"]')) > 0)
304+
305+
# send
306+
IESGComment.objects.create(ballot=draft.idinternal.ballot,
307+
ad=IESGLogin.objects.get(login_name=login_as),
308+
text="Test!", date=date.today(),
309+
revision=draft.revision_display(), active=1)
310+
311+
r = self.client.post(url, dict(cc="test@example.com", cc_state_change="1"))
312+
self.assertEquals(r.status_code, 302)
313+
314+
self.assertTrue(len(mail_outbox) == 1)
315+
self.assertTrue("COMMENT" in mail_outbox[0]['Subject'])
296316

297317

298318
TEST_RFC_INDEX = '''<?xml version="1.0" encoding="UTF-8"?>

branch/iesg-tracker/ietf/idrfc/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,5 @@
4848
url(r'^(?P<name>[^/]+)/edit/resurrect/$', views_edit.request_resurrect, {}, name='doc_request_resurrect'),
4949
url(r'^(?P<name>[^/]+)/edit/addcomment/$', views_edit.add_comment, {}, name='doc_add_comment'),
5050
url(r'^(?P<name>[^/]+)/edit/position/$', views_edit.edit_position, {}, name='doc_edit_position'),
51+
url(r'^(?P<name>[^/]+)/edit/sendballotcomment/$', views_edit.send_ballot_comment, {}, name='doc_send_ballot_comment'),
5152
)

branch/iesg-tracker/ietf/idrfc/views_edit.py

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
from datetime import datetime, date, time, timedelta
33
from django.http import HttpResponse, HttpResponseRedirect, Http404
44
from django.shortcuts import render_to_response, get_object_or_404
5+
from django.core.urlresolvers import reverse as urlreverse
56
from django.template.loader import render_to_string
67
from django.template import RequestContext
78
from django import forms
89
from django.utils.html import strip_tags
910

11+
from ietf.utils.mail import send_mail_text
1012
from ietf.ietfauth.decorators import group_required
1113
from ietf.idtracker.templatetags.ietf_filters import in_group
1214
from ietf.idtracker.models import *
@@ -356,7 +358,16 @@ def position_to_ballot_choice(position):
356358

357359
def position_label(position_value):
358360
return dict(BALLOT_CHOICES).get(position_value, "")
359-
361+
362+
def get_ballot_info(ballot, area_director):
363+
pos = Position.objects.filter(ballot=ballot, ad=area_director)
364+
pos = pos[0] if pos else None
365+
discuss = IESGDiscuss.objects.filter(ballot=ballot, ad=area_director)
366+
discuss = discuss[0] if discuss else None
367+
comment = IESGComment.objects.filter(ballot=ballot, ad=area_director)
368+
comment = comment[0] if comment else None
369+
return (pos, discuss, comment)
370+
360371
class EditPositionForm(forms.Form):
361372
position = forms.ChoiceField(choices=BALLOT_CHOICES, widget=forms.RadioSelect)
362373
discuss_text = forms.CharField(required=False, widget=forms.Textarea)
@@ -370,16 +381,7 @@ def edit_position(request, name):
370381

371382
login = IESGLogin.objects.get(login_name=request.user.username)
372383

373-
pos = Position.objects.filter(ballot=doc.idinternal.ballot, ad=login)
374-
if pos:
375-
pos = pos[0]
376-
377-
discuss = IESGDiscuss.objects.filter(ballot=doc.idinternal.ballot, ad=login)
378-
if discuss:
379-
discuss = discuss[0]
380-
comment = IESGComment.objects.filter(ballot=doc.idinternal.ballot, ad=login)
381-
if comment:
382-
comment = comment[0]
384+
pos, discuss, comment = get_ballot_info(doc.idinternal.ballot, login)
383385

384386
if request.method == 'POST':
385387
form = EditPositionForm(request.POST)
@@ -440,11 +442,12 @@ def edit_position(request, name):
440442
if comment.text:
441443
add_document_comment(request, doc, comment.text, ballot=DocumentComment.BALLOT_COMMENT)
442444

443-
444-
#email_owner(request, doc, doc.idinternal.job_owner, login, "A new comment added by %s" % login)
445445
doc.idinternal.event_date = date.today()
446446
doc.idinternal.save()
447-
return HttpResponseRedirect(doc.idinternal.get_absolute_url())
447+
if request.POST.get("send_mail"):
448+
return HttpResponseRedirect(urlreverse("doc_send_ballot_comment", kwargs=dict(name=doc.filename)))
449+
else:
450+
return HttpResponseRedirect(doc.idinternal.get_absolute_url())
448451
else:
449452
initial = {}
450453
if pos:
@@ -464,3 +467,48 @@ def edit_position(request, name):
464467
discuss=discuss,
465468
comment=comment),
466469
context_instance=RequestContext(request))
470+
471+
@group_required('Area_Director','Secretariat')
472+
def send_ballot_comment(request, name):
473+
doc = get_object_or_404(InternetDraft, filename=name)
474+
if not doc.idinternal:
475+
raise Http404()
476+
477+
login = IESGLogin.objects.get(login_name=request.user.username)
478+
pos, discuss, comment = get_ballot_info(doc.idinternal.ballot, login)
479+
480+
subj = []
481+
d = ""
482+
if pos and pos.discuss == 1 and discuss and discuss.text:
483+
d = discuss.text
484+
subj.append("DISCUSS")
485+
c = ""
486+
if comment and comment.text:
487+
c = comment.text
488+
subj.append("COMMENT")
489+
490+
subject = "%s: %s" % (" and ".join(subj), doc.file_tag())
491+
body = render_to_string("idrfc/ballot_comment_mail.txt",
492+
dict(discuss=d, comment=c))
493+
frm = u"%s <%s>" % login.person.email()
494+
to = "iesg@iesg.org"
495+
496+
if request.method == 'POST':
497+
cc = [x.strip() for x in request.POST.get("cc", "").split(',') if x.strip()]
498+
if request.POST.get("cc_state_change") and doc.idinternal.state_change_notice_to:
499+
cc.extend(doc.idinternal.state_change_notice_to.split(','))
500+
501+
send_mail_text(request, to, frm, subject, body, cc=", ".join(cc))
502+
503+
return HttpResponseRedirect(doc.idinternal.get_absolute_url())
504+
505+
return render_to_response('idrfc/send_ballot_comment.html',
506+
dict(doc=doc,
507+
subject=subject,
508+
body=body,
509+
frm=frm,
510+
to=to,
511+
can_send=d or c),
512+
context_instance=RequestContext(request))
513+
514+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% if discuss %}Discuss:
2+
{{ discuss|safe }}
3+
4+
{% endif %}{% if comment %}Comment:
5+
{{ comment|safe }}
6+
{% endif %}

branch/iesg-tracker/ietf/templates/idrfc/edit_position.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
<div class="actions">
2626
<a href="{{ doc.idinternal.get_absolute_url }}">Back</a>
27+
<input type="submit" name="send_mail" value="Save and send email"/>
2728
<input type="submit" value="Save"/>
2829
</div>
2930
</form>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<h3>Email DISCUSS and COMMENT text to IESG list</h3>
2+
3+
<form action="" method="POST">
4+
<table>
5+
<tr><td>From:</td> <td>{{ frm }}</td></tr>
6+
<tr><td>To:</td> <td>{{ to }}</td></tr>
7+
<tr>
8+
<td>Cc:<br/>
9+
<span class="help">separated by comma</span></td>
10+
<td><input type="text" name="cc" value="" size="75" /><br/>
11+
{% if doc.idinternal.state_change_notice_to %}
12+
<label>
13+
<input type="checkbox" name="cc_state_change" value="1" />
14+
{{ doc.idinternal.state_change_notice_to }}
15+
</label>
16+
{% endif %}
17+
</td>
18+
</tr>
19+
<tr><td>Subject:</td> <td>{{ subject }}</td></tr>
20+
<tr>
21+
<td>Body:</td>
22+
<td><pre>{{ body }}</pre></td>
23+
</tr>
24+
</table>
25+
26+
<div class="actions">
27+
<a href="{{ doc.idinternal.get_absolute_url }}">Back</a>
28+
<input type="submit" value="Send"/>
29+
</div>
30+
</form>
31+

0 commit comments

Comments
 (0)