diff --git a/ietf/doc/tests.py b/ietf/doc/tests.py
index d6c4327469..3a6f860329 100644
--- a/ietf/doc/tests.py
+++ b/ietf/doc/tests.py
@@ -66,6 +66,7 @@ class SearchTests(TestCase):
def test_search(self):
draft = WgDraftFactory(name='draft-ietf-mars-test',group=GroupFactory(acronym='mars',parent=Group.objects.get(acronym='farfut')),authors=[PersonFactory()],ad=PersonFactory())
+ rfc = WgRfcFactory()
draft.set_state(State.objects.get(used=True, type="draft-iesg", slug="pub-req"))
old_draft = IndividualDraftFactory(name='draft-foo-mars-test',authors=[PersonFactory()],title="Optimizing Martian Network Topologies")
old_draft.set_state(State.objects.get(used=True, type="draft", slug="expired"))
@@ -97,11 +98,12 @@ def test_search(self):
self.assertEqual(r.status_code, 200)
self.assertContains(r, "draft-foo-mars-test")
- # find by rfc/active/inactive
- draft.set_state(State.objects.get(type="draft", slug="rfc"))
- r = self.client.get(base_url + "?rfcs=on&name=%s" % draft.name)
+ # find by RFC
+ r = self.client.get(base_url + "?rfcs=on&name=%s" % rfc.name)
self.assertEqual(r.status_code, 200)
- self.assertContains(r, draft.title)
+ self.assertContains(r, rfc.title)
+
+ # find by active/inactive
draft.set_state(State.objects.get(type="draft", slug="active"))
r = self.client.get(base_url + "?activedrafts=on&name=%s" % draft.name)
@@ -322,8 +324,7 @@ def test_docs_for_ad(self):
draft = IndividualDraftFactory(ad=ad)
draft.action_holders.set([PersonFactory()])
draft.set_state(State.objects.get(type='draft-iesg', slug='lc'))
- rfc = IndividualDraftFactory(ad=ad)
- rfc.set_state(State.objects.get(type='draft', slug='rfc'))
+ rfc = IndividualRfcFactory(ad=ad)
conflrev = DocumentFactory(type_id='conflrev',ad=ad)
conflrev.set_state(State.objects.get(type='conflrev', slug='iesgeval'))
statchg = DocumentFactory(type_id='statchg',ad=ad)
diff --git a/ietf/doc/views_search.py b/ietf/doc/views_search.py
index c1cc718835..b3627df5cc 100644
--- a/ietf/doc/views_search.py
+++ b/ietf/doc/views_search.py
@@ -1,4 +1,4 @@
-# Copyright The IETF Trust 2009-2022, All Rights Reserved
+# Copyright The IETF Trust 2009-2023, All Rights Reserved
# -*- coding: utf-8 -*-
#
# Some parts Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
@@ -36,8 +36,10 @@
import re
import datetime
+import operator
from collections import defaultdict
+from functools import reduce
from django import forms
from django.conf import settings
@@ -95,7 +97,7 @@ class SearchForm(forms.Form):
("ad", "AD"), ("-ad", "AD (desc)"), ),
required=False, widget=forms.HiddenInput)
- doctypes = forms.ModelMultipleChoiceField(queryset=DocTypeName.objects.filter(used=True).exclude(slug__in=('draft','liai-att')).order_by('name'), required=False)
+ doctypes = forms.ModelMultipleChoiceField(queryset=DocTypeName.objects.filter(used=True).exclude(slug__in=('draft', 'rfc', 'bcp', 'std', 'fyi', 'liai-att')).order_by('name'), required=False)
def __init__(self, *args, **kwargs):
super(SearchForm, self).__init__(*args, **kwargs)
@@ -154,8 +156,11 @@ def retrieve_search_results(form, all_types=False):
else:
types = []
- if query['activedrafts'] or query['olddrafts'] or query['rfcs']:
+ if query['activedrafts'] or query['olddrafts']:
types.append('draft')
+
+ if query['rfcs']:
+ types.append('rfc')
types.extend(query["doctypes"])
@@ -166,13 +171,50 @@ def retrieve_search_results(form, all_types=False):
# name
if query["name"]:
- docs = docs.filter(Q(name__icontains=query["name"]) |
- Q(title__icontains=query["name"])).distinct()
+ look_for = query["name"]
+ queries = [
+ Q(name__icontains=look_for),
+ Q(title__icontains=look_for)
+ ]
+ # Check to see if this is just a search for an rfc look for a few variants
+ if look_for.lower()[:3] == "rfc" and look_for[3:].strip().isdigit():
+ spaceless = look_for.lower()[:3]+look_for[3:].strip()
+ if spaceless != look_for:
+ queries.extend([
+ Q(name__icontains=spaceless),
+ Q(title__icontains=spaceless)
+ ])
+ singlespace = look_for.lower()[:3]+" "+look_for[3:].strip()
+ if singlespace != look_for:
+ queries.extend([
+ Q(name__icontains=singlespace),
+ Q(title__icontains=singlespace)
+ ])
+
+ # Do a similar thing if the search is just for a subseries doc, like a bcp.
+ if look_for.lower()[:3] in ["bcp", "fyi", "std"] and look_for[3:].strip().isdigit() and query["rfcs"]: # Also look for rfcs contained in the subseries.
+ queries.extend([
+ Q(targets_related__source__name__icontains=look_for, targets_related__relationship_id="contains"),
+ Q(targets_related__source__title__icontains=look_for, targets_related__relationship_id="contains"),
+ ])
+ spaceless = look_for.lower()[:3]+look_for[3:].strip()
+ if spaceless != look_for:
+ queries.extend([
+ Q(targets_related__source__name__icontains=spaceless, targets_related__relationship_id="contains"),
+ Q(targets_related__source__title__icontains=spaceless, targets_related__relationship_id="contains"),
+ ])
+ singlespace = look_for.lower()[:3]+" "+look_for[3:].strip()
+ if singlespace != look_for:
+ queries.extend([
+ Q(targets_related__source__name__icontains=singlespace, targets_related__relationship_id="contains"),
+ Q(targets_related__source__title__icontains=singlespace, targets_related__relationship_id="contains"),
+ ])
+
+ combined_query = reduce(operator.or_, queries)
+ docs = docs.filter(combined_query).distinct()
# rfc/active/old check buttons
allowed_draft_states = []
- if query["rfcs"]:
- allowed_draft_states.append("rfc")
if query["activedrafts"]:
allowed_draft_states.append("active")
if query["olddrafts"]:
@@ -320,9 +362,7 @@ def ad_dashboard_group_type(doc):
if not doc:
return ('I-D', 'RFC', 'Conflict Review', 'Status Change', 'Charter')
if doc.type.slug=='draft':
- if doc.get_state_slug('draft') == 'rfc':
- return 'RFC'
- elif doc.get_state_slug('draft') == 'active' and doc.get_state_slug('draft-iesg') and doc.get_state('draft-iesg').name =='RFC Ed Queue':
+ if doc.get_state_slug('draft') == 'active' and doc.get_state_slug('draft-iesg') and doc.get_state('draft-iesg').name =='RFC Ed Queue':
return 'RFC'
elif doc.get_state_slug('draft') == 'active' and doc.get_state_slug('draft-iesg') and doc.get_state('draft-iesg').name in ('Dead', 'I-D Exists', 'AD is watching'):
return None
@@ -330,6 +370,8 @@ def ad_dashboard_group_type(doc):
return None
else:
return 'I-D'
+ if doc.type.slug=='rfc':
+ return 'RFC'
elif doc.type.slug=='conflrev':
return 'Conflict Review'
elif doc.type.slug=='statchg':
@@ -341,10 +383,10 @@ def ad_dashboard_group_type(doc):
def ad_dashboard_group(doc):
+ if doc.type.slug=='rfc':
+ return 'RFC'
if doc.type.slug=='draft':
- if doc.get_state_slug('draft') == 'rfc':
- return 'RFC'
- elif doc.get_state_slug('draft') == 'active' and doc.get_state_slug('draft-iesg'):
+ if doc.get_state_slug('draft') == 'active' and doc.get_state_slug('draft-iesg'):
return '%s Internet-Draft' % doc.get_state('draft-iesg').name
else:
return '%s Internet-Draft' % doc.get_state('draft').name
@@ -482,7 +524,7 @@ def ad_workload(request):
doctypes = list(
DocTypeName.objects.filter(used=True)
- .exclude(slug__in=("draft", "liai-att"))
+ .exclude(slug__in=("draft", "rfc", "std", "bcp", "fyi", "liai-att"))
.values_list("pk", flat=True)
)
@@ -680,7 +722,7 @@ def docs_for_ad(request, name):
form = SearchForm({'by':'ad','ad': ad.id,
'rfcs':'on', 'activedrafts':'on', 'olddrafts':'on',
'sort': 'status',
- 'doctypes': list(DocTypeName.objects.filter(used=True).exclude(slug__in=('draft','liai-att')).values_list("pk", flat=True))})
+ 'doctypes': list(DocTypeName.objects.filter(used=True).exclude(slug__in=('draft', 'rfc', 'bcp' ,'std', 'fyi', 'liai-att')).values_list("pk", flat=True))})
results, meta = prepare_document_table(request, retrieve_search_results(form), form.data, max_results=500)
results.sort(key=ad_dashboard_sort_key)
del meta["headers"][-1]
diff --git a/ietf/templates/doc/search/status_columns.html b/ietf/templates/doc/search/status_columns.html
index 5f8dd826f5..15f284fd12 100644
--- a/ietf/templates/doc/search/status_columns.html
+++ b/ietf/templates/doc/search/status_columns.html
@@ -89,5 +89,9 @@
Updated by {{ doc.updated_by_list|join:", "|urlize_ietf_docs }}
{% endif %}
+ {% if doc.part_of %}
+
+ {% for sub in doc.part_of %}{% if sub.contains|length_is:"1" %} Also known as {% else %} Part of {% endif %}{{sub.name|slice:":3"|upper}} {{sub.name|slice:"3:"}}{% if not forloop.last %}, {%endif%}{% endfor %}
+ {% endif %}
{% endif %}
\ No newline at end of file