Skip to content

Commit 798f769

Browse files
committed
Merged [4600] from rjsparks@nostrum.com:
* Adds a new document type for conflict reviews, with a ballot for the IESG 5742 response to a review request * Integrated the new document type into the iESG agenda views (including RSS feeds)* Removed the Edit and Add buttons from the document main view. * Replaced Add with actions appropriate for the document type, such as "Begin IESG Processing" or "Begin IETF Conflict Review", and made most data directly editable on the document's main page, depending on access permissions. * Removed a manual editing step that the secretariat had to perform when sending conflict review messages. The view now composes the message correctly given the stream. * Added a pencil icon motif to differentiate fields that are editable. * Generalized several views and helper functions to use Document instead of (e.g.) IdWrapper * Generalized reading documents from the repository * Added a way to get from IdWrapper to the underlying Document to facilitate migrating way from the Wrapper classes* Added many helpers to Document to assist with migrating off IdWrapper * Minor fixes and other changes * Fixes to document main view to avoid (silent) template failures. * Began removing some of the code that is no longer reachable post-migration * Corrected the behavior of the undefer code and added test cases for it * Improved initial population of notification lists and added the ability to regenerate the initial list * Made the test code that scans for template coverage more robust * Deployment notes: * new setting: CONFLICT_REVIEW_PATH. The associated directory will need to be created This branch fixes bugs ietf-tools#805, ietf-tools#744 and ietf-tools#812 - Legacy-Id: 4652 Note: SVN reference [4600] has been migrated to Git commit 798e7a5
2 parents 8bd83e8 + 798e7a5 commit 798f769

71 files changed

Lines changed: 3978 additions & 865 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ietf/doc/admin.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ class DocAuthorInline(admin.TabularInline):
2626
raw_id_fields = ['author', ]
2727
extra = 1
2828

29+
class RelatedDocumentInline(admin.TabularInline):
30+
model = RelatedDocument
31+
raw_id_fields = ['target']
32+
extra = 1
33+
2934
# document form for managing states in a less confusing way
3035

3136
class StatesWidget(forms.SelectMultiple):
@@ -89,7 +94,7 @@ class DocumentAdmin(admin.ModelAdmin):
8994
search_fields = ['name']
9095
list_filter = ['type']
9196
raw_id_fields = ['authors', 'related', 'group', 'shepherd', 'ad']
92-
inlines = [DocAliasInline, DocAuthorInline, ]
97+
inlines = [DocAliasInline, DocAuthorInline, RelatedDocumentInline, ]
9398
form = DocumentForm
9499

95100
def state(self, instance):
@@ -114,6 +119,13 @@ class DocAliasAdmin(admin.ModelAdmin):
114119
raw_id_fields = ['document']
115120
admin.site.register(DocAlias, DocAliasAdmin)
116121

122+
class RelatedDocumentAdmin(admin.ModelAdmin):
123+
list_display = ['source', 'target', 'relationship', ]
124+
list_filter = ['relationship', ]
125+
search_fields = ['source__name', 'target__name', 'target__document__name', ]
126+
raw_id_fields = ['source', 'target', ]
127+
admin.site.register(RelatedDocument, RelatedDocumentAdmin)
128+
117129
class BallotTypeAdmin(admin.ModelAdmin):
118130
list_display = ["slug", "doc_type", "name", "question"]
119131
admin.site.register(BallotType, BallotTypeAdmin)
@@ -140,9 +152,3 @@ class BallotPositionDocEventAdmin(DocEventAdmin):
140152

141153
admin.site.register(BallotPositionDocEvent, BallotPositionDocEventAdmin)
142154

143-
class RelatedDocumentAdmin(admin.ModelAdmin):
144-
list_display = ['source', 'target', 'relationship', ]
145-
list_filter = ['relationship', ]
146-
search_fields = ['source__name', 'target__name', 'target__document__name', ]
147-
raw_id_fields = ['source', 'target', ]
148-
admin.site.register(RelatedDocument, RelatedDocumentAdmin)

ietf/doc/migrations/0003_add_conflict.py

Lines changed: 436 additions & 0 deletions
Large diffs are not rendered by default.

ietf/doc/models.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,113 @@ def display_name(self):
205205
name = name.upper()
206206
return name
207207

