@@ -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+
203310class RelatedDocHistory (models .Model ):
204311 source = models .ForeignKey ('DocHistory' )
205312 target = models .ForeignKey ('DocAlias' , related_name = "reversely_related_document_history_set" )
0 commit comments