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