Skip to content

Commit 3336f4a

Browse files
committed
Merged in [16656] from rjsparks@nostrum.com:
Add IANA expert review tracking. - Legacy-Id: 16716 Note: SVN reference [16656] has been migrated to Git commit e45a32e
2 parents 1d74b14 + e45a32e commit 3336f4a

11 files changed

Lines changed: 239 additions & 34 deletions

File tree

ietf/doc/admin.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
StateDocEvent, ConsensusDocEvent, BallotType, BallotDocEvent, WriteupDocEvent, LastCallDocEvent,
1313
TelechatDocEvent, BallotPositionDocEvent, ReviewRequestDocEvent, InitialReviewDocEvent,
1414
AddedMessageEvent, SubmissionDocEvent, DeletedEvent, EditedAuthorsDocEvent, DocumentURL,
15-
ReviewAssignmentDocEvent )
15+
ReviewAssignmentDocEvent, IanaExpertDocEvent )
1616

1717

1818
class StateTypeAdmin(admin.ModelAdmin):
@@ -155,7 +155,7 @@ def short_desc(self, obj):
155155
admin.site.register(AddedMessageEvent, DocEventAdmin)
156156
admin.site.register(SubmissionDocEvent, DocEventAdmin)
157157
admin.site.register(EditedAuthorsDocEvent, DocEventAdmin)
158-
158+
admin.site.register(IanaExpertDocEvent, DocEventAdmin)
159159

160160
class DeletedEventAdmin(admin.ModelAdmin):
161161
list_display = ['id', 'content_type', 'json', 'by', 'time']
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Copyright The IETF Trust 2019, All Rights Reserved
2+
# -*- coding: utf-8 -*-
3+
# Generated by Django 1.11.23 on 2019-08-07 12:07
4+
from __future__ import unicode_literals
5+
6+
from django.db import migrations
7+
8+
def forward(apps, schema_editor):
9+
StateType = apps.get_model('doc','StateType')
10+
State = apps.get_model('doc','State')
11+
12+
StateType.objects.create(slug='draft-iana-experts',label='IANA Experts State')
13+
State.objects.create(type_id='draft-iana-experts',
14+
slug='need-experts',
15+
name='Need IANA Expert(s)',
16+
used=True,
17+
desc='One or more registries need experts assigned',
18+
order=0
19+
)
20+
State.objects.create(type_id='draft-iana-experts',
21+
slug='reviews-assigned',
22+
name='Reviews assigned',
23+
used=True,
24+
desc='One or more expert reviews have been assigned',
25+
order=1
26+
)
27+
State.objects.create(type_id='draft-iana-experts',
28+
slug='expert-issues',
29+
name='Issues identified',
30+
used=True,
31+
desc='Some expert reviewers have identified issues',
32+
order=2
33+
)
34+
State.objects.create(type_id='draft-iana-experts',
35+
slug='reviewers-ok',
36+
name='Expert Reviews OK',
37+
used=True,
38+
desc='All expert reviews have been completed with no blocking issues',
39+
order=2
40+
)
41+
42+
def reverse(apps, schema_editor):
43+
StateType = apps.get_model('doc','StateType')
44+
State = apps.get_model('doc','State')
45+
46+
State.objects.filter(type_id='draft-iana-experts', slug__in=('need-experts','reviews-assigned','reviews-complete')).delete()
47+
StateType.objects.filter(slug='draft-iana-experts').delete()
48+
49+
50+
51+
class Migration(migrations.Migration):
52+
53+
dependencies = [
54+
('doc', '0023_one_to_many_docalias'),
55+
]
56+
57+
operations = [
58+
migrations.RunPython(forward, reverse)
59+
]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright The IETF Trust 2019, All Rights Reserved
2+
# -*- coding: utf-8 -*-
3+
# Generated by Django 1.11.23 on 2019-08-07 12:27
4+
from __future__ import unicode_literals
5+
6+
from django.db import migrations, models
7+
import django.db.models.deletion
8+
9+
10+
class Migration(migrations.Migration):
11+
12+
dependencies = [
13+
('doc', '0024_iana_experts'),
14+
]
15+
16+
operations = [
17+
migrations.CreateModel(
18+
name='IanaExpertDocEvent',
19+
fields=[
20+
('docevent_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='doc.DocEvent')),
21+
],
22+
bases=('doc.docevent',),
23+
),
24+
]

ietf/doc/models.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,9 @@ class Meta:
10521052
class NewRevisionDocEvent(DocEvent):
10531053
pass
10541054

1055+
class IanaExpertDocEvent(DocEvent):
1056+
pass
1057+
10551058
class StateDocEvent(DocEvent):
10561059
state_type = ForeignKey(StateType)
10571060
state = ForeignKey(State, blank=True, null=True)

ietf/doc/resources.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
TelechatDocEvent, DocReminder, LastCallDocEvent, NewRevisionDocEvent, WriteupDocEvent,
1717
InitialReviewDocEvent, DocHistoryAuthor, BallotDocEvent, RelatedDocument,
1818
RelatedDocHistory, BallotPositionDocEvent, AddedMessageEvent, SubmissionDocEvent,
19-
ReviewRequestDocEvent, ReviewAssignmentDocEvent, EditedAuthorsDocEvent, DocumentURL)
19+
ReviewRequestDocEvent, ReviewAssignmentDocEvent, EditedAuthorsDocEvent, DocumentURL,
20+
IanaExpertDocEvent )
2021

