Final corrections and coord with Ole. Fixed agenda package, template cleanup, more tests and a couple of bugs.

- Legacy-Id: 3360
This commit is contained in:
Martin Qvist 2011-08-24 08:42:51 +00:00
parent 2ed5c356d4
commit ecac9c2e11
24 changed files with 426 additions and 216 deletions

View file

@ -208,6 +208,19 @@ def get_doc_sectionREDESIGN(id):
s = s + "1"
return s
def get_wg_section(wg):
if wg.state_id == "proposed":
if wg.charter.charter_state_id == "intrev":
s = '411'
elif wg.charter.charter_state_id == "iesgrev":
s = '412'
elif wg.state_id == "active":
if wg.charter.charter_state_id == "intrev":
s = '421'
elif wg.charter.charter_state_id == "iesgrev":
s = '422'
return s
if settings.USE_DB_REDESIGN_PROXY_CLASSES:
get_doc_section = get_doc_sectionREDESIGN
@ -253,15 +266,17 @@ def agenda_docs(date, next_agenda):
return res
def agenda_wg_actions(date):
mapping = {12:'411', 13:'412',22:'421',23:'422'}
matches = WGAction.objects.filter(agenda=1,telechat_date=date,category__in=mapping.keys()).order_by('category')
res = {}
for o in matches:
section_key = "s"+mapping[o.category]
from doc.models import TelechatDocEvent
from group.models import Group
matches = Group.objects.filter(charter__docevent__telechatdocevent__telechat_date=date)
res = dict(("s%s%s%s" % (i, j, k), []) for i in range(2, 5) for j in range (1, 4) for k in range(1, 4))
for wg in list(matches):
section_key = "s"+get_wg_section(wg)
if section_key not in res:
res[section_key] = []
area = AreaGroup.objects.get(group=o.group_acronym)
res[section_key].append({'obj':o, 'area':str(area.area)})
res[section_key].append({'obj':wg})
return res
def agenda_management_issues(date):

View file

@ -43,20 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endif %}
<tr>
<td>{{wg.area|upper}}</td>
<td>{{ wg.obj.status_date|date:"M d"}}</td>
<td>{{wg.obj.parent.name|upper}}</td>
<td>{{ wg.obj.time|date:"M d"}}</td>
<td>
<a href="http://www.ietf.org/iesg/evaluation/{{wg.obj.group_acronym}}-charter.txt">
{{ wg.obj.group_acronym.name|escape }} ({{wg.obj.group_acronym}})
<a href="http://www.ietf.org/iesg/evaluation/charter-ietf-{{wg.obj.acronym}}-{{wg.obj.charter.rev}}.txt">
{{ wg.obj.name|escape }} ({{wg.obj.acronym}})
</a>
</td>
</tr>
{% if wg.obj.token_name %}
<tr><td></td><td>Token:</td><td>{{ wg.obj.token_name|escape }}</td></tr>
{% endif %}
{% if wg.obj.note %}
<tr><td></td><td></td><td>Note: {{wg.obj.note|escape}}</td></tr>
{% endif %}
{% if forloop.last %}
</table>

View file

@ -35,11 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{{ title2 }}
{% endif %}{{ title3 }}
{% for wg in section_wgs %}
o {{ wg.obj.group_acronym.name }} ({{wg.obj.group_acronym}})
{% if wg.obj.token_name %} Token: {{ wg.obj.token_name }}
{% endif %}
{% if wg.obj.note %} {% filter wordwrap:"68"|indent|indent %}Note: {{wg.obj.note|striptags}}{% endfilter %}
{% endif %}
o {{ wg.obj.name }} ({{wg.obj.acronym}})
{% empty %}
NONE
{% endfor %}

View file

@ -36,14 +36,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{{ title2 }}<br>
{{ title3 }} ({{ forloop.counter }} of {{ section_wgs|length }})</h3>
<p><b>{{ wg.obj.group_acronym.name }} ({{wg.obj.group_acronym}})<br>
{% if wg.obj.token_name %}
Token: {{ wg.obj.token_name }}
{% endif %}</b></p>
{% if wg.obj.note %}
<p>Note: {{wg.obj.note|striptags}}</p>
{% endif %}
<p><b>{{ wg.obj.name }} ({{wg.obj.acronym}})<br>
{% if title3|startswith:"4.1.1" %}
<p>Does anyone have an objection to the charter being sent for

View file

@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block title %}WG {{ announcement }} announcement writeup for {{ doc.group.acronym }}{% endblock %}
{% block title %}WG {{ announcement }} announcement writeup for {{ charter.chartered_group.acronym }}{% endblock %}
{% block morecss %}
form #id_announcement_text {
@ -10,7 +10,7 @@ form #id_announcement_text {
{% endblock %}
{% block content %}
<h1>WG {{ announcement }} announcement writeup for {{ doc.group.acronym }}</h1>
<h1>WG {{ announcement }} announcement writeup for {{ charter.chartered_group.acronym }}</h1>
<form action="" method="POST">
@ -22,12 +22,4 @@ form #id_announcement_text {
</div>
</form>
{% load ietf_filters %}
{% if user|in_group:"Secretariat" %}
<p>
{% if can_announce %}
<a href="{% url doc_approve_ballot name=doc.name %}">Approve ballot</a>
{% endif %}
</p>
{% endif %}
{% endblock%}

