change text for missing authors in public domain
[wolnelektury.git] / src / search / views.py
index 70a216e..f7f6040 100644 (file)
@@ -3,20 +3,21 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django.conf import settings
+from django.http.response import HttpResponseRedirect
 from django.shortcuts import render_to_response
 from django.template import RequestContext
 from django.views.decorators import cache
 from django.http import HttpResponse, JsonResponse
-from django.utils.translation import ugettext as _
 
-from catalogue.utils import split_tags
 from catalogue.models import Book, Tag
-from pdcounter.models import Author as PDCounterAuthor, BookStub as PDCounterBook
+from pdcounter.models import Author
 from search.index import Search, SearchResult
 from suggest.forms import PublishingSuggestForm
 import re
 import json
 
+from wolnelektury.utils import re_escape
+
 
 def match_word_re(word):
     if 'sqlite' in settings.DATABASES['default']['ENGINE']:
@@ -29,7 +30,7 @@ query_syntax_chars = re.compile(r"[\\/*:(){}]")
 
 
 def remove_query_syntax_chars(query, replace=' '):
-    return query_syntax_chars.sub(' ', query)
+    return query_syntax_chars.sub(replace, query)
 
 
 def did_you_mean(query, tokens):
@@ -64,30 +65,31 @@ def hint(request):
     if len(prefix) < 2:
         return JsonResponse([], safe=False)
 
-    prefix = remove_query_syntax_chars(prefix)
+    prefix = re_escape(' '.join(remove_query_syntax_chars(prefix).split()))
 
     try:
         limit = int(request.GET.get('max', ''))
     except ValueError:
-        limit = -1
+        limit = 20
     else:
         if limit < 1:
-            limit = -1
+            limit = 20
 
+    authors = Tag.objects.filter(
+        category='author', name_pl__iregex='\m' + prefix).only('name', 'id', 'slug', 'category')
     data = [
         {
             'label': author.name,
-            'category': _('author'),
             'id': author.id,
             'url': author.get_absolute_url(),
         }
-        for author in Tag.objects.filter(category='author', name__iregex='\m' + prefix)[:10]
+        for author in authors[:limit]
     ]
     if len(data) < limit:
         data += [
             {
-                'label': '<cite>%s</cite>, %s' % (b.title, b.author_unicode()),
-                'category': _('book'),
+                'label': b.title,
+                'author': b.author_unicode(),
                 'id': b.id,
                 'url': b.get_absolute_url()
             }
@@ -125,8 +127,11 @@ def main(request):
 
     search = Search()
 
-    tags = search.hint_tags(query, pdcounter=True, prefix=False)
-    tags = split_tags(tags)
+    pd_authors = Author.objects.filter(name__icontains=query)
+    existing_slugs = Tag.objects.filter(
+        category='author', slug__in=list(pd_authors.values_list('slug', flat=True)))\
+        .values_list('slug', flat=True)
+    pd_authors = pd_authors.exclude(slug__in=existing_slugs)
 
     results_parts = []
 
@@ -137,8 +142,8 @@ def main(request):
         (['metadata'], True),
         (['text', 'themes_pl'], False),
     )
-    for fieldset, is_book in fieldsets:
-        search_fields += fieldset
+    for fields, is_book in fieldsets:
+        search_fields += fields
         results_parts.append(search.search_words(words, search_fields, book=is_book))
 
     results = []
@@ -152,6 +157,10 @@ def main(request):
                 results.append(result)
                 ids_results[book_id] = result
 
+    descendant_ids = set(
+        Book.objects.filter(id__in=ids_results, ancestor__in=ids_results).values_list('id', flat=True))
+    results = [result for result in results if result.book_id not in descendant_ids]
+
     for result in results:
         search.get_snippets(result, query, num=3)
 
@@ -165,23 +174,23 @@ def main(request):
 
     results = filter(ensure_exists, results)
 
-    if not results:
+    if not results and not pd_authors:
         form = PublishingSuggestForm(initial={"books": query + ", "})
         return render_to_response(
             'catalogue/search_no_hits.html',
             {
-                'tags': tags,
-                'prefix': query,
                 'form': form,
                 'did_you_mean': suggestion
             },
             context_instance=RequestContext(request))
 
+    if not results and len(pd_authors) == 1:
+        return HttpResponseRedirect(pd_authors[0].get_absolute_url())
+
     return render_to_response(
         'catalogue/search_multiple_hits.html',
         {
-            'tags': tags['author'] + tags['kind'] + tags['genre'] + tags['epoch'] + tags['theme'],
-            'prefix': query,
+            'pd_authors': pd_authors,
             'results': results,
             'did_you_mean': suggestion
         },