2122
from ietf.name.resources import BallotPositionNameResource, DocTypeNameResource
2223
class BallotTypeResource(ModelResource):
@@ -713,3 +714,27 @@ class Meta:
713714
"state": ALL_WITH_RELATIONS,
714715
}
715716
api.doc.register(ReviewAssignmentDocEventResource())
717+
718+
719+
from ietf.person.resources import PersonResource
720+
class IanaExpertDocEventResource(ModelResource):
721+
by = ToOneField(PersonResource, 'by')
722+
doc = ToOneField(DocumentResource, 'doc')
723+
docevent_ptr = ToOneField(DocEventResource, 'docevent_ptr')
724+
class Meta:
725+
queryset = IanaExpertDocEvent.objects.all()
726+
serializer = api.Serializer()
727+
cache = SimpleCache()
728+
#resource_name = 'ianaexpertdocevent'
729+
ordering = ['docevent_ptr', ]
730+
filtering = {
731+
"id": ALL,
732+
"time": ALL,
733+
"type": ALL,
734+
"rev": ALL,
735+
"desc": ALL,
736+
"by": ALL_WITH_RELATIONS,
737+
"doc": ALL_WITH_RELATIONS,
738+
"docevent_ptr": ALL_WITH_RELATIONS,
739+
}
740+
api.doc.register(IanaExpertDocEventResource())

ietf/doc/tests_draft.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from ietf.doc.factories import IndividualDraftFactory, WgDraftFactory, RgDraftFactory, DocEventFactory
2020
from ietf.doc.models import ( Document, DocReminder, DocEvent,
2121
ConsensusDocEvent, LastCallDocEvent, RelatedDocument, State, TelechatDocEvent,
22-
WriteupDocEvent, DocRelationshipName)
22+
WriteupDocEvent, DocRelationshipName, IanaExpertDocEvent )
2323
from ietf.doc.utils import get_tags_for_stream_id, create_ballot_if_not_open
2424
from ietf.name.models import StreamName, DocTagName
2525
from ietf.group.factories import GroupFactory, RoleFactory
@@ -200,6 +200,17 @@ def test_change_iana_state(self):
200200
draft = Document.objects.get(name=draft.name)
201201
self.assertEqual(draft.get_state("draft-iana-review"), next_state)
202202

203+
def test_add_expert_review_comment(self):
204+
draft = WgDraftFactory()
205+
url = urlreverse('ietf.doc.views_draft.add_iana_experts_comment',kwargs=dict(name=draft.name))
206+
login_testing_unauthorized(self, 'iana', url)
207+
r = self.client.get(url)
208+
self.assertEqual(r.status_code, 200)
209+
r = self.client.post(url,dict(comment='!2ab3x#1'))
210+
self.assertEqual(r.status_code, 302)
211+
self.assertEqual(draft.latest_event(IanaExpertDocEvent,type='comment').desc,'!2ab3x#1')
212+
213+
203214
def test_request_last_call(self):
204215
ad = Person.objects.get(user__username="ad")
205216
draft = WgDraftFactory(ad=ad,states=[('draft-iesg','ad-eval')])

ietf/doc/urls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@
9191
url(r'^%(name)s/email-aliases/$' % settings.URL_REGEXPS, RedirectView.as_view(pattern_name='ietf.doc.views_doc.document_email', permanent=False),name='ietf.doc.urls.redirect.document_email'),
9292