View file

@ -1,5 +1,5 @@
{% autoescape off %}{{ ad }} has entered the following ballot position for
{{ doc.filename }}-{{ doc.revision_display }}: {{ pos.name }}
{{ charter.name }}-{{ charter.rev }}: {{ pos.name }}
When responding, please keep the subject line intact and reply to all
email addresses included in the To and CC lines. (Feel free to cut this

View file

@ -1,13 +0,0 @@
{% extends "base.html" %}
{% block title %}Ballot for {{ doc }} issued{% endblock %}
{% block content %}
<h1>Ballot for {{ doc }} issued</h1>
<p>Ballot has been sent out.</p>
<div class="actions">
<a href="{{ back_url }}">Back to document</a>
</div>
{% endblock %}

View file

@ -1,36 +0,0 @@
{% extends "base.html" %}
{% block title %}Ballot writeup and notes for {{ doc }}{% endblock %}
{% block morecss %}
form #id_ballot_writeup {
width: 700px;
height: 600px;
}
{% endblock %}
{% block content %}
<h1>Ballot writeup and notes for {{ doc }}</h1>
<form action="" method="POST">
<p>(Technical Summary, Working Group Summary, Document Quality,
Personnel, RFC Editor Note, IRTF Note, IESG Note, IANA Note)</p>
<p>This text will be appended to all announcements and messages to
the IRTF or RFC Editor.</p>
{{ ballot_writeup_form.ballot_writeup }}
{% if not approval %}<p style="font-style:italic">Ballot cannot be issued before <a href="{% url doc_ballot_approvaltext name=doc.name %}">announcement text</a> is added.</p>{% endif %}
<div class="actions">
<a href="{{ back_url }}">Back</a>
<input type="submit" name="save_ballot_writeup" value="Save Ballot Writeup" />
<input style="margin-left: 8px" type="submit" {% if not approval %}disabled="disabled"{% endif %} name="issue_ballot" value="Save and {% if ballot_issued %}Re-{% endif %}Issue Ballot" />
</div>
</form>
{% endblock%}

View file

