aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2013-02-19 15:54:43 +0000
committerPaul Eggleton <paul.eggleton@linux.intel.com>2013-02-19 17:22:45 +0000
commit430ae4f90e8953a0f1c91842bb2eb291ab9b92df (patch)
tree19f102279ea00cd1fda502787fdc052f275bce91
parentfd600fb716ce46a0f73ca0017f1923fba6cb53ef (diff)
downloadopenembedded-core-contrib-430ae4f90e8953a0f1c91842bb2eb291ab9b92df.tar.gz
Improve recipe search
* Use more traditional GET instead of POST method * Search in pn, summary, description and filename instead of just pn Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
-rw-r--r--README3
-rw-r--r--layerindex/recipes.html5
-rw-r--r--layerindex/simplesearch.py39
-rw-r--r--layerindex/views.py16
4 files changed, 50 insertions, 13 deletions
diff --git a/README b/README
index 9bd42368cd..0a113ef188 100644
--- a/README
+++ b/README
@@ -91,5 +91,6 @@ Bundled jQuery is redistributed under the MIT license.
Bundled uitablefilter.js is redistributed under the MIT license.
All other content is copyright (C) 2013 Intel Corporation and licensed
-under the MIT license - see COPYING.MIT for details.
+under the MIT license (unless otherwise noted) - see COPYING.MIT for
+details.
diff --git a/layerindex/recipes.html b/layerindex/recipes.html
index a51831d25c..72021b0aee 100644
--- a/layerindex/recipes.html
+++ b/layerindex/recipes.html
@@ -31,9 +31,8 @@
<div class="row-fluid">
<div class="input-append">
- <form id="filter-form" action="{% url recipe_search %}" method="post">
- {% csrf_token %}
- <input type="text" class="input-xxlarge" id="appendedInputButtons" placeholder="Search recipes" name="filter" value="{{ search_keyword }}" />
+ <form id="filter-form" action="{% url recipe_search %}" method="get">
+ <input type="text" class="input-xxlarge" id="appendedInputButtons" placeholder="Search recipes" name="q" value="{{ search_keyword }}" />
<button class="btn" type="submit">search</button>
</form>
</div>
diff --git a/layerindex/simplesearch.py b/layerindex/simplesearch.py
new file mode 100644
index 0000000000..3b2a530716
--- /dev/null
+++ b/layerindex/simplesearch.py
@@ -0,0 +1,39 @@
+# Borrowed from http://julienphalip.com/post/2825034077/adding-search-to-a-django-site-in-a-snap
+# Copyright 2011 Julien Phalip. All Rights Reserved.
+
+import re
+from django.db.models import Q
+
+def normalize_query(query_string,
+ findterms=re.compile(r'"([^"]+)"|(\S+)').findall,
+ normspace=re.compile(r'\s{2,}').sub):
+ ''' Splits the query string in invidual keywords, getting rid of unecessary spaces
+ and grouping quoted words together.
+ Example:
+
+ >>> normalize_query(' some random words "with quotes " and spaces')
+ ['some', 'random', 'words', 'with quotes', 'and', 'spaces']
+
+ '''
+ return [normspace(' ', (t[0] or t[1]).strip()) for t in findterms(query_string)]
+
+def get_query(query_string, search_fields):
+ ''' Returns a query, that is a combination of Q objects. That combination
+ aims to search keywords within a model by testing the given search fields.
+
+ '''
+ query = None # Query to search for every search term
+ terms = normalize_query(query_string)
+ for term in terms:
+ or_query = None # Query to search for a given term in each field
+ for field_name in search_fields:
+ q = Q(**{"%s__icontains" % field_name: term})
+ if or_query is None:
+ or_query = q
+ else:
+ or_query = or_query | q
+ if query is None:
+ query = or_query
+ else:
+ query = query & or_query
+ return query
diff --git a/layerindex/views.py b/layerindex/views.py
index a96ec40f49..eca6472499 100644
--- a/layerindex/views.py
+++ b/layerindex/views.py
@@ -19,6 +19,7 @@ from django.db.models import Q
from django.core.mail import EmailMessage
from django.template.loader import get_template
from django.template import Context
+import simplesearch
import settings
@@ -96,22 +97,19 @@ class LayerListView(ListView):
class RecipeSearchView(ListView):
context_object_name = 'recipe_list'
- paginate_by = 20
+ paginate_by = 10
def get_queryset(self):
- keyword = self.request.session.get('keyword')
- if keyword:
- return Recipe.objects.all().filter(pn__icontains=keyword).order_by('pn', 'layer')
+ query_string = self.request.GET.get('q', '')
+ if query_string.strip():
+ entry_query = simplesearch.get_query(query_string, ['pn', 'summary', 'description', 'filename'])
+ return Recipe.objects.filter(entry_query).order_by('pn', 'layer')
else:
return Recipe.objects.all().order_by('pn', 'layer')
- def post(self, request, *args, **kwargs):
- request.session['keyword'] = request.POST['filter']
- return HttpResponseRedirect(reverse('recipe_search'))
-
def get_context_data(self, **kwargs):
context = super(RecipeSearchView, self).get_context_data(**kwargs)
- context['search_keyword'] = self.request.session.get('keyword') or ''
+ context['search_keyword'] = self.request.GET.get('q', '')
return context