Indicate on the IESG Telechat Agenda if a document has an RFC Editor Note. To accomplish this, the RFC Editor Note needed to be separated from the rest of the ballot write up. Fixes #1230.
- Legacy-Id: 10770
This commit is contained in:
parent
8ae439ae0f
commit
4b5ac9e09e
|
@ -92,6 +92,17 @@ def generate_ballot_writeup(request, doc):
|
|||
|
||||
return e
|
||||
|
||||
def generate_ballot_rfceditornote(request, doc):
|
||||
e = WriteupDocEvent()
|
||||
e.type = "changed_ballot_rfceditornote_text"
|
||||
e.by = request.user.person
|
||||
e.doc = doc
|
||||
e.desc = u"RFC Editor Note for ballot was generated"
|
||||
e.text = unicode(render_to_string("doc/mail/ballot_rfceditornote.txt"))
|
||||
e.save()
|
||||
|
||||
return e
|
||||
|
||||
def generate_last_call_announcement(request, doc):
|
||||
expiration_date = datetime.date.today() + datetime.timedelta(days=14)
|
||||
if doc.group.type_id in ("individ", "area"):
|
||||
|
|
|
@ -232,6 +232,10 @@ class DocumentInfo(models.Model):
|
|||
else:
|
||||
return None
|
||||
|
||||
def has_rfc_editor_note(self):
|
||||
e = self.latest_event(WriteupDocEvent, type="changed_rfc_editor_note_text")
|
||||
return bool(e and (e.text != ""))
|
||||
|
||||
def meeting_related(self):
|
||||
answer = False
|
||||
if self.type_id in ("agenda","minutes","bluesheets","slides"):
|
||||
|
@ -675,6 +679,7 @@ EVENT_TYPES = [
|
|||
|
||||
("changed_ballot_approval_text", "Changed ballot approval text"),
|
||||
("changed_ballot_writeup_text", "Changed ballot writeup text"),
|
||||
("changed_rfc_editor_note_text", "Changed RFC Editor Note text"),
|
||||
|
||||
("changed_last_call_text", "Changed last call text"),
|
||||
("requested_last_call", "Requested last call"),
|
||||
|
|
|
@ -707,11 +707,19 @@ class DocTestCase(TestCase):
|
|||
text="This is ballot writeup notes.",
|
||||
by=Person.objects.get(name="(System)"))
|
||||
|
||||
rfced_note = WriteupDocEvent.objects.create(
|
||||
doc=doc,
|
||||
desc="Changed text",
|
||||
type="changed_rfc_editor_note_text",
|
||||
text="This is a note for the RFC Editor.",
|
||||
by=Person.objects.get(name="(System)"))
|
||||
|
||||
url = urlreverse('doc_writeup', kwargs=dict(name=doc.name))
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
self.assertTrue(appr.text in r.content)
|
||||
self.assertTrue(notes.text in r.content)
|
||||
self.assertTrue(rfced_note.text in r.content)
|
||||
|
||||
def test_history(self):
|
||||
doc = make_test_data()
|
||||
|
|
|
@ -273,6 +273,45 @@ class BallotWriteupsTests(TestCase):
|
|||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("This is a simple test" in draft.latest_event(WriteupDocEvent, type="changed_ballot_writeup_text").text)
|
||||
|
||||
def test_edit_ballot_rfceditornote(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_rfceditornote', kwargs=dict(name=draft.name))
|
||||
login_testing_unauthorized(self, "secretary", url)
|
||||
|
||||
# add a note to the RFC Editor
|
||||
rfced_note = WriteupDocEvent.objects.create(
|
||||
doc=draft,
|
||||
desc="Changed text",
|
||||
type="changed_rfc_editor_note_text",
|
||||
text="This is a note for the RFC Editor.",
|
||||
by=Person.objects.get(name="(System)"))
|
||||
|
||||
# normal get
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code, 200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEqual(len(q('textarea[name=rfc_editor_note]')), 1)
|
||||
self.assertTrue(q('[type=submit]:contains("Save")'))
|
||||
self.assertTrue("<label class=\"control-label\">RFC Editor Note</label>" in r.content)
|
||||
self.assertTrue("This is a note for the RFC Editor" in r.content)
|
||||
|
||||
# save with a note
|
||||
r = self.client.post(url, dict(
|
||||
rfc_editor_note="This is a simple test.",
|
||||
save_ballot_rfceditornote="1"))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue(draft.has_rfc_editor_note())
|
||||
self.assertTrue("This is a simple test" in draft.latest_event(WriteupDocEvent, type="changed_rfc_editor_note_text").text)
|
||||
|
||||
# clear the existing note
|
||||
r = self.client.post(url, dict(
|
||||
rfc_editor_note=" ",
|
||||
clear_ballot_rfceditornote="1"))
|
||||
self.assertEqual(r.status_code, 200)
|
||||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertFalse(draft.has_rfc_editor_note())
|
||||
|
||||
def test_issue_ballot(self):
|
||||
draft = make_test_data()
|
||||
url = urlreverse('doc_ballot_writeupnotes', kwargs=dict(name=draft.name))
|
||||
|
@ -340,6 +379,55 @@ class BallotWriteupsTests(TestCase):
|
|||
draft = Document.objects.get(name=draft.name)
|
||||
self.assertTrue("Subject: Results of IETF-conflict review" in draft.latest_event(WriteupDocEvent, type="changed_ballot_approval_text").text)
|
||||
|
||||
def test_edit_verify_permissions(self):
|
||||
|
||||
def verify_fail(username, url):
|
||||
if username:
|
||||
self.client.login(username=username, password=username+"+password")
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code,403)
|
||||
|
||||
def verify_can_see(username, url):
|
||||
self.client.login(username=username, password=username+"+password")
|
||||
r = self.client.get(url)
|
||||
self.assertEqual(r.status_code,200)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEqual(len(q("<textarea class=\"form-control\"")),1)
|
||||
|
||||
draft = make_test_data()
|
||||
|
||||
e = WriteupDocEvent()
|
||||
e.type = "changed_ballot_approval_text"
|
||||
e.by = Person.objects.get(name="(System)")
|
||||
e.doc = draft
|
||||
e.desc = u"Ballot approval text was generated"
|
||||
e.text = u"Test approval text."
|
||||
e.save()
|
||||
|
||||
e = WriteupDocEvent()
|
||||
e.type = "changed_ballot_writeup_text"
|
||||
e.by = Person.objects.get(name="(System)")
|
||||
e.doc = draft
|
||||
e.desc = u"Ballot writeup was generated"
|
||||
e.text = u"Test ballot writeup text."
|
||||
e.save()
|
||||
|
||||
e = WriteupDocEvent()
|
||||
e.type = "changed_ballot_rfceditornote_text"
|
||||
e.by = Person.objects.get(name="(System)")
|
||||
e.doc = draft
|
||||
e.desc = u"RFC Editor Note for ballot was generated"
|
||||
e.text = u"Test note to the RFC Editor text."
|
||||
e.save()
|
||||
|
||||
for p in ['doc_ballot_approvaltext','doc_ballot_writeupnotes','doc_ballot_rfceditornote']:
|
||||
url = urlreverse(p, kwargs=dict(name=draft.name))
|
||||
|
||||
for username in ['plain','marschairman','iana','iab chair']:
|
||||
verify_fail(username, url)
|
||||
|
||||
for username in ['secretary','ad']:
|
||||
verify_can_see(username, url)
|
||||
|
||||
class ApproveBallotTests(TestCase):
|
||||
def test_approve_ballot(self):
|
||||
|
|
|
@ -99,6 +99,7 @@ urlpatterns = patterns('',
|
|||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/undeferballot/$', views_ballot.undefer_ballot, name='doc_undefer_ballot'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/lastcalltext/$', views_ballot.lastcalltext, name='doc_ballot_lastcall'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/ballotwriteupnotes/$', views_ballot.ballot_writeupnotes, name='doc_ballot_writeupnotes'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/ballotrfceditornote/$', views_ballot.ballot_rfceditornote, name='doc_ballot_rfceditornote'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/approvaltext/$', views_ballot.ballot_approvaltext, name='doc_ballot_approvaltext'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/approveballot/$', views_ballot.approve_ballot, name='doc_approve_ballot'),
|
||||
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/makelastcall/$', views_ballot.make_last_call, name='doc_make_last_call'),
|
||||
|
|
|
@ -19,7 +19,8 @@ from ietf.doc.utils import ( add_state_change_event, close_ballot, close_open_ba
|
|||
create_ballot_if_not_open, update_telechat )
|
||||
from ietf.doc.mails import ( email_ballot_deferred, email_ballot_undeferred,
|
||||
extra_automation_headers, generate_last_call_announcement,
|
||||
generate_issue_ballot_mail, generate_ballot_writeup, generate_approval_mail )
|
||||
generate_issue_ballot_mail, generate_ballot_writeup, generate_ballot_rfceditornote,
|
||||
generate_approval_mail )
|
||||
from ietf.doc.lastcall import request_last_call
|
||||
from ietf.iesg.models import TelechatDate
|
||||
from ietf.ietfauth.utils import has_role, role_required
|
||||
|
@ -585,6 +586,57 @@ def ballot_writeupnotes(request, name):
|
|||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
class BallotRfcEditorNoteForm(forms.Form):
|
||||
rfc_editor_note = forms.CharField(widget=forms.Textarea, label="RFC Editor Note", required=True)
|
||||
|
||||
def clean_rfc_editor_note(self):
|
||||
return self.cleaned_data["rfc_editor_note"].replace("\r", "")
|
||||
|
||||
@role_required('Area Director','Secretariat')
|
||||
def ballot_rfceditornote(request, name):
|
||||
"""Editing of RFC Editor Note in the ballot"""
|
||||
doc = get_object_or_404(Document, docalias__name=name)
|
||||
|
||||
login = request.user.person
|
||||
|
||||
|
||||
|
||||
existing = doc.latest_event(WriteupDocEvent, type="changed_rfc_editor_note_text")
|
||||
if not existing or (existing.text == ""):
|
||||
existing = generate_ballot_rfceditornote(request, doc)
|
||||
|
||||
form = BallotRfcEditorNoteForm(auto_id=False, initial=dict(rfc_editor_note=existing.text))
|
||||
|
||||
if request.method == 'POST' and "save_ballot_rfceditornote" in request.POST:
|
||||
form = BallotRfcEditorNoteForm(request.POST)
|
||||
if form.is_valid():
|
||||
t = form.cleaned_data["rfc_editor_note"]
|
||||
if t != existing.text:
|
||||
e = WriteupDocEvent(doc=doc, by=login)
|
||||
e.by = login
|
||||
e.type = "changed_rfc_editor_note_text"
|
||||
e.desc = "RFC Editor Note was changed"
|
||||
e.text = t.rstrip()
|
||||
e.save()
|
||||
|
||||
if request.method == 'POST' and "clear_ballot_rfceditornote" in request.POST:
|
||||
e = WriteupDocEvent(doc=doc, by=login)
|
||||
e.by = login
|
||||
e.type = "changed_rfc_editor_note_text"
|
||||
e.desc = "RFC Editor Note was cleared"
|
||||
e.text = ""
|
||||
e.save()
|
||||
|
||||
# make sure form shows a blank RFC Editor Note
|
||||
form = BallotRfcEditorNoteForm(initial=dict(rfc_editor_note=" "))
|
||||
|
||||
return render_to_response('doc/ballot/rfceditornote.html',
|
||||
dict(doc=doc,
|
||||
back_url=doc.get_absolute_url(),
|
||||
ballot_rfceditornote_form=form,
|
||||
),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
class ApprovalTextForm(forms.Form):
|
||||
approval_text = forms.CharField(widget=forms.Textarea, required=True)
|
||||
|
||||
|
@ -657,7 +709,19 @@ def approve_ballot(request, name):
|
|||
if not e:
|
||||
e = generate_ballot_writeup(request, doc)
|
||||
ballot_writeup = e.text
|
||||
|
||||
|
||||
error_duplicate_rfc_editor_note = False
|
||||
e = doc.latest_event(WriteupDocEvent, type="changed_rfc_editor_note_text")
|
||||
if e and (e.text != ""):
|
||||
if "RFC Editor Note" in ballot_writeup:
|
||||
error_duplicate_rfc_editor_note = True
|
||||
ballot_writeup += "\n\n" + e.text
|
||||
|
||||
if error_duplicate_rfc_editor_note:
|
||||
return render_to_response('doc/draft/rfceditor_note_duplicate_error.html',
|
||||
dict(doc=doc),
|
||||
context_instance=RequestContext(request))
|
||||
|
||||
if "NOT be published" in approval_text:
|
||||
action = "do_not_publish"
|
||||
elif "To: RFC Editor" in approval_text:
|
||||
|
|
|
@ -691,6 +691,10 @@ def document_writeup(request, name):
|
|||
text_from_writeup("changed_ballot_writeup_text"),
|
||||
urlreverse("doc_ballot_writeupnotes", kwargs=dict(name=doc.name))))
|
||||
|
||||
writeups.append(("RFC Editor Note",
|
||||
text_from_writeup("changed_rfc_editor_note_text"),
|
||||
urlreverse("doc_ballot_rfceditornote", kwargs=dict(name=doc.name))))
|
||||
|
||||
elif doc.type_id == "charter":
|
||||
sections.append(("WG Review Announcement",
|
||||
"",
|
||||
|
|
|
@ -156,6 +156,9 @@ def agenda_json(request, date=None):
|
|||
e = doc.latest_event(ConsensusDocEvent, type="changed_consensus")
|
||||
if e:
|
||||
docinfo['consensus'] = e.consensus
|
||||
|
||||
docinfo['rfc-ed-note'] = doc.has_rfc_editor_note()
|
||||
|
||||
elif doc.type_id == 'conflrev':
|
||||
docinfo['rev'] = doc.rev
|
||||
td = doc.relateddocument_set.get(relationship__slug='conflrev').target.document
|
||||
|
|
|
@ -57,7 +57,14 @@ def get_doc_writeup(doc):
|
|||
want to display the contents of the document
|
||||
'''
|
||||
writeup = 'This document has no writeup'
|
||||
if doc.type_id in ('draft','charter'):
|
||||
if doc.type_id == 'draft':
|
||||
latest = doc.latest_event(WriteupDocEvent, type='changed_ballot_writeup_text')
|
||||
if latest and doc.has_rfc_editor_note:
|
||||
rfced_note = doc.latest_event(WriteupDocEvent, type="changed_rfc_editor_note_text")
|
||||
writeup = latest.text + "\n\n" + rfced_note.text
|
||||
else:
|
||||
writeup = latest.text
|
||||
if doc.type_id == 'charter':
|
||||
latest = doc.latest_event(WriteupDocEvent, type='changed_ballot_writeup_text')
|
||||
if latest:
|
||||
writeup = latest.text
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% extends "base.html" %}
|
||||
{# Copyright The IETF Trust 2015, All Rights Reserved #}
|
||||
{# Copyright The IETF Trust 2016, All Rights Reserved #}
|
||||
{% load origin %}
|
||||
|
||||
{% load bootstrap3 %}
|
||||
|
@ -18,7 +18,7 @@
|
|||
{% bootstrap_form ballot_writeup_form %}
|
||||
|
||||
<div class="help-block">
|
||||
Technical summary, Working Group summary, document quality, personnel, RFC Editor note, IRTF note, IESG note, IANA note. This text will be appended to all announcements and messages to the IRTF or RFC Editor.
|
||||
Technical summary, Working Group summary, document quality, personnel, IRTF note, IESG note, IANA note. This text will be appended to all announcements and messages to the IRTF or RFC Editor.
|
||||
</div>
|
||||
|
||||
{% buttons %}
|
||||
|
|
|
@ -32,10 +32,6 @@ Personnel
|
|||
experts(s), insert 'The IANA Expert(s) for the registries
|
||||
in this document are <TO BE ADDED BY THE AD>.'
|
||||
|
||||
RFC Editor Note
|
||||
|
||||
(Insert RFC Editor Note here or remove section)
|
||||
|
||||
IRTF Note
|
||||
|
||||
(Insert IRTF Note here or remove section)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{# Copyright The IETF Trust 2015, All Rights Reserved #}{% load origin %}{% origin %}
|
||||
{# Copyright The IETF Trust 2016, All Rights Reserved #}{% load origin %}{% origin %}
|
||||
{% load ietf_filters ballot_icon %}
|
||||
|
||||
<div class="pull-right">{% ballot_icon doc %}</div>
|
||||
|
@ -20,6 +20,9 @@
|
|||
<span class="fa fa-file"></span></a>
|
||||
{% endwith %}
|
||||
<a href="{% url "doc_view" name=doc.canonical_name %}">{{ doc.canonical_name }}</a>
|
||||
{% if doc.has_rfc_editor_note %}
|
||||
<a href="{% url "doc_view" name=doc.canonical_name %}writeup/"> <em>(Has RFC Editor Note)</em></a>
|
||||
{% endif %}
|
||||
</dd>
|
||||
|
||||
<dt>{{ doc.intended_std_level }}</dt><dd><b>{{ doc.title }}</b></dd>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% load ietf_filters %}{% with doc.rfc_number as rfc_number %}
|
||||
o {{doc.canonical_name}}{% if not rfc_number %}-{{doc.rev}}{% endif %}{% endwith %}{% if doc.stream %} - {{ doc.stream }} stream{% endif %}
|
||||
o {{doc.canonical_name}}{% if not rfc_number %}-{{doc.rev}}{% endif %}{% endwith %}{%if doc.has_rfc_editor_note %} (Has RFC Editor Note){% endif %}{% if doc.stream %} - {{ doc.stream }} stream{% endif %}
|
||||
{% filter wordwrap:"68"|indent|indent %}{{ doc.title }} ({{ doc.intended_std_level }}){% endfilter %}
|
||||
{% if doc.note %}{# note: note is not escaped #} {% filter wordwrap:"68"|indent|indent %}Note: {{ doc.note|striptags }}{% endfilter %}
|
||||
{% endif %} Token: {{ doc.ad }}{% if doc.iana_review_state %}
|
||||
|
|
Loading…
Reference in a new issue