9393
url(r'^%(name)s/edit/state/$' % settings.URL_REGEXPS, views_draft.change_state), # IESG state
94-
url(r'^%(name)s/edit/state/(?P<state_type>iana-action|iana-review)/$' % settings.URL_REGEXPS, views_draft.change_iana_state),
94+
url(r'^%(name)s/edit/state/(?P<state_type>iana-action|iana-review|iana-experts)/$' % settings.URL_REGEXPS, views_draft.change_iana_state),
95+
url(r'^%(name)s/edit/ianaexpertcomment/$' % settings.URL_REGEXPS, views_draft.add_iana_experts_comment),
9596
url(r'^%(name)s/edit/info/$' % settings.URL_REGEXPS, views_draft.edit_info),
9697
url(r'^%(name)s/edit/requestresurrect/$' % settings.URL_REGEXPS, views_draft.request_resurrect),
9798
url(r'^%(name)s/edit/submit-to-iesg/$' % settings.URL_REGEXPS, views_draft.to_iesg),

ietf/doc/views_doc.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
import debug # pyflakes:ignore
5757

5858
from ietf.doc.models import ( Document, DocAlias, DocHistory, DocEvent, BallotDocEvent,
59-
ConsensusDocEvent, NewRevisionDocEvent, TelechatDocEvent, WriteupDocEvent,
59+
ConsensusDocEvent, NewRevisionDocEvent, TelechatDocEvent, WriteupDocEvent, IanaExpertDocEvent,
6060
IESG_BALLOT_ACTIVE_STATES, STATUSCHANGE_RELATIONS )
6161
from ietf.doc.utils import ( add_links_in_new_revision_events, augment_events_with_revision,
6262
can_adopt_draft, can_unadopt_draft, get_chartering_type, get_tags_for_stream_id,
@@ -396,6 +396,9 @@ def document_main(request, name, rev=None):
396396
review_assignments = review_assignments_to_list_for_docs([doc]).get(doc.name, [])
397397
no_review_from_teams = no_review_from_teams_on_doc(doc, rev or doc.rev)
398398

399+
exp_comment = doc.latest_event(IanaExpertDocEvent,type="comment")
400+
iana_experts_comment = exp_comment and exp_comment.desc
401+
399402
return render(request, "doc/document_draft.html",
400403
dict(doc=doc,
401404
group=group,
@@ -452,6 +455,8 @@ def document_main(request, name, rev=None):
452455
rfc_editor_state=doc.get_state("draft-rfceditor"),
453456
iana_review_state=doc.get_state("draft-iana-review"),
454457
iana_action_state=doc.get_state("draft-iana-action"),
458+
iana_experts_state=doc.get_state("draft-iana-experts"),
459+
iana_experts_comment=iana_experts_comment,
455460
started_iesg_process=started_iesg_process,
456461
shepherd_writeup=shepherd_writeup,
457462
search_archive=search_archive,

ietf/doc/views_draft.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from ietf.doc.models import ( Document, DocAlias, RelatedDocument, State,
2727
StateType, DocEvent, ConsensusDocEvent, TelechatDocEvent, WriteupDocEvent, StateDocEvent,
28-
IESG_SUBSTATE_TAGS)
28+
IanaExpertDocEvent, IESG_SUBSTATE_TAGS)
2929
from ietf.doc.mails import ( email_pulled_from_rfc_queue, email_resurrect_requested,
3030
email_resurrection_completed, email_state_changed, email_stream_changed,
3131
email_stream_state_changed, email_stream_tags_changed, extra_automation_headers,
@@ -188,6 +188,23 @@ def change_state(request, name):
188188
next_states=next_states,
189189
to_iesg_eval=to_iesg_eval))
190190

191+
class AddIanaExpertsCommentForm(forms.Form):
192+
comment = forms.CharField(required=True, widget=forms.Textarea, strip=False)
193+
194+
@role_required('Secretariat', 'IANA')
195+
def add_iana_experts_comment(request, name):
196+
doc = get_object_or_404(Document, docalias__name = name)
197+
if request.method == 'POST':
198+
form = AddIanaExpertsCommentForm(request.POST)
199+
if form.is_valid():
200+
IanaExpertDocEvent.objects.create(doc=doc, rev=doc.rev, by=request.user.person, type="comment", desc=form.cleaned_data['comment'])
201+
return HttpResponseRedirect(doc.get_absolute_url())
202+
else:
203+
form = AddIanaExpertsCommentForm()
204+
205+
return render(request, 'doc/draft/add_iana_experts_comment.html', dict(form=form, doc=doc))
206+
207+
191208
class ChangeIanaStateForm(forms.Form):
192209
state = forms.ModelChoiceField(State.objects.all(), required=False)
193210

@@ -197,6 +214,7 @@ def __init__(self, state_type, *args, **kwargs):
197214
choices = State.objects.filter(used=True, type=state_type).order_by("order").values_list("pk", "name")
198215
self.fields['state'].choices = [("", "-------")] + list(choices)
199216

217+
200218
@role_required('Secretariat', 'IANA')
201219
def change_iana_state(request, name, state_type):
202220
"""Change IANA review state of Internet Draft. Normally, this is done via

ietf/templates/doc/document_draft.html

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -514,34 +514,69 @@
514514
</tbody>
515515
{% endif %}
516516

517-
{% if iana_review_state %}
518-
<tbody class="meta">
519-
<tr>
520-
<th>IANA</th>
521-
<th><a href="{% url "ietf.help.views.state" doc=doc.type.slug type="iana-review" %}">IANA review state</a></th>
522-
<td class="edit">
523-
{% if can_edit_iana_state and not snapshot %}
524-
<a class="btn btn-default btn-xs" href="{% url 'ietf.doc.views_draft.change_iana_state' name=doc.name state_type="iana-review" %}">Edit</a>
525-
{% endif %}
526-
</td>
527-
<td>
528-
{{ iana_review_state }}
529-
</td>
530-
</tr>
517+
{% if can_edit_iana_state or iana_review_state or iana_experts_state or iana_experts_comment %}
518+
<tbody class="meta">
519+
{% if iana_review_state or can_edit_iana_state %}
520+
<tr>
521+
<th>IANA</th>
522+
<th><a href="{% url "ietf.help.views.state" doc=doc.type.slug type="iana-review" %}">IANA review state</a></th>
523+
<td class="edit">
524+
{% if can_edit_iana_state and not snapshot %}
525+
<a class="btn btn-default btn-xs" href="{% url 'ietf.doc.views_draft.change_iana_state' name=doc.name state_type="iana-review" %}">Edit</a>
526+
{% endif %}
527+
</td>
528+
<td>
529+
{{ iana_review_state }}
530+
</td>
531+
</tr>
532+
{% endif %}
531533

532-
<tr>
533-
<th></th>
534-
<th>IANA action state</th>
535-
<td class="edit">
536-
{% if can_edit_iana_state and not snapshot %}
537-
<a class="btn btn-default btn-xs" href="{% url 'ietf.doc.views_draft.change_iana_state' name=doc.name state_type="iana-action" %}">Edit</a>
538-
{% endif %}
539-
</td>
540-
<td>
541-
{{ iana_action_state }}
542-
</td>
543-
</tr>
544-
</tbody>
534+
{% if iana_action_state or can_edit_iana_state %}
535+
<tr>
536+
<th>{% if not can_edit_iana_state and not iana_review_state %}IANA{% endif %}</th>
537+
<th><a href="{% url "ietf.help.views.state" doc=doc.type.slug type="iana-action" %}">IANA action state</a></th>
538+
<td class="edit">
539+
{% if can_edit_iana_state and not snapshot %}
540+
<a class="btn btn-default btn-xs" href="{% url 'ietf.doc.views_draft.change_iana_state' name=doc.name state_type="iana-action" %}">Edit</a>
541+
{% endif %}
542+
</td>
543+
<td>
544+
{{ iana_action_state }}
545+
</td>
546+
</tr>
547+
{% endif %}
548+
549+
{% if iana_experts_state or can_edit_iana_state %}
550+
<tr>
551+
<th>{% if not can_edit_iana_state and not iana_review_state and not iana_action_state %}IANA{% endif %}</th>
552+
<th><a href="{% url "ietf.help.views.state" doc=doc.type.slug type="iana-experts" %}">IANA expert review state</a></th>
553+
<td class="edit">
554+
{% if can_edit_iana_state and not snapshot %}
555+
<a class="btn btn-default btn-xs" href="{% url 'ietf.doc.views_draft.change_iana_state' name=doc.name state_type="iana-experts" %}">Edit</a>
556+
{% endif %}
557+
</td>
558+
<td>
559+
{{ iana_experts_state }}
560+
</td>
561+
</tr>
562+
{% endif %}
563+
564+
{% if iana_experts_comment or can_edit_iana_state %}
565+
<tr>
566+
<th>{% if not can_edit_iana_state and not iana_review_state and not iana_action_state and not iana_experts_state %}IANA{% endif %}</th>
567+
<th>IANA expert review comments</th>
568+
<td class="edit">
569+
{% if can_edit_iana_state and not snapshot %}
570+
<a class="btn btn-default btn-xs" href="{% url 'ietf.doc.views_draft.add_iana_experts_comment' name=doc.name %}">Edit</a>
571+
{% endif %}
572+
</td>
573+
<td>
574+
{{ iana_experts_comment }}
575+
</td>
576+
</tr>
577+
{% endif %}
578+
579+
</tbody>
545580
{% endif %}
546581

547582
<tbody class="meta">

0 commit comments

Comments
 (0)