Skip to content

Commit 51ab812

Browse files
committed
merged in from 4.20-ise
- Legacy-Id: 4502
1 parent 5ebe0b1 commit 51ab812

67 files changed

Lines changed: 3914 additions & 830 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: 11 additions & 1 deletion
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,11 @@ class DocAliasAdmin(admin.ModelAdmin):
114119
raw_id_fields = ['document']
115120
admin.site.register(DocAlias, DocAliasAdmin)
116121

122+
class RelatedDocumentAdmin(admin.ModelAdmin):
123+
search_fields = ['source__name','target__name']
124+
raw_id_fields = ['source','target']
125+
admin.site.register(RelatedDocument,RelatedDocumentAdmin)
126+
117127
class BallotTypeAdmin(admin.ModelAdmin):
118128
list_display = ["slug", "doc_type", "name", "question"]
119129
admin.site.register(BallotType, BallotTypeAdmin)

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
@@ -200,6 +200,113 @@ def canonical_name(self):
200200

201201
return name
202202

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