Skip to content

Commit 5bbea70

Browse files
committed
fix: repair many revision related issues with the main and htmlized views
1 parent be77cc9 commit 5bbea70

12 files changed

Lines changed: 149 additions & 90 deletions

File tree

ietf/api/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ def rfcdiff_latest_json(request, name, rev=None):
328328
response = dict()
329329
condition, document, history, found_rev = find_doc_for_rfcdiff(name, rev)
330330
if document.type_id == "rfc":
331-
draft = next(iter(document.related_that('became_rfc')), None)
331+
draft = document.came_from_draft()
332332
if condition == 'no such document':
333333
raise Http404
334334
elif condition in ('historic version', 'current version'):

ietf/doc/factories.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,11 @@ class Meta:
5151
def name(self, n):
5252
return draft_name_generator(self.type_id,self.group,n)
5353

54-
newrevisiondocevent = factory.RelatedFactory('ietf.doc.factories.NewRevisionDocEventFactory','doc')
54+
@factory.post_generation
55+
def newrevisiondocevent(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
56+
if create:
57+
if obj.type_id != "rfc":
58+
NewRevisionDocEventFactory(doc=obj)
5559

5660
@factory.post_generation
5761
def states(obj, create, extracted, **kwargs): # pylint: disable=no-self-argument
@@ -106,6 +110,7 @@ class DocumentFactory(BaseDocumentFactory):
106110

107111
class RfcFactory(BaseDocumentFactory):
108112
type_id = "rfc"
113+
rev = ""
109114
rfc_number = factory.Sequence(lambda n: n + 1000)
110115
name = factory.LazyAttribute(lambda o: f"rfc{o.rfc_number:d}")
111116
expires = None

ietf/doc/management/commands/generate_draft_aliases.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def handle(self, *args, **options):
130130
for draft in interesting_drafts.distinct().iterator():
131131
# Omit drafts that became RFCs, unless they were published in the last DEFAULT_YEARS
132132
if draft.get_state_slug()=="rfc":
133-
rfc = next(iter(draft.related_that_doc("became_rfc")), None)
133+
rfc = draft.became_rfc()
134134
log.assertion("rfc is not None")
135135
if rfc.latest_event(type='published_rfc').time < show_since:
136136
continue

ietf/doc/models.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,28 @@ def get_file_name(self):
198198
self._cached_file_name = os.path.join(self.get_file_path(), self.get_base_name())
199199
return self._cached_file_name
200200

201-
def revisions(self):
201+
202+
def revisions_by_dochistory(self):
202203
revisions = []
203-
doc = self.doc if isinstance(self, DocHistory) else self
204-
for e in doc.docevent_set.filter(type='new_revision').distinct():
205-
if e.rev and not e.rev in revisions:
206-
revisions.append(e.rev)
207-
if not doc.rev in revisions:
208-
revisions.append(doc.rev)
209-
revisions.sort()
204+
if self.type_id != "rfc":
205+
for h in self.history_set.order_by("time", "id"):
206+
if h.rev and not h.rev in revisions:
207+
revisions.append(h.rev)
208+
if not self.rev in revisions:
209+
revisions.append(self.rev)
210210
return revisions
211211

212+
def revisions_by_newrevisionevent(self):
213+
revisions = []
214+
if self.type_id != "rfc":
215+
doc = self.doc if isinstance(self, DocHistory) else self
216+
for e in doc.docevent_set.filter(type='new_revision').distinct():
217+
if e.rev and not e.rev in revisions:
218+
revisions.append(e.rev)
219+
if not doc.rev in revisions:
220+
revisions.append(doc.rev)
221+
revisions.sort()
222+
return revisions
212223

213224
def get_href(self, meeting=None):
214225
return self._get_ref(meeting=meeting,meeting_doc_refs=settings.MEETING_DOC_HREFS)
@@ -654,6 +665,15 @@ def referenced_by_rfcs(self):
654665
source__type__slug="rfc"
655666
)
656667

