Skip to content

Commit f3fd4db

Browse files
committed
Merge forward complete - checkpointing before fixing popup position dialogs
- Legacy-Id: 4595
2 parents f861882 + 1a5a7b9 commit f3fd4db

68 files changed

Lines changed: 3943 additions & 832 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
@@ -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)