search for exact matches first, fixing #533
[wolnelektury.git] / apps / catalogue / views.py
index b4fb092..4601117 100644 (file)
@@ -171,7 +171,7 @@ def book_text(request, slug):
 # = Search =
 # ==========
 def _word_starts_with(name, prefix):
-    """returns a Q object gettings models having `name` contain a word
+    """returns a Q object getting models having `name` contain a word
     starting with `prefix`
     """
     kwargs = {}
@@ -190,6 +190,19 @@ def _word_starts_with(name, prefix):
     return Q(**kwargs)
 
 
+def _tags_exact_matches(prefix, user):
+    book_stubs = models.BookStub.objects.filter(title__iexact = prefix)
+    books = models.Book.objects.filter(title__iexact = prefix)
+    book_stubs = filter(lambda x: x not in books, book_stubs)
+    tags = models.Tag.objects.filter(name__iexact = prefix)
+    if user.is_authenticated():
+        tags = tags.filter(~Q(category='book') & (~Q(category='set') | Q(user=user)))
+    else:
+        tags = tags.filter(~Q(category='book') & ~Q(category='set'))
+
+    return list(books) + list(tags) + list(book_stubs)
+
+
 def _tags_starting_with(prefix, user):
     book_stubs = models.BookStub.objects.filter(_word_starts_with('title', prefix))
     books = models.Book.objects.filter(_word_starts_with('title', prefix))
@@ -214,10 +227,14 @@ def search(request):
 
     # Prefix must have at least 2 characters
     if len(prefix) < 2:
-        return render_to_response('catalogue/search_no_hits.html', {'query':prefix, 'tags':tag_list},
-            context_instance=RequestContext(request))
+        return HttpResponseRedirect(reverse('catalogue.views.search_no_hits', 
+            kwargs={'tags': '/'.join(tag.slug for tag in tag_list)}
+        ))
+    
+    result = _tags_exact_matches(prefix, request.user)
+    if (not result):
+        result = _tags_starting_with(prefix, request.user)
     
-    result = _tags_starting_with(prefix, request.user)
     if len(result) > 0:
         tag = result[0]
         if isinstance(tag, models.Book) or isinstance(tag, models.BookStub):
@@ -229,8 +246,19 @@ def search(request):
                 kwargs={'tags': '/'.join(tag.slug for tag in tag_list)}
             ))
     else:
-        return render_to_response('catalogue/search_no_hits.html', {'query':prefix, 'tags':tag_list},
-            context_instance=RequestContext(request))
+        return HttpResponseRedirect(reverse('catalogue.views.search_no_hits', 
+            kwargs={'tags': '/'.join(tag.slug for tag in tag_list)}
+        ))
+
+
+def search_no_hits(request, tags):
+    try:
+        tag_list = models.Tag.get_tag_list(tags)
+    except:
+        tag_list = []
+
+    return render_to_response('catalogue/search_no_hits.html', {'tags':tag_list},
+        context_instance=RequestContext(request))
 
 
 def tags_starting_with(request):