From 9728186ec4c27d4c04df486c528df073522977a6 Mon Sep 17 00:00:00 2001 From: Lars Eggert Date: Thu, 3 Dec 2015 13:25:51 +0000 Subject: [PATCH] Make revision history (via crawl_history) available in document templates. This lays the foundation for graphical timelines. - Legacy-Id: 10542 --- ietf/doc/utils.py | 51 +++++++++++++++++++++++++++++++++---------- ietf/doc/views_doc.py | 12 +++++++++- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py index 575fa2c44..5f38fd90a 100644 --- a/ietf/doc/utils.py +++ b/ietf/doc/utils.py @@ -3,6 +3,7 @@ import re import urllib import math import datetime +import operator from django.conf import settings from django.db.models.query import EmptyQuerySet @@ -27,7 +28,7 @@ def email_update_telechat(request, doc, text): if not to: return - + text = strip_tags(text) send_mail(request, to, None, "Telechat update notice: %s" % doc.file_tag(), @@ -41,7 +42,7 @@ def get_state_types(doc): if not doc: return res - + res.append(doc.type_id) if doc.type_id == "draft": @@ -52,7 +53,7 @@ def get_state_types(doc): res.append("draft-iana-review") res.append("draft-iana-action") res.append("draft-rfceditor") - + return res def get_tags_for_stream_id(stream_id): @@ -144,7 +145,7 @@ def needed_ballot_positions(doc, active_positions): answer.append("Has enough positions to pass.") return " ".join(answer) - + def create_ballot_if_not_open(doc, by, ballot_slug, time=None): if not doc.ballot_open(ballot_slug): if time: @@ -359,7 +360,7 @@ def make_notify_changed_event(request, doc, by, new_notify, time=None): def update_telechat(request, doc, by, new_telechat_date, new_returning_item=None): from ietf.doc.models import TelechatDocEvent - + on_agenda = bool(new_telechat_date) prev = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat") @@ -378,7 +379,7 @@ def update_telechat(request, doc, by, new_telechat_date, new_returning_item=None # auto-set returning item _ONLY_ if the caller did not provide a value if ( new_returning_item != None - and on_agenda + and on_agenda and prev_agenda and new_telechat_date != prev_telechat and prev_telechat < datetime.date.today() @@ -392,7 +393,7 @@ def update_telechat(request, doc, by, new_telechat_date, new_returning_item=None e.doc = doc e.returning_item = returning e.telechat_date = new_telechat_date - + if on_agenda != prev_agenda: if on_agenda: e.desc = "Placed on agenda for telechat - %s" % (new_telechat_date) @@ -426,7 +427,7 @@ def rebuild_reference_relations(doc,filename=None): refs = draft.Draft(draft._gettext(filename), filename).get_refs() except IOError as e: return { 'errors': ["%s :%s" % (e.strerror, filename)] } - + doc.relateddocument_set.filter(relationship__slug__in=['refnorm','refinfo','refold','refunk']).delete() warnings = [] @@ -449,11 +450,11 @@ def rebuild_reference_relations(doc,filename=None): ret = {} if errors: - ret['errors']=errors + ret['errors']=errors if warnings: - ret['warnings']=warnings + ret['warnings']=warnings if unfound: - ret['unfound']=list(unfound) + ret['unfound']=list(unfound) return ret @@ -539,3 +540,31 @@ def uppercase_std_abbreviated_name(name): return name.upper() else: return name + +def crawl_history(doc): + # return document history data for use in ietf/templates/doc/timeline.html + def ancestors(doc): + retval = [] + if hasattr(doc, 'relateddocument_set'): + for rel in doc.relateddocument_set.filter(relationship__slug='replaces'): + if rel.target.document not in retval: + retval.append(rel.target.document) + retval.extend(ancestors(rel.target.document)) + return retval + + retval = [] + history = ancestors(doc) + if history is not None: + history.append(doc) + for d in history: + for e in d.docevent_set.filter(type='new_revision'): + if hasattr(e, 'newrevisiondocevent'): + retval.append((d.name, e.newrevisiondocevent.rev, e.time.isoformat())) + + if doc.type_id == "draft": + e = doc.latest_event(type='published_rfc') + else: + e = doc.latest_event(type='iesg_approved') + if e: + retval.append((doc.name, e.doc.canonical_name, e.time.isoformat())) + return sorted(retval, key=operator.itemgetter(2)) diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py index 0ee022e8b..cbe1ebd7a 100644 --- a/ietf/doc/views_doc.py +++ b/ietf/doc/views_doc.py @@ -49,7 +49,7 @@ from ietf.doc.models import ( Document, DocAlias, DocHistory, DocEvent, BallotDo from ietf.doc.utils import ( add_links_in_new_revision_events, augment_events_with_revision, can_adopt_draft, get_chartering_type, get_document_content, get_tags_for_stream_id, needed_ballot_positions, nice_consensus, prettify_std_name, update_telechat, has_same_ballot, - get_initial_notify, make_notify_changed_event ) + get_initial_notify, make_notify_changed_event, crawl_history) from ietf.community.models import CommunityList from ietf.group.models import Role from ietf.group.utils import can_manage_group_type, can_manage_materials @@ -417,6 +417,7 @@ def document_main(request, name, rev=None): search_archive=search_archive, actions=actions, tracking_document=tracking_document, + rev_history=crawl_history(latest_revision.doc if latest_revision else doc), ), context_instance=RequestContext(request)) @@ -442,6 +443,8 @@ def document_main(request, name, rev=None): can_manage = can_manage_group_type(request.user, doc.group.type_id) + latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision") + return render_to_response("doc/document_charter.html", dict(doc=doc, top=top, @@ -456,6 +459,7 @@ def document_main(request, name, rev=None): group=group, milestones=milestones, can_manage=can_manage, + rev_history=crawl_history(latest_revision.doc if latest_revision else doc), ), context_instance=RequestContext(request)) @@ -473,6 +477,8 @@ def document_main(request, name, rev=None): if doc.get_state_slug() in ("iesgeval") and doc.active_ballot(): ballot_summary = needed_ballot_positions(doc, doc.active_ballot().active_ad_positions().values()) + latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision") + return render_to_response("doc/document_conflict_review.html", dict(doc=doc, top=top, @@ -484,6 +490,7 @@ def document_main(request, name, rev=None): conflictdoc=conflictdoc, ballot_summary=ballot_summary, approved_states=('appr-reqnopub-pend','appr-reqnopub-sent','appr-noprob-pend','appr-noprob-sent'), + rev_history=crawl_history(latest_revision.doc if latest_revision else doc), ), context_instance=RequestContext(request)) @@ -508,6 +515,8 @@ def document_main(request, name, rev=None): else: sorted_relations=None + latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision") + return render_to_response("doc/document_status_change.html", dict(doc=doc, top=top, @@ -519,6 +528,7 @@ def document_main(request, name, rev=None): ballot_summary=ballot_summary, approved_states=('appr-pend','appr-sent'), sorted_relations=sorted_relations, + rev_history=crawl_history(latest_revision.doc if latest_revision else doc), ), context_instance=RequestContext(request))