208+
#TODO can/should this be a function instead of a property? Currently a view uses it as a property
209+
@property
210+
def telechat_date(self):
211+
e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
212+
return e.telechat_date if e else None
213+
214+
def area_acronym(self):
215+
g = self.group
216+
if g:
217+
if g.type_id == "area":
218+
return g.acronym
219+
elif g.type_id != "individ":
220+
return g.parent.acronym
221+
else:
222+
return None
223+
224+
def group_acronym(self):
225+
g = self.group
226+
if g and g.type_id != "area":
227+
return g.acronym
228+
else:
229+
return "none"
230+
231+
def on_upcoming_agenda(self):
232+
e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
233+
return bool(e and e.telechat_date and e.telechat_date >= datetime.date.today())
234+
235+
def returning_item(self):
236+
e = self.latest_event(TelechatDocEvent, type="scheduled_for_telechat")
237+
return e.returning_item if e else None
238+
239+
# This is brittle. Resist the temptation to make it more brittle by combining the search against those description
240+
# strings to one command. It is coincidence that those states have the same description - one might change.
241+
# Also, this needs further review - is it really the case that there would be no other changed_document events
242+
# between when the state was changed to defer and when some bit of code wants to know if we are deferred? Why
243+
# isn't this just returning whether the state is currently a defer state for that document type?
244+
def active_defer_event(self):
245+
if self.type_id == "draft" and self.get_state_slug("draft-iesg") == "defer":
246+
return self.latest_event(type="changed_document", desc__startswith="State changed to <b>IESG Evaluation - Defer</b>")
247+
elif self.type_id == "conflrev" and self.get_state_slug("conflrev") == "defer":
248+
return self.latest_event(type="changed_document", desc__startswith="State changed to <b>IESG Evaluation - Defer</b>")
249+
return None
250+
251+
def displayname_with_link(self):
252+
return '<a href="%s">%s-%s</a>' % (self.get_absolute_url(), self.name , self.rev)
253+
254+
def rfc_number(self):
255+
qs = self.docalias_set.filter(name__startswith='rfc')
256+
return qs[0].name[3:] if qs else None
257+
258+
def replaced_by(self):
259+
return [ rel.source for alias in self.docalias_set.all() for rel in alias.relateddocument_set.filter(relationship='replaces') ]
260+
261+
def friendly_state(self):
262+
""" Return a concise text description of the document's current state """
263+
if self.type_id=='draft':
264+
# started_iesg_process is is how the redesigned database schema (as of May2012) captured what
265+
# used to be "has an IDInternal", aka *Wrapper.in_ietf_process()=True
266+
in_iesg_process = self.latest_event(type='started_iesg_process')
267+
iesg_state_summary=None
268+
if in_iesg_process:
269+
iesg_state = self.states.get(type='draft-iesg')
270+
# This knowledge about which tags are reportable IESG substate tags is duplicated in idrfc
271+
IESG_SUBSTATE_TAGS = ('point', 'ad-f-up', 'need-rev', 'extpty')
272+
iesg_substate = self.tags.filter(slug__in=IESG_SUBSTATE_TAGS)
273+
# There really shouldn't be more than one tag in iesg_substate, but this will do something sort-of-sensible if there is
274+
iesg_state_summary = iesg_state.name
275+
if iesg_substate:
276+
iesg_state_summary = iesg_state_summary + "::"+"::".join(tag.name for tag in iesg_substate)
277+
278+
if self.get_state_slug() == "rfc":
279+
return "<a href=\"%s\">RFC %d</a>" % (urlreverse('doc_view', args=['rfc%d' % self.rfc_number]), self.rfc_number)
280+
elif self.get_state_slug() == "repl":
281+
rs = self.replaced_by()
282+
if rs:
283+
return "Replaced by "+", ".join("<a href=\"%s\">%s</a>" % (urlreverse('doc_view', args=[name]),name) for name in rs)
284+
else:
285+
return "Replaced"
286+
elif self.get_state_slug() == "active":
287+
if in_iesg_process:
288+
if iesg_state.slug == "dead":
289+
# Many drafts in the draft-iesg "Dead" state are not dead
290+
# in other state machines; they're just not currently under
291+
# IESG processing. Show them as "I-D Exists (IESG: Dead)" instead...
292+
return "I-D Exists (IESG: "+iesg_state_summary+")"
293+
elif iesg_state.slug == "lc":
294+
expiration_date = str(self.latest_event(LastCallDocEvent,type="sent_last_call").expires.date())
295+
return iesg_state_summary + " (ends "+expiration_date+")"
296+
else:
297+
return iesg_state_summary
298+
else:
299+
return "I-D Exists"
300+
else:
301+
if in_iesg_process and iesg_state.slug == "dead":
302+
return self.get_state().name +" (IESG: "+iesg_state_summary+")"
303+
# Expired/Withdrawn by Submitter/IETF
304+
return self.get_state().name
305+
else:
306+
return self.get_state().name
307+
308+
def ipr(self):
309+
"""Returns the IPR disclosures against this document (as a queryset over IprDocAlias)."""
310+
from ietf.ipr.models import IprDocAlias
311+
return IprDocAlias.objects.filter(doc_alias__document=self)
312+
313+
314+
208315
class RelatedDocHistory(models.Model):
209316
source = models.ForeignKey('DocHistory')
210317
target = models.ForeignKey('DocAlias', related_name="reversely_related_document_history_set")

ietf/doc/templatetags/__init__.py

Whitespace-only changes.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from django import template
2+
3+
register = template.Library()
4+
5+
@register.filter
6+
def rfc_editor_state(doc):
7+
state = doc.states.filter(type='draft-stream-ise')
8+
return state[0] if state else None

ietf/doc/tests.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
3+
from ietf.doc.tests_conflict_review import *

0 commit comments

Comments
 (0)