668+
def became_rfc(self):
669+
doc = self if isinstance(self, Document) else self.doc
670+
return next(iter(doc.related_that_doc("became_rfc")), None)
671+
672+
def came_from_draft(self):
673+
doc = self if isinstance(self, Document) else self.doc
674+
return next(iter(doc.related_that("became_rfc")), None)
675+
676+
657677
class Meta:
658678
abstract = True
659679

ietf/doc/tests.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2883,3 +2883,30 @@ def test_gets_request_conflict_review_action_button(self):
28832883
r = self.client.get(url)
28842884
self.assertContains(r, target_string)
28852885

2886+
class DocInfoMethodsTests(TestCase):
2887+
2888+
def test_became_rfc(self):
2889+
draft = WgDraftFactory()
2890+
rfc = WgRfcFactory()
2891+
draft.relateddocument_set.create(relationship_id="became_rfc",target=rfc)
2892+
self.assertEqual(draft.became_rfc(), rfc)
2893+
self.assertEqual(rfc.came_from_draft(), draft)
2894+
2895+
charter = CharterFactory()
2896+
self.assertIsNone(charter.became_rfc())
2897+
self.assertIsNone(charter.came_from_draft())
2898+
2899+
def test_revisions(self):
2900+
draft = WgDraftFactory(rev="09",create_revisions=range(0,10))
2901+
self.assertEqual(draft.revisions_by_dochistory(),[f"{i:02d}" for i in range(0,10)])
2902+
self.assertEqual(draft.revisions_by_newrevisionevent(),[f"{i:02d}" for i in range(0,10)])
2903+
rfc = WgRfcFactory()
2904+
self.assertEqual(rfc.revisions_by_newrevisionevent(),[])
2905+
self.assertEqual(rfc.revisions_by_dochistory(),[])
2906+
2907+
draft.history_set.filter(rev__lt="08").delete()
2908+
draft.docevent_set.filter(newrevisiondocevent__rev="05").delete()
2909+
self.assertEqual(draft.revisions_by_dochistory(),[f"{i:02d}" for i in range(8,10)])
2910+
self.assertEqual(draft.revisions_by_newrevisionevent(),[f"{i:02d}" for i in [*range(0,5), *range(6,10)]])
2911+
2912+

ietf/doc/views_doc.py

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -197,29 +197,28 @@ def document_main(request, name, rev=None, document_html=False):
197197

198198
# take care of possible redirections
199199
if document_html is False and rev is None:
200-
became_rfc = next(iter(doc.related_that_doc("became_rfc")), None)
200+
became_rfc = doc.became_rfc()
201201
if became_rfc:
202202
return redirect("ietf.doc.views_doc.document_main", name=became_rfc.name)
203-
204-
revisions = []
205-
for h in doc.history_set.order_by("time", "id"):
206-
if h.rev and not h.rev in revisions:
207-
revisions.append(h.rev)
208-
if not doc.rev in revisions:
209-
revisions.append(doc.rev)
203+
204+
revisions = doc.revisions_by_dochistory()
210205
latest_rev = doc.rev
211206

212207
snapshot = False
213208

214209
gh = None
215210
if rev:
216211
# find the entry in the history
212+
debug.show('doc.name')
217213
for h in doc.history_set.order_by("-time"):
218214
if rev == h.rev:
219215
snapshot = True
220216
doc = h
221217
break
222218

219+
debug.show('doc.name')
220+
221+
223222
if not snapshot and document_html is False:
224223
return redirect('ietf.doc.views_doc.document_main', name=name)
225224

@@ -239,7 +238,6 @@ def document_main(request, name, rev=None, document_html=False):
239238
if telechat and (not telechat.telechat_date or telechat.telechat_date < date_today(settings.TIME_ZONE)):
240239
telechat = None
241240

