Merged [5898] from adam@nostrum.com, with

additional tweaks from henrik: Added the capability to search for all kinds
 of documents in the main datatracker search page.  Fixes bug #838.
 - Legacy-Id: 5926
Note: SVN reference [5898] has been migrated to Git commit b14a8d0cee
This commit is contained in:
Henrik Levkowetz 2013-07-31 12:45:32 +00:00
commit 6794113320
5 changed files with 76 additions and 31 deletions

View file

@ -62,6 +62,8 @@ class SearchForm(forms.Form):
sort = forms.ChoiceField(choices=(("document", "Document"), ("title", "Title"), ("date", "Date"), ("status", "Status"), ("ipr", "Ipr"), ("ad", "AD")), required=False, widget=forms.HiddenInput)
doctypes = DocTypeName.objects.exclude(slug='draft').order_by('name');
def __init__(self, *args, **kwargs):
super(SearchForm, self).__init__(*args, **kwargs)
responsible = Document.objects.values_list('ad', flat=True).distinct()
@ -155,12 +157,15 @@ def fill_in_search_attributes(docs):
else:
d.latest_revision_date = d.time
if d.get_state_slug() == "rfc":
d.search_heading = "RFC"
elif d.get_state_slug() == "active":
d.search_heading = "Active Internet-Draft"
if d.type_id == "draft":
if d.get_state_slug() == "rfc":
d.search_heading = "RFC"
elif d.get_state_slug() in ("ietf-rm", "auth-rm"):
d.search_heading = "Withdrawn Internet-Draft"
else:
d.search_heading = "%s Internet-Draft" % d.get_state()
else:
d.search_heading = "Old Internet-Draft"
d.search_heading = "%s" % (d.type,);
d.expirable = expirable_draft(d)
@ -196,22 +201,38 @@ def fill_in_search_attributes(docs):
l.sort()
def retrieve_search_results(form, types=['draft']):
def retrieve_search_results(form, all_types=False):
"""Takes a validated SearchForm and return the results."""
if not form.is_valid():
raise ValueError("SearchForm doesn't validate: %s" % form.errors)
query = form.cleaned_data
if not (query['activedrafts'] or query['olddrafts'] or query['rfcs']):
types=[];
meta = {}
if (query['activedrafts'] or query['olddrafts'] or query['rfcs']):
types.append('draft')
# Advanced document types are data-driven, so we need to read them from the
# raw form.data field (and track their checked/unchecked state ourselves)
meta['checked'] = {}
alltypes = DocTypeName.objects.exclude(slug='draft').order_by('name');
for doctype in alltypes:
if form.data.__contains__('include-' + doctype.slug):
types.append(doctype.slug)
meta['checked'][doctype.slug] = True
if len(types) == 0 and not all_types:
return ([], {})
MAX = 500
if types and len(types) > 0:
docs = Document.objects.filter(type__in=types)
else:
if all_types:
docs = Document.objects.all()
else:
docs = Document.objects.filter(type__in=types)
# name
if query["name"]:
@ -219,16 +240,16 @@ def retrieve_search_results(form, types=['draft']):
Q(title__icontains=query["name"])).distinct()
# rfc/active/old check buttons
if types == ['draft']:
allowed_states = []
if query["rfcs"]:
allowed_states.append("rfc")
if query["activedrafts"]:
allowed_states.append("active")
if query["olddrafts"]:
allowed_states.extend(['repl', 'expired', 'auth-rm', 'ietf-rm'])
allowed_draft_states = []
if query["rfcs"]:
allowed_draft_states.append("rfc")
if query["activedrafts"]:
allowed_draft_states.append("active")
if query["olddrafts"]:
allowed_draft_states.extend(['repl', 'expired', 'auth-rm', 'ietf-rm'])
docs = docs.filter(states__type="draft", states__slug__in=allowed_states)
docs = docs.filter(Q(states__slug__in=allowed_draft_states) |
~Q(type__slug='draft')).distinct()
# radio choices
by = query["by"]
@ -259,12 +280,14 @@ def retrieve_search_results(form, types=['draft']):
rfc_num = d.rfc_number()
if rfc_num != None:
res.append(2)
elif d.get_state_slug() == "active":
res.append(1)
if d.type_id == "draft":
res.append(["Active", "Expired", "Replaced", "Withdrawn", "RFC"].index(d.search_heading.split()[0] ))
else:
res.append(3)
res.append(d.type_id);
res.append("-");
res.append(d.get_state_slug());
res.append("-");
if query["sort"] == "title":
res.append(d.title)
@ -296,11 +319,10 @@ def retrieve_search_results(form, types=['draft']):
results.sort(key=sort_key)
# fill in a meta dict with some information for rendering the result table
meta = {}
if len(results) == MAX:
meta['max'] = MAX
meta['by'] = query['by']
meta['advanced'] = bool(query['by'])
meta['advanced'] = bool(query['by'] or len(meta['checked']))
meta['headers'] = [{'title': 'Document', 'key':'document'},
{'title': 'Title', 'key':'title'},
@ -316,7 +338,6 @@ def retrieve_search_results(form, types=['draft']):
h["sort_url"] = "?" + d.urlencode()
if h['key'] == query.get('sort'):
h['sorted'] = True
return (results, meta)
@ -477,7 +498,7 @@ def docs_for_ad(request, name):
form = SearchForm({'by':'ad','ad': ad.id,
'rfcs':'on', 'activedrafts':'on', 'olddrafts':'on',
'sort': 'status'})
results, meta = retrieve_search_results(form, types=None)
results, meta = retrieve_search_results(form, all_types=True)
results.sort(key=ad_dashboard_sort_key)
del meta["headers"][-1]
#

View file

@ -482,3 +482,12 @@ def _test():
if __name__ == "__main__":
_test()
@register.filter
def plural(text, list, arg=u's'):
"Similar to pluralize, but looks at the text, too"
from django.template.defaultfilters import pluralize
if text.endswith('s'):
return text
else:
return text + pluralize(len(list), arg)

View file

@ -52,6 +52,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<b class="toggle_advanced"><img src="/images/{% if meta.advanced %}minus{% else %}plus{% endif %}.png" alt="" /> Advanced</b>
<div id="search_advanced" style="{% if not meta.advanced %}display:none;{%endif%}">
<div class="search_field">
<label>Additional Document Types:</label>
<table id="search_types">
{% for doc_type in form.doctypes %}
<tr><td><label><input type="checkbox" advdoctype="true" {% if doc_type.slug in meta.checked %}checked="checked"{% endif %}name="include-{{doc_type.slug}}"/>{{doc_type}}</label></td></tr>
{% endfor %}
</table>
</div>
Additional search criteria:
<div class="search_field">

View file

@ -1,4 +1,4 @@
{% comment %}
{% comment %}<!--
Copyright (C) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
All rights reserved. Contact: Pasi Eronen <pasi.eronen@nokia.com>
@ -30,8 +30,9 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% endcomment %}
-->{% endcomment %}
{% load ietf_filters %}
<div class="search-results">
{% if not docs %}
@ -61,7 +62,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{% regroup docs by search_heading as grouped_docs %}
{% for doc_group in grouped_docs %}
<tr class="header"><td colspan="10">{{ doc_group.grouper }}{{doc_group.list|length|pluralize}}</td></tr>
<tr class="header"><td colspan="10">{{ doc_group.grouper|plural:doc_group.list }}</td></tr>
{% for doc in doc_group.list %}
{% include "idrfc/search_result_row.html" %}

View file

@ -12,6 +12,10 @@ $(function () {
advanced = true;
});
var additional_doctypes = form.find("input[advdoctype=true]:checked");
if (additional_doctypes.length > 0)
advanced = true;
return advanced;
}