Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: teach search about rfcs and subseries #6431

Merged
merged 3 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions ietf/doc/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
72 changes: 57 additions & 15 deletions ietf/doc/views_search.py
Original file line number Diff line number Diff line change
@@ -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).
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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"])

Expand All @@ -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 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"]:
Expand Down Expand Up @@ -320,16 +362,16 @@ 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
elif doc.get_state('draft').name in ('Expired', 'Replaced'):
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':
Expand All @@ -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
Expand Down Expand Up @@ -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)
)

Expand Down Expand Up @@ -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]
Expand Down
4 changes: 4 additions & 0 deletions ietf/templates/doc/search/status_columns.html
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,9 @@
<br>
<span class="text-body-secondary">Updated by {{ doc.updated_by_list|join:", "|urlize_ietf_docs }}</span>
{% endif %}
{% if doc.part_of %}
<br>
<span class="text-body-secondary">{% for sub in doc.part_of %}{% if sub.contains|length_is:"1" %} Also known as {% else %} Part of {% endif %}<a href="{% url 'ietf.doc.views_doc.document_main' name=sub.name%}">{{sub.name|slice:":3"|upper}} {{sub.name|slice:"3:"}}</a>{% if not forloop.last %}, {%endif%}{% endfor %}</span>
{% endif %}
{% endif %}
</td>
Loading