242-
243241
# specific document types
244242
if doc.type_id == "rfc":
245243
split_content = request.COOKIES.get("full_draft", settings.USER_PREFERENCE_DEFAULTS["full_draft"]) == "off"
@@ -302,7 +300,7 @@ def document_main(request, name, rev=None, document_html=False):
302300
diff_revisions = None
303301
simple_diff_revisions = None
304302
if document_html:
305-
diff_revisions=get_diff_revisions(request, name, doc if isinstance(doc,Document) else doc.doc)
303+
diff_revisions=get_diff_revisions(request, name, doc)
306304
simple_diff_revisions = [t[1] for t in diff_revisions if t[0] == doc.name]
307305
simple_diff_revisions.reverse()
308306
html = doc.html_body()
@@ -311,10 +309,8 @@ def document_main(request, name, rev=None, document_html=False):
311309
css = Path(finders.find("ietf/css/document_html_inline.css")).read_text()
312310
if html:
313311
css += Path(finders.find("ietf/css/document_html_txt.css")).read_text()
314-
draft_that_became_rfc = None
315-
became_rfc = next(iter(doc.related_that("became_rfc")), None)
316-
if became_rfc:
317-
draft_that_became_rfc = became_rfc
312+
draft_that_became_rfc = doc.came_from_draft()
313+
318314
# submission
319315
submission = ""
320316
if group is None:
@@ -651,6 +647,7 @@ def document_main(request, name, rev=None, document_html=False):
651647
css = Path(finders.find("ietf/css/document_html_inline.css")).read_text()
652648
if html:
653649
css += Path(finders.find("ietf/css/document_html_txt.css")).read_text()
650+
debug.show("doc.name")
654651