@ -3,10 +3,6 @@
{% block title %}Change position for {{ ad.name }} on {{ wg.acronym }}{% endblock %}
{% block morecss %}
div.ballot-deferred {
margin-top: 8px;
margin-bottom: 8px;
}
form.position-form .position ul {
padding: 0;
margin: 0;

View file

@ -40,7 +40,7 @@ Copyright The IETF Trust 2011, All Rights Reserved
{% for pos in info.positions %}
{% if pos.comment or pos.block_comment %}
<h2 class="ballot_ad"><a name="{{pos.ad|slugify}}">{% if pos.is_old_ad %}[{%endif%}{{pos.ad|escape}}{% if pos.is_old_ad %}]{%endif%}</a></h2>
<h2 class="ballot_ad"><a name="{{pos.ad|slugify}}">{{pos.ad|escape}}</a></h2>
{% if pos.block_comment %}
<p><b>Blocking ({{pos.block_comment_time}})</b> <img src="/images/comment.png" width="14" height="12" alt=""/></p>

View file

@ -1,7 +1,6 @@
{% load ietf_filters %}
{% for p in positions %}
{% if p.is_old_ad %}[{%endif%}<a{% if user|in_group:"Secretariat" %} href="{% url wg_edit_position name=wg.acronym %}?ad={{ p.ad_id }}" title="Click to edit the position of {{ p.ad }}"{% endif %}>{{p.ad}}</a>{% if p.is_old_ad %}]{%endif%}{% if p.comment or p.block_comment %}&nbsp;<a href="#{{p.ad|slugify}}"><img src="/images/comment.png" width="14" height="12" alt="*" border="0"/></a>{% endif %}<br/>
{% if p.old_positions %}<span class="was">(was {{p.old_positions|join:", "}})</span><br/>{%endif%}
<a{% if user|in_group:"Secretariat" %} href="{% url wg_edit_position name=wg.acronym %}?ad={{ p.ad_id }}" title="Click to edit the position of {{ p.ad }}"{% endif %}>{{p.ad}}</a>{% if p.comment or p.block_comment %}&nbsp;<a href="#{{p.ad|slugify}}"><img src="/images/comment.png" width="14" height="12" alt="*" border="0"/></a>{% endif %}<br/>
{% empty %}
<i>none</i>
{% endfor %}

View file

@ -29,12 +29,8 @@ Copyright The IETF Trust 2011, All Rights Reserved
{{ c.info.text|fill:"80"|safe|urlize|linebreaksbr|keep_spacing|sanitize_html|safe }}
</div>
{% else %}
{% if c.info.dontmolest %}
{{ c.info.text|safe }}
{% else %}
{{ c.info.text|fill:"80"|safe|urlize|linebreaksbr|keep_spacing|sanitize_html|safe }}
{% endif %}
{% endif %}
</td>
{% endif %}

View file

@ -26,9 +26,7 @@ div.diffTool { padding: 8px 4px; margin: 8px 0;}
{% endblock %}
{% block pagehead %}
{% if doc.in_ietf_process %}
<link rel="alternate" type="application/atom+xml" href="/feed/comments/{{ wg.name }}/" />
{% endif %}
<link rel="alternate" type="application/atom+xml" href="/feed/wgcomments/{{ wg.acronym }}/" />
<meta name="description" content="{% include "wgrecord/wg_description.html" %}" />
{% endblock %}

View file

@ -21,14 +21,7 @@ form.send-ballot pre {
<tr>
<th>Cc:<br/>
<span class="help">separated<br/> by comma</span></th>
<td><input type="text" name="cc" value="" size="75" /><br/>
{% if doc.idinternal.state_change_notice_to %}
<label>
<input type="checkbox" name="cc_state_change" value="1" checked="yes" />
{{ doc.idinternal.state_change_notice_to }}
</label>
{% endif %}
</td>
<td><input type="text" name="cc" value="" size="75" /></td>
</tr>
<tr><th>Subject:</th> <td>{{ subject }}</td></tr>
<tr>

View file

@ -4,27 +4,9 @@
Charter submission for {{ wg.acronym }}
{% endblock %}
{% block morecss %}
.ietf-navset {
background:#214197 url(/images/yui/sprite.png) repeat-x left -1400px;
color:white;
border:1px solid black;
padding:4px;
}
.ietf-navset .selected { font-weight:bold; padding: 0 3px; }
.ietf-navset a, .ietf-navset a:visited { color: white; padding:0 3px; }
.cutoff-warning { border: 1px dashed red; background-color: #ffeeaa; padding: 1em 2em; margin: 1em 0px; }
{% endblock %}
{% block content %}
<h1>Charter submission for {{ wg.acronym }}</h1>
{% if form.cutoff_warning %}
<div class="cutoff-warning">
{{ form.cutoff_warning|safe }}
</div>
{% endif %}
<p>The text will be submitted as <strong>charter-ietf-{{ wg.acronym }}-{{ next_rev }}</strong></p>
<form class="edit-info" action="" enctype="multipart/form-data" method="POST">
<table>

View file

@ -1 +1 @@
FIXME: description of {{ wg.name }}
IETF Working Group {{ wg.name }} ({{ wg.acronym }}){% if wg.parent %} under the {{ wg.parent }}{% endif %}

View file

@ -359,3 +359,296 @@ class WgInfoTestCase(django.test.TestCase):
self.assertEquals(charter.rev, next_revision(prev_rev))
self.assertTrue("new_revision" in charter.latest_event().type)
class WgAddCommentTestCase(django.test.TestCase):
fixtures = ['names']
def test_add_comment(self):
make_test_data()
# Make sure all relevant names are created
type_charter = name(DocTypeName, "charter", "Charter")
active = name(GroupStateName, "active", "Active")
notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review")
infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review")
intrev=name(CharterDocStateName, slug="intrev", name="Internal review")
extrev=name(CharterDocStateName, slug="extrev", name="External review")
iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review")
approved=name(CharterDocStateName, slug="approved", name="Approved")
group = Group.objects.get(acronym="mars")
url = urlreverse('wg_add_comment', kwargs=dict(name=group.acronym))
login_testing_unauthorized(self, "secretary", url)
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertEquals(len(q('form textarea[name=comment]')), 1)
# request resurrect
comments_before = group.groupevent_set.filter(type="added_comment").count()
r = self.client.post(url, dict(comment="This is a test."))
self.assertEquals(r.status_code, 302)
self.assertEquals(group.groupevent_set.filter(type="added_comment").count(), comments_before + 1)
self.assertTrue("This is a test." in group.groupevent_set.filter(type="added_comment").order_by('-time')[0].desc)
class WgEditPositionTestCase(django.test.TestCase):
fixtures = ['names', 'ballot']
def test_edit_position(self):
make_test_data()
# Make sure all relevant names are created
type_charter = name(DocTypeName, "charter", "Charter")
active = name(GroupStateName, "active", "Active")
notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review")
infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review")
intrev=name(CharterDocStateName, slug="intrev", name="Internal review")
extrev=name(CharterDocStateName, slug="extrev", name="External review")
iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review")
approved=name(CharterDocStateName, slug="approved", name="Approved")
no = name(GroupBallotPositionName, 'no', 'No'),
yes = name(GroupBallotPositionName, 'yes', 'Yes'),
abstain = name(GroupBallotPositionName, 'abstain', 'Abstain'),
block = name(GroupBallotPositionName, 'block', 'Block'),
norecord = name(GroupBallotPositionName, 'norecord', 'No record'),
group = Group.objects.get(acronym="mars")
url = urlreverse('wg_edit_position', kwargs=dict(name=group.acronym))
login_testing_unauthorized(self, "ad", url)
charter = set_or_create_charter(group)
p = Person.objects.get(name="Aread Irector")
e = DocEvent()
e.type = "started_iesg_process"
e.by = p
e.doc = charter
e.desc = "IESG process started"
e.save()
charter.charter_state = iesgrev
charter.save()
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form input[name=position]')) > 0)
self.assertEquals(len(q('form textarea[name=comment]')), 1)
# vote
pos_before = charter.docevent_set.filter(type="changed_ballot_position").count()
self.assertTrue(not charter.docevent_set.filter(type="changed_ballot_position", by__name="Aread Irector"))
r = self.client.post(url, dict(position="block",
block_comment="This is a blocking test.",
comment="This is a test."))
self.assertEquals(r.status_code, 302)
self.assertEquals(charter.docevent_set.filter(type="changed_ballot_position").count(), pos_before + 1)
e = charter.latest_event(GroupBallotPositionDocEvent)
self.assertTrue("This is a blocking test." in e.block_comment)
self.assertTrue("This is a test." in e.comment)
self.assertTrue(e.pos_id, "block")
# recast vote
pos_before = charter.docevent_set.filter(type="changed_ballot_position").count()
r = self.client.post(url, dict(position="yes"))
self.assertEquals(r.status_code, 302)
self.assertEquals(charter.docevent_set.filter(type="changed_ballot_position").count(), pos_before + 1)
e = charter.latest_event(GroupBallotPositionDocEvent)
self.assertTrue(e.pos_id, "yes")
# clear vote
pos_before = charter.docevent_set.filter(type="changed_ballot_position").count()
r = self.client.post(url, dict(position="norecord"))
self.assertEquals(r.status_code, 302)
self.assertEquals(charter.docevent_set.filter(type="changed_ballot_position").count(), pos_before + 1)
e = charter.latest_event(GroupBallotPositionDocEvent)
self.assertTrue(e.pos_id, "norecord")
def test_edit_position_as_secretary(self):
make_test_data()
# Make sure all relevant names are created
type_charter = name(DocTypeName, "charter", "Charter")
active = name(GroupStateName, "active", "Active")
notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review")
infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review")
intrev=name(CharterDocStateName, slug="intrev", name="Internal review")
extrev=name(CharterDocStateName, slug="extrev", name="External review")
iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review")
approved=name(CharterDocStateName, slug="approved", name="Approved")
no = name(GroupBallotPositionName, 'no', 'No'),
yes = name(GroupBallotPositionName, 'yes', 'Yes'),
abstain = name(GroupBallotPositionName, 'abstain', 'Abstain'),
block = name(GroupBallotPositionName, 'block', 'Block'),
norecord = name(GroupBallotPositionName, 'norecord', 'No record'),
group = Group.objects.get(acronym="mars")
url = urlreverse('wg_edit_position', kwargs=dict(name=group.acronym))
p = Person.objects.get(name="Aread Irector")
url += "?ad=%d" % p.id
login_testing_unauthorized(self, "secretary", url)
charter = set_or_create_charter(group)
e = DocEvent()
e.type = "started_iesg_process"
e.by = p
e.doc = charter
e.desc = "IESG process started"
e.save()
charter.charter_state = iesgrev
charter.save()
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form input[name=position]')) > 0)
# vote for rhousley
pos_before = charter.docevent_set.filter(type="changed_ballot_position").count()
self.assertTrue(not charter.docevent_set.filter(type="changed_ballot_position", by__name="Sec Retary"))
r = self.client.post(url, dict(position="no"))
self.assertEquals(r.status_code, 302)
self.assertEquals(charter.docevent_set.filter(type="changed_ballot_position").count(), pos_before + 1)
e = charter.latest_event(GroupBallotPositionDocEvent)
self.assertTrue(e.pos_id, "no")
def test_send_ballot_comment(self):
make_test_data()
# Make sure all relevant names are created
type_charter = name(DocTypeName, "charter", "Charter")
active = name(GroupStateName, "active", "Active")
notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review")
infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review")
intrev=name(CharterDocStateName, slug="intrev", name="Internal review")
extrev=name(CharterDocStateName, slug="extrev", name="External review")
iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review")
approved=name(CharterDocStateName, slug="approved", name="Approved")
no = name(GroupBallotPositionName, 'no', 'No'),
yes = name(GroupBallotPositionName, 'yes', 'Yes'),
abstain = name(GroupBallotPositionName, 'abstain', 'Abstain'),
block = name(GroupBallotPositionName, 'block', 'Block'),
norecord = name(GroupBallotPositionName, 'norecord', 'No record'),
group = Group.objects.get(acronym="mars")
url = urlreverse('wg_send_ballot_comment', kwargs=dict(name=group.acronym))
login_testing_unauthorized(self, "ad", url)
charter = set_or_create_charter(group)
p = Person.objects.get(name="Aread Irector")
e = DocEvent()
e.type = "started_iesg_process"
e.by = p
e.doc = charter
e.desc = "IESG process started"
e.save()
charter.charter_state = iesgrev
charter.save()
GroupBallotPositionDocEvent.objects.create(
doc=charter,
by=p,
type="changed_ballot_position",
pos=GroupBallotPositionName.objects.get(slug="block"),
ad=p,
block_comment="This is a block test",
comment="This is a test",
)
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue(len(q('form input[name="cc"]')) > 0)
# send
p = Person.objects.get(name="Aread Irector")
mailbox_before = len(mail_outbox)
r = self.client.post(url, dict(cc="test@example.com", cc_state_change="1"))
self.assertEquals(r.status_code, 302)
self.assertEquals(len(mail_outbox), mailbox_before + 1)
self.assertTrue("BLOCKING COMMENT" in mail_outbox[-1]['Subject'])
self.assertTrue("COMMENT" in mail_outbox[-1]['Subject'])
class WgApproveBallotTestCase(django.test.TestCase):
fixtures = ['base', 'names', 'ballot']
def test_approve_ballot(self):
make_test_data()
# Make sure all relevant names are created
type_charter = name(DocTypeName, "charter", "Charter")
proposed = name(GroupStateName, "proposed", "Proposed")
active = name(GroupStateName, "active", "Active")
notrev=name(CharterDocStateName, slug="notrev", name="Not currently under review")
infrev=name(CharterDocStateName, slug="infrev", name="Informal IESG review")
intrev=name(CharterDocStateName, slug="intrev", name="Internal review")
extrev=name(CharterDocStateName, slug="extrev", name="External review")
iesgrev=name(CharterDocStateName, slug="iesgrev", name="IESG review")
approved=name(CharterDocStateName, slug="approved", name="Approved")
no = name(GroupBallotPositionName, 'no', 'No'),
yes = name(GroupBallotPositionName, 'yes', 'Yes'),
abstain = name(GroupBallotPositionName, 'abstain', 'Abstain'),
block = name(GroupBallotPositionName, 'block', 'Block'),
norecord = name(GroupBallotPositionName, 'norecord', 'No record'),
group = Group.objects.get(acronym="mars")
url = urlreverse('wg_approve_ballot', kwargs=dict(name=group.acronym))
login_testing_unauthorized(self, "secretary", url)
charter = set_or_create_charter(group)
p = Person.objects.get(name="Aread Irector")
e = DocEvent()
e.type = "started_iesg_process"
e.by = p
e.doc = charter
e.desc = "IESG process started"
e.save()
charter.charter_state = iesgrev
charter.save()
# normal get
r = self.client.get(url)
self.assertEquals(r.status_code, 200)
q = PyQuery(r.content)
self.assertTrue("Send out the announcement" in q('input[type=submit]')[0].get('value'))
self.assertEquals(len(q('pre')), 1)
# approve
mailbox_before = len(mail_outbox)
# Dont copy the actual txt file
from django.conf import settings
settings.DONT_COPY_CHARTER_ON_APPROVE = True
r = self.client.post(url, dict())
self.assertEquals(r.status_code, 302)
charter = Document.objects.get(name=charter.name)
self.assertEquals(charter.charter_state_id, "approved")
self.assertEquals(charter.rev, "01")
self.assertEquals(len(mail_outbox), mailbox_before + 2)
self.assertTrue("WG Action" in mail_outbox[-1]['Subject'])
self.assertTrue("Charter approved" in mail_outbox[-2]['Subject'])

View file

@ -14,16 +14,16 @@ urlpatterns += patterns('',
(r'^searchPerson/$', views_search.search_person),
url(r'^ad/(?P<name>[A-Za-z0-9.-]+)/$', views_search.by_ad, name="wg_search_by_ad"),
url(r'^in_process/$', views_search.in_process, name="wg_search_in_process"),
url(r'^(?P<name>[A-Za-z0-9._-]+)/((?P<rev>[0-9][0-9](-[0-9][0-9])?)/)?((?P<tab>ballot|writeup|history)/)?$', views_rec.wg_main, name="wg_view_record"),
(r'^(?P<name>[A-Za-z0-9._-]+)/_ballot.data$', views_rec.wg_ballot),
url(r'^(?P<name>[A-Za-z0-9._-]+)/edit/state/$', views_edit.change_state, name='wg_change_state'),
url(r'^(?P<name>[A-Za-z0-9._-]+)/edit/info/$', views_edit.edit_info, name='wg_edit_info'),
url(r'^(?P<name>[A-Za-z0-9._-]+)/edit/conclude/$', views_edit.conclude, name='wg_conclude'),
url(r'^(?P<name>[A-Za-z0-9._-]+)/edit/addcomment/$', views_edit.add_comment, name='wg_add_comment'),
url(r'^(?P<name>[A-Za-z0-9._-]+)/edit/(?P<ann>action|review)/$', views_ballot.announcement_text, name='wg_announcement_text'),
url(r'^(?P<name>[A-Za-z0-9._-]+)/edit/position/$', views_ballot.edit_position, name='wg_edit_position'),
url(r'^(?P<name>[A-Za-z0-9._-]+)/edit/sendballotcomment/$', views_ballot.send_ballot_comment, name='wg_send_ballot_comment'),
url(r'^(?P<name>[A-Za-z0-9._-]+)/edit/approveballot/$', views_ballot.approve_ballot, name='wg_approve_ballot'),
url(r'^(?P<name>[A-Za-z0-9._-]+)/submit/$', views_submit.submit, name='wg_submit'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/((?P<rev>[0-9][0-9](-[0-9][0-9])?)/)?((?P<tab>ballot|writeup|history)/)?$', views_rec.wg_main, name="wg_view_record"),
(r'^(?P<name>[A-Za-z0-9._+-]+)/_ballot.data$', views_rec.wg_ballot),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/state/$', views_edit.change_state, name='wg_change_state'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/info/$', views_edit.edit_info, name='wg_edit_info'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/conclude/$', views_edit.conclude, name='wg_conclude'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/addcomment/$', views_edit.add_comment, name='wg_add_comment'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/(?P<ann>action|review)/$', views_ballot.announcement_text, name='wg_announcement_text'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/position/$', views_ballot.edit_position, name='wg_edit_position'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/sendballotcomment/$', views_ballot.send_ballot_comment, name='wg_send_ballot_comment'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/edit/approveballot/$', views_ballot.approve_ballot, name='wg_approve_ballot'),
url(r'^(?P<name>[A-Za-z0-9._+-]+)/submit/$', views_submit.submit, name='wg_submit'),
)

View file

@ -24,12 +24,14 @@ from group.models import Group, GroupHistory, GroupEvent, save_group_in_history
from name.models import GroupBallotPositionName, CharterDocStateName, GroupStateName
from doc.models import Document, DocEvent, GroupBallotPositionDocEvent, WriteupDocEvent
def default_action_text(wg, doc, user):
e = WriteupDocEvent(doc=doc, by=user)
def default_action_text(wg, charter, user):
e = WriteupDocEvent(doc=charter, by=user)
e.by = user
e.type = "changed_action_announcement"
e.desc = "WG action text was changed"
e.text = "The %s (%s) working group " % (wg.name, wg.acronym)
e.text = "To: ietf-announce@ietf.org\n"
e.text += "Subject: WG Action: %s (%s)\n" % (wg.name, wg.acronym)
e.text += "The %s (%s) working group " % (wg.name, wg.acronym)
if wg.parent:
e.text += "in the %s " % wg.parent.name
e.text += "of the IETF has been "
@ -41,15 +43,17 @@ def default_action_text(wg, doc, user):
e.save()
return e
def default_review_text(wg, doc, user):
e = WriteupDocEvent(doc=doc, by=user)
def default_review_text(wg, charter, user):
e = WriteupDocEvent(doc=charter, by=user)
e.by = user
e.type = "changed_review_announcement"
e.desc = "WG review text was changed"
e.text = "To: ietf-announce@ietf.org\n"
e.text += "Subject: WG Review: %s (%s)\n" % (wg.name, wg.acronym)
if wg.state_id == "proposed":
e.text = "A charter"
e.text += "A charter"
else:
e.text = "A modified charter"
e.text += "A modified charter"
e.text += " has been submitted for the %s (%s) working group \n" % (wg.name, wg.acronym)
if wg.parent:
e.text += "in the %s " % wg.parent.name
@ -100,15 +104,17 @@ def edit_position(request, name):
else:
raise Http404
doc = set_or_create_charter(wg)
started_process = doc.latest_event(type="started_iesg_process")
charter = set_or_create_charter(wg)
started_process = charter.latest_event(type="started_iesg_process")
if not started_process:
raise Http404
ad = login = request.user.get_profile()
if 'HTTP_REFERER' in request.META:
return_to_url = request.META['HTTP_REFERER']
else:
return_to_url = doc.get_absolute_url()
return_to_url = charter.get_absolute_url()
# if we're in the Secretariat, we can select an AD to act as stand-in for
if not has_role(request.user, "Area Director"):
@ -118,7 +124,7 @@ def edit_position(request, name):
from person.models import Person
ad = get_object_or_404(Person, pk=ad_id)
old_pos = doc.latest_event(GroupBallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time)
old_pos = charter.latest_event(GroupBallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time)
if request.method == 'POST':
form = EditPositionForm(request.POST)
@ -130,7 +136,7 @@ def edit_position(request, name):
if clean['return_to_url']:
return_to_url = clean['return_to_url']
pos = GroupBallotPositionDocEvent(doc=doc, by=login)
pos = GroupBallotPositionDocEvent(doc=charter, by=login)
pos.type = "changed_ballot_position"
pos.ad = ad
pos.pos = clean["position"]
@ -149,7 +155,7 @@ def edit_position(request, name):
changes.append("comment")
if pos.comment:
e = DocEvent(doc=doc)
e = DocEvent(doc=charter)
e.by = ad # otherwise we can't see who's saying it
e.type = "added_comment"
e.desc = "[Ballot comment]\n" + pos.comment
@ -161,7 +167,7 @@ def edit_position(request, name):
changes.append("block_comment")
if pos.block_comment:
e = DocEvent(doc=doc, by=login)
e = DocEvent(doc=charter, by=login)
e.by = ad # otherwise we can't see who's saying it
e.type = "added_comment"
e.desc = "[Ballot blocking comment]\n" + pos.block_comment
@ -186,8 +192,8 @@ def edit_position(request, name):
for e in added_events:
e.save() # save them after the position is saved to get later id
doc.time = pos.time
doc.save()
charter.time = pos.time
charter.save()
if request.POST.get("send_mail"):
qstr = "?return_to_url=%s" % return_to_url
@ -209,7 +215,7 @@ def edit_position(request, name):
form = EditPositionForm(initial=initial)
return render_to_response('wgrecord/edit_position.html',
dict(doc=doc,
dict(charter=charter,
wg=wg,
form=form,
ad=ad,
@ -230,8 +236,8 @@ def send_ballot_comment(request, name):
else:
raise Http404
doc = set_or_create_charter(wg)
started_process = doc.latest_event(type="started_iesg_process")
charter = set_or_create_charter(wg)
started_process = charter.latest_event(type="started_iesg_process")
if not started_process:
raise Http404()
@ -239,12 +245,12 @@ def send_ballot_comment(request, name):
return_to_url = request.GET.get('return_to_url')
if not return_to_url:
return_to_url = doc.get_absolute_url()
return_to_url = charter.get_absolute_url()
if 'HTTP_REFERER' in request.META:
back_url = request.META['HTTP_REFERER']
else:
back_url = doc.get_absolute_url()
back_url = charter.get_absolute_url()
# if we're in the Secretariat, we can select an AD to act as stand-in for
if not has_role(request.user, "Area Director"):
@ -254,7 +260,7 @@ def send_ballot_comment(request, name):
from person.models import Person
ad = get_object_or_404(Person, pk=ad_id)
pos = doc.latest_event(GroupBallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time)
pos = charter.latest_event(GroupBallotPositionDocEvent, type="changed_ballot_position", ad=ad, time__gte=started_process.time)
if not pos:
raise Http404()
@ -269,28 +275,23 @@ def send_ballot_comment(request, name):
subj.append("COMMENT")
ad_name_genitive = ad.name + "'" if ad.name.endswith('s') else ad.name + "'s"
subject = "%s %s on %s" % (ad_name_genitive, pos.pos.name if pos.pos else "No Position", doc.name + "-" + doc.rev)
subject = "%s %s on %s" % (ad_name_genitive, pos.pos.name if pos.pos else "No Position", charter.name + "-" + charter.rev)
if subj:
subject += ": (with %s)" % " and ".join(subj)
doc.filename = doc.name # compatibility attributes
doc.revision_display = doc.rev
body = render_to_string("wgrecord/ballot_comment_mail.txt",
dict(block_comment=d, comment=c, ad=ad.name, doc=doc, pos=pos.pos))
dict(block_comment=d, comment=c, ad=ad.name, charter=charter, pos=pos.pos))
frm = ad.formatted_email()
to = "The IESG <iesg@ietf.org>"
if request.method == 'POST':
cc = [x.strip() for x in request.POST.get("cc", "").split(',') if x.strip()]
if request.POST.get("cc_state_change") and doc.notify:
cc.extend(doc.notify.split(','))
send_mail_text(request, to, frm, subject, body, cc=", ".join(cc))
return HttpResponseRedirect(return_to_url)
return render_to_response('wgrecord/send_ballot_comment.html',
dict(doc=doc,
dict(charter=charter,
subject=subject,
body=body,
frm=frm,
@ -319,19 +320,19 @@ def announcement_text(request, name, ann):
else:
raise Http404
doc = set_or_create_charter(wg)
charter = set_or_create_charter(wg)
login = request.user.get_profile()
if ann == "action":
existing = doc.latest_event(WriteupDocEvent, type="changed_action_announcement")
existing = charter.latest_event(WriteupDocEvent, type="changed_action_announcement")
elif ann == "review":
existing = doc.latest_event(WriteupDocEvent, type="changed_review_announcement")
existing = charter.latest_event(WriteupDocEvent, type="changed_review_announcement")
if not existing:
if ann == "action":
existing = default_action_text(wg, doc, login)
existing = default_action_text(wg, charter, login)
elif ann == "review":
existing = default_review_text(wg, doc, login)
existing = default_review_text(wg, charter, login)
form = AnnouncementTextForm(initial=dict(announcement_text=existing.text))
@ -340,20 +341,20 @@ def announcement_text(request, name, ann):
if form.is_valid():
t = form.cleaned_data['announcement_text']
if t != existing.text:
e = WriteupDocEvent(doc=doc, by=login)
e = WriteupDocEvent(doc=charter, by=login)
e.by = login
e.type = "changed_%s_announcement" % ann
e.desc = "WG %s text was changed" % ann
e.text = t
e.save()
doc.time = e.time
doc.save()
charter.time = e.time
charter.save()
return redirect('wg_view_record', name=wg.acronym)
return render_to_response('wgrecord/announcement_text.html',
dict(doc=doc,
dict(charter=charter,
announcement=ann,
back_url=doc.get_absolute_url(),
back_url=charter.get_absolute_url(),
announcement_text_form=form,
),
context_instance=RequestContext(request))
@ -370,13 +371,13 @@ def approve_ballot(request, name):
else:
raise Http404
doc = set_or_create_charter(wg)
charter = set_or_create_charter(wg)
login = request.user.get_profile()
e = doc.latest_event(WriteupDocEvent, type="changed_action_announcement")
e = charter.latest_event(WriteupDocEvent, type="changed_action_announcement")
if not e:
announcement = default_action_text(wg, doc, login)
announcement = default_action_text(wg, charter, login).text
else:
announcement = e.text
@ -384,15 +385,15 @@ def approve_ballot(request, name):
new_state = GroupStateName.objects.get(slug="active")
new_charter_state = CharterDocStateName.objects.get(slug="approved")
save_charter_in_history(doc)
save_charter_in_history(charter)
save_group_in_history(wg)
prev_state = wg.state
prev_charter_state = doc.charter_state
prev_charter_state = charter.charter_state
wg.state = new_state
doc.charter_state = new_charter_state
charter.charter_state = new_charter_state
e = DocEvent(doc=doc, by=login)
e = DocEvent(doc=charter, by=login)
e.type = "iesg_approved"
e.desc = "IESG has approved the charter"
@ -400,36 +401,36 @@ def approve_ballot(request, name):
change_description = e.desc + " and WG state has been changed to %s" % new_state.name
e = log_state_changed(request, doc, login, prev_state)
e = log_state_changed(request, charter, login, prev_state)
wg.time = e.time
wg.save()
filename = os.path.join(doc.get_file_path(), doc.name+"-"+doc.rev+".txt")
try:
source = open(filename, 'rb')
raw_content = source.read()
filename = os.path.join(charter.get_file_path(), charter.name+"-"+charter.rev+".txt")
if not settings.DONT_COPY_CHARTER_ON_APPROVE:
try:
source = open(filename, 'rb')
raw_content = source.read()
doc.rev = next_approved_revision(doc.rev)
new_filename = os.path.join(doc.get_file_path(), doc.name+"-"+doc.rev+".txt")
destination = open(new_filename, 'wb+')
destination.write(raw_content)
destination.close()
except IOError:
raise Http404
new_filename = os.path.join(charter.get_file_path(), charter.name+"-"+charter.rev+".txt")
destination = open(new_filename, 'wb+')
destination.write(raw_content)
destination.close()
except IOError:
raise Http404
doc.save()
charter.rev = next_approved_revision(charter.rev)
charter.save()
email_secretariat(request, wg, "state-%s" % doc.charter_state_id, change_description)
email_secretariat(request, wg, "state-%s" % charter.charter_state_id, change_description)
# send announcement
send_mail_preformatted(request, announcement)
return HttpResponseRedirect(doc.get_absolute_url())
return HttpResponseRedirect(charter.get_absolute_url())
return render_to_response('wgrecord/approve_ballot.html',
dict(doc=doc,
dict(charter=charter,
announcement=announcement,
wg=wg),
context_instance=RequestContext(request))

View file

@ -108,7 +108,7 @@ def change_state(request, name):
if charter.charter_state_id == "extrev":
email_secretariat(request, wg, "state-%s" % charter.charter_state_id, messages['extrev'])
if form.cleaned_data["charter_state"] == "infrev":
if form.cleaned_data["charter_state"].slug == "infrev":
e = DocEvent()
e.type = "started_iesg_process"
e.by = login

View file

@ -100,7 +100,7 @@ def wg_main(request, name, rev, tab):
info['pos_no'] = filter(lambda x: x.pos_id == "no", latest_positions)
info['pos_block'] = filter(lambda x: x.pos_id == "block", latest_positions)
info['pos_abstain'] = filter(lambda x: x.pos_id == "abstain", latest_positions)
info['pos_no_record'] = no_record
info['pos_no_record'] = no_record + [x.ad for x in latest_positions if x.pos_id == "norecord"]
# Get annoucement texts
review_ann = wg.charter.latest_event(WriteupDocEvent, type="changed_review_announcement")

View file

@ -77,6 +77,13 @@ secretariat_group.state = state_names["active"]
secretariat_group.type = type_names["ietf"]
secretariat_group.save()
# create RSOC for use with roles
rsoc_group, _ = Group.objects.get_or_create(acronym="rsoc")
rsoc_group.name = "RFC Series Oversight Committee"
rsoc_group.state = state_names["active"]
rsoc_group.type = type_names["ietf"]
rsoc_group.save()
system = Person.objects.get(name="(System)")

View file

@ -254,14 +254,12 @@ for o in IESGHistory.objects.all().order_by('meeting__start_date', 'pk'):
existing = history if history else area
h = GroupHistory(group=area,
charter=existing.charter,
time=meeting_time,
name=existing.name,
acronym=existing.acronym,
state=existing.state,
type=existing.type,
parent=existing.parent,
iesg_state=existing.iesg_state,
ad=existing.ad,
list_email=existing.list_email,
list_subscribe=existing.list_subscribe,

View file

@ -5,8 +5,11 @@ jQuery(document).ready(function () {
}
function setMessageDraft(state) {
if (jQuery("#id_state").val() != "conclude") {
if (message[state]) {
if (jQuery("#id_state").val() == "conclude") {
jQuery("#id_message").val("");
initial_time.hide();
} else {
if (message[state]) {
if (state == "infrev") {
initial_time.show();
jQuery("#id_initial_time").val(1);
@ -15,11 +18,10 @@ jQuery(document).ready(function () {
jQuery("#id_initial_time").val(0);
}
jQuery("#id_message").val(message[state]);
} else {
jQuery("#id_message").val("");
}
} else {
} else {
jQuery("#id_message").val("");
initial_time.hide();
}
}
}
@ -27,6 +29,10 @@ jQuery(document).ready(function () {
setMessageDraft(jQuery(this).val());
});
jQuery("#id_state").click(function (e) {
setMessageDraft(jQuery("#id_charter_state").val());
});
jQuery("#id_charter_state").click();
});