From e14dcdac8f046bdfdf575e1fdbb23fa2afa9948a Mon Sep 17 00:00:00 2001
From: Lars Eggert <lars@eggert.org>
Date: Sat, 25 Mar 2017 18:52:46 +0000
Subject: [PATCH] Rename crawl_history to make_rev_history, which is more
 descriptive. Fix #2224 (thanks, Robert!) by generating graphs for the entire
 revision history of a doc, both forward and backward in time. Commit ready
 for merge.  - Legacy-Id: 13109

---
 ietf/doc/utils.py     | 29 ++++++++++++++++++++++-------
 ietf/doc/views_doc.py |  4 ++--
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/ietf/doc/utils.py b/ietf/doc/utils.py
index 81223da11..d3d069592 100644
--- a/ietf/doc/utils.py
+++ b/ietf/doc/utils.py
@@ -654,19 +654,34 @@ def extract_complete_replaces_ancestor_mapping_for_docs(names):
     return replaces
 
 
-def crawl_history(doc):
+def make_rev_history(doc):
     # return document history data for inclusion in doc.json (used by timeline)
+
+    def get_predecessors(doc):
+        predecessors = []
+        if hasattr(doc, 'relateddocument_set'):
+            for alias in doc.related_that_doc('replaces'):
+                if alias.document not in predecessors:
+                    predecessors.append(alias.document)
+                    predecessors.extend(get_predecessors(alias.document))
+        return predecessors
+
     def get_ancestors(doc):
         ancestors = []
         if hasattr(doc, 'relateddocument_set'):
-            for rel in doc.relateddocument_set.filter(relationship__slug='replaces'):
-                if rel.target.document not in ancestors:
-                    ancestors.append(rel.target.document)
-                    ancestors.extend(get_ancestors(rel.target.document))
-            return ancestors
+            for alias in doc.related_that('replaces'):
+                if alias.document not in ancestors:
+                    ancestors.append(alias.document)
+                    ancestors.extend(get_ancestors(alias.document))
+        return ancestors
+
+    def get_replaces_tree(doc):
+        tree = get_predecessors(doc)
+        tree.extend(get_ancestors(doc))
+        return tree
 
     history = {}
-    docs = get_ancestors(doc)
+    docs = get_replaces_tree(doc)
     if docs is not None:
         docs.append(doc)
         for d in docs:
diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py
index af6664222..3da42be0e 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, crawl_history, default_consensus,
+    get_initial_notify, make_notify_changed_event, make_rev_history, default_consensus,
     add_events_message_info, get_unicode_document_content, build_doc_meta_block)
 from ietf.community.utils import augment_docs_with_tracking_info
 from ietf.group.models import Role
@@ -996,7 +996,7 @@ def document_json(request, name, rev=None):
     data["ad"] = doc.ad.role_email("ad").formatted_email() if doc.ad else None
 
     latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision")
-    data["rev_history"] = crawl_history(latest_revision.doc if latest_revision else doc)
+    data["rev_history"] = make_rev_history(latest_revision.doc if latest_revision else doc)
 
     if doc.type_id == "draft":
         data["iesg_state"] = extract_name(doc.get_state("draft-iesg"))