655652
return render(request, "doc/document_draft.html" if document_html is False else "doc/document_html.html",
656653
dict(doc=doc,
@@ -1134,6 +1131,9 @@ def document_email(request,name):
11341131

11351132

11361133
def get_diff_revisions(request, name, doc):
1134+
""" returns list of (name, rev, time, url, is_this_doc, is_previous_doc)
1135+
ordered by -time for use by forms used to get to the diff tools.
1136+
"""
11371137
diffable = any(
11381138
[
11391139
name.startswith(prefix)
@@ -1160,16 +1160,17 @@ def get_diff_revisions(request, name, doc):
11601160
relateddocument__relationship="replaces",
11611161
)
11621162
)
1163-
diff_documents.extend(
1164-
Document.objects.filter(
1165-
relateddocument__target=doc,
1166-
relateddocument__relationship="became_rfc"
1167-
)
1168-
)
1163+
if doc.came_from_draft():
1164+
diff_documents.append(doc.came_from_draft())
1165+
1166+
if doc.became_rfc():
1167+
rfc = doc.became_rfc()
1168+
e = rfc.latest_event(type="published_rfc")
1169+
diff_revisions.append((rfc.name, "", e.time if e else rfc.time, rfc.name, False, False))
11691170

11701171
if doc.type_id == "rfc":
11711172
e = doc.latest_event(type="published_rfc")
1172-
diff_revisions.append((name, "", e.time if e else doc.time, name))
1173+
diff_revisions.append((name, "", e.time if e else doc.time, name, True, False))
11731174

11741175
seen = set()
11751176
for e in (
@@ -1198,7 +1199,16 @@ def get_diff_revisions(request, name, doc):
11981199
# rfcdiff tool has special support for IDs
11991200
url = e.doc.name + "-" + e.rev
12001201

1201-
diff_revisions.append((e.doc.name, e.rev, e.time, url))
1202+
diff_revisions.append((e.doc.name, e.rev, e.time, url, e.doc == doc and e.rev == doc.rev, False))
1203+
1204+
diff_revisions.sort(key=lambda t: t[2], reverse=True)
1205+
for index, t in enumerate(diff_revisions):
1206+
if t[4]: # is_this_doc
1207+
n = index+1
1208+
if n < len(diff_revisions):
1209+
t_name, rev, time, url, _, _ = diff_revisions[n]
1210+
diff_revisions[n] = (t_name, rev, time, url, False, True)
1211+
break
12021212

12031213
return diff_revisions
12041214

@@ -1280,7 +1290,7 @@ def document_bibtex(request, name, rev=None):
12801290
if doc.type_id == "draft":
12811291
latest_revision = doc.latest_event(NewRevisionDocEvent, type="new_revision")
12821292
replaced_by = [d.name for d in doc.related_that("replaces")]
1283-
draft_became_rfc = next(iter(doc.related_that_doc("became_rfc")), None)
1293+
draft_became_rfc = doc.became_rfc()
12841294

12851295
if rev != None and rev != doc.rev:
12861296
# find the entry in the history
@@ -2170,7 +2180,7 @@ def idnits2_state(request, name, rev=None):
21702180
raise Http404
21712181
zero_revision = None
21722182
if doc.type_id == "rfc":
2173-
draft = next(iter(doc.related_that('became_rfc')), None)
2183+
draft = doc.came_from_draft()
21742184
if draft:
21752185
zero_revision = NewRevisionDocEvent.objects.filter(doc=draft,rev='00').first()
21762186
else:

ietf/idindex/index.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def formatted_rev_date(name):
3333

3434
rfcs = dict()
3535
for rfc in Document.objects.filter(type_id="rfc"):
36-
draft = next(iter(rfc.related_that("became_rfc")), None)
36+
draft = rfc.came_from_draft()
3737
if draft is not None:
3838
rfcs[draft.name] = rfc.name
3939

@@ -117,7 +117,7 @@ def all_id2_txt():
117117

118118
rfcs = dict()
119119
for rfc in Document.objects.filter(type_id="rfc"):
120-
draft = next(iter(rfc.related_that("became_rfc")), None)
120+
draft = rfc.came_from_draft()
121121
if draft is not None:
122122
rfcs[draft.name] = rfc.name
123123

ietf/meeting/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def _get_materials_doc(meeting, name):
235235
docname, rev = name.rsplit("-", 1)
236236
if len(rev) == 2 and rev.isdigit():
237237
doc = Document.objects.get(name=docname) # may raise Document.DoesNotExist
238-
if doc.get_related_meeting() == meeting and rev in doc.revisions():
238+
if doc.get_related_meeting() == meeting and rev in doc.revisions_by_newrevisionevent():
239239
return doc, rev
240240
# give up
241241
raise Document.DoesNotExist

ietf/templates/doc/document_history_form.html

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,34 +11,22 @@
1111
<label for="url1" class="col-form-label col-sm-2 fw-bold">From revision</label>
1212
<div class="col-sm-10">
1313
{% endif %}
14-
{% with prev_rev=doc.rev|add:"-1"|stringformat:"02d" %}
1514
<select class="form-select{% if document_html %} form-select-sm mb-1{% endif %} select2-field"
1615
data-max-entries="1"
1716
data-width="resolve"
1817
data-allow-clear="false"
1918
data-minimum-input-length="0"
2019
{% if not document_html %}id="url1"{% else %}aria-label="From revision"{% endif %}
2120
name="url1">
22-
{% for name, rev, time, url in diff_revisions %}
23-
<option value="{{ url }}"
24-
{% if document_html %}
25-
{% if name == doc.name %}
26-
{% if rev == prev_rev or doc.rev == "00" and rev == "00" %} selected{% endif %}
27-
{% endif %}
28-
{% else %}
29-
{% if diff_revisions|length > 1 and forloop.counter == 2 %} selected{% endif %}
30-
{% endif %}>
21+
{% for name, rev, time, url, is_this_doc, is_previous_doc in diff_revisions %}
22+
<option value="{{ url }}"{% if is_previous_doc %} selected{% endif %}>
3123
{{ name|prettystdname }}{% if rev %}-{{ rev }}{% endif %}
3224
{% if not document_html %}({{ time|date:"Y-m-d" }}){% endif %}
3325
</option>
3426
{% endfor %}
35-
{% if doc.name|rfcbis %}
27+
{% if doc.name|rfcbis %} {# TODO - move this into the diffable versions logic #}
3628
<option value="{{ doc.name|rfcbis }}"
37-
{% if document_html %}
38-
{% if rev == prev_rev %} selected{% endif %}
39-
{% else %}
4029
{% if diff_revisions and diff_revisions|length == 1 %} selected{% endif %}
41-
{% endif %}>
4230
{{ doc.name|rfcbis|prettystdname }}
4331
</option>
4432
{% endif %}
@@ -57,13 +45,8 @@
5745
data-minimum-input-length="0"
5846
{% if not document_html %}id="url2"{% else %}aria-label="To revision"{% endif %}
5947
name="url2">
60-
{% for name, rev, time, url in diff_revisions %}
61-
<option value="{{ url }}"
62-
{% if document_html %}
63-
{% if not snapshot and doc.get_state_slug == "rfc" and name == "rfc"|add:doc.rfc_number or snapshot and name == doc.name and rev == doc.rev %} selected{% endif %}
64-
{% else %}
65-
{% if forloop.counter == 1 %} selected{% endif %}
66-
{% endif %}>
48+
{% for name, rev, time, url, is_this_doc, is_previous_doc in diff_revisions %}
49+
<option value="{{ url }}"{% if is_this_doc %} selected{%endif%}>
6750
{{ name|prettystdname }}{% if rev %}-{{ rev }}{% endif %}
6851
{% if not document_html %}({{ time|date:"Y-m-d" }}){% endif %}
6952
</option>
@@ -107,7 +90,6 @@
10790
name="difftype">
10891
Inline
10992
</button>
110-
{% endwith %}
11193
{% if not document_html %}
11294
</div>
11395
</div>

ietf/templates/doc/document_html.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
{% endif %}
3434
<link rel="alternate" type="application/atom+xml" title="Document changes" href="/feed/document-changes/{{ doc.name }}/">
3535
<meta name="description"
36-
{% if not snapshot and doc.get_state_slug == 'rfc' %}
37-
content="{{ doc.title }} (RFC {{ doc.rfc_number }}{% if published %}, {{ published.time|date:'F Y' }}{% endif %}{% if obsoleted_by %}; obsoleted by {% for rel in obsoleted_by %}{{ rel.source.name|prettystdname}}{% if not forloop.last%}, {% endif %}{% endfor %}{% endif %})"
36+
{% if doc.type_id == "rfc" %}
37+
content="{{ doc.title }} (RFC {{ doc.rfc_number }}, {{ published.time|date:'F Y' }}{% if obsoleted_by %}; obsoleted by {% for rel in obsoleted_by %}{{ rel.source.name|prettystdname}}{% if not forloop.last%}, {% endif %}{% endfor %}{% endif %})"
3838
{% else %}
3939
content="{{ doc.title }} (Internet-Draft, {{ doc.time|date:'Y' }})"
4040
{% endif %}>
@@ -98,9 +98,9 @@
9898
<nav class="navbar bg-light-subtle px-1 fixed-top d-print-none d-md-none">
9999
<a class="nav-link ps-1"
100100
href="{% url 'ietf.doc.views_doc.document_main' name=doc.name %}">
101-
{% if not snapshot and doc.get_state_slug == "rfc" %}
101+
{% if doc.type_id == "rfc" %}
102102
RFC {{ doc.rfc_number }}
103-
{% else %}
103+
{% else %}
104104
{{ doc.name }}-{{ doc.rev }}
105105
{% endif %}
106106
<br class="d-sm-none">
@@ -175,7 +175,7 @@
175175
<div class="pt-2 pt-lg-3 px-md-2 px-lg-3">
176176
<a class="btn btn-primary btn-sm" href="{% url 'ietf.doc.views_doc.document_main' name=doc.name %}">Datatracker</a>
177177
<p class="fw-bold pt-2">
178-
{% if not snapshot and doc.get_state_slug == "rfc" %}
178+
{% if doc.type_id == "rfc" %}
179179
RFC {{ doc.rfc_number }}
180180
{% else %}
181181
{{ doc.name }}-{{ doc.rev }}

0 commit comments

Comments
 (0)