Theme page.
[wolnelektury.git] / src / search / views.py
index 3bbe720..6ff0f7a 100644 (file)
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
@@ -12,6 +11,7 @@ from catalogue.models import Book, Tag
 from pdcounter.models import Author
 from picture.models import Picture
 from search.index import Search, SearchResult, PictureResult
 from pdcounter.models import Author
 from picture.models import Picture
 from search.index import Search, SearchResult, PictureResult
+from .forms import SearchFilters
 from suggest.forms import PublishingSuggestForm
 import re
 import json
 from suggest.forms import PublishingSuggestForm
 import re
 import json
@@ -60,8 +60,8 @@ def did_you_mean(query, tokens):
 
 
 @cache.never_cache
 
 
 @cache.never_cache
-def hint(request):
-    prefix = request.GET.get('term', '')
+def hint(request, mozhint=False, param='term'):
+    prefix = request.GET.get(param, '')
     if len(prefix) < 2:
         return JsonResponse([], safe=False)
 
     if len(prefix) < 2:
         return JsonResponse([], safe=False)
 
@@ -86,15 +86,29 @@ def hint(request):
         for author in authors[:limit]
     ]
     if len(data) < limit:
         for author in authors[:limit]
     ]
     if len(data) < limit:
-        data += [
-            {
-                'label': b.title,
-                'author': b.author_unicode(),
-                'id': b.id,
-                'url': b.get_absolute_url()
-            }
-            for b in Book.objects.filter(title__iregex='\m' + prefix)[:limit-len(data)]
+        for b in Book.objects.filter(findable=True, title__iregex='\m' + prefix)[:limit-len(data)]:
+            author_str = b.author_unicode()
+            translator = b.translator()
+            if translator:
+                author_str += ' (tłum. ' + translator + ')'
+            data.append(
+                {
+                    'label': b.title,
+                    'author': author_str,
+                    'id': b.id,
+                    'url': b.get_absolute_url()
+                }
+            )
+
+    if mozhint:
+        data = [
+            prefix,
+            [
+                item['label']
+                for item in data
+            ]
         ]
         ]
+
     callback = request.GET.get('callback', None)
     if callback:
         return HttpResponse("%s(%s);" % (callback, json.dumps(data)),
     callback = request.GET.get('callback', None)
     if callback:
         return HttpResponse("%s(%s);" % (callback, json.dumps(data)),
@@ -103,9 +117,38 @@ def hint(request):
         return JsonResponse(data, safe=False)
 
 
         return JsonResponse(data, safe=False)
 
 
+
+@cache.never_cache
+def search(request):
+    filters = SearchFilters(request.GET)
+    ctx = {
+        'title': 'Wynik wyszukiwania',
+        'query': filters.data['q'],
+        'filters': filters,
+    }
+    if filters.is_valid():
+        ctx['results'] = filters.results()
+        for k, v in ctx['results'].items():
+            if v:
+                ctx['hasresults'] = True
+                break
+    return render(request, 'search/results.html', ctx)
+
+
 @cache.never_cache
 def main(request):
 @cache.never_cache
 def main(request):
+    if request.EXPERIMENTS['search'].value:
+        request.EXPERIMENTS['layout'].override(True)
+        return search(request)
+
     query = request.GET.get('q', '')
     query = request.GET.get('q', '')
+
+    format = request.GET.get('format')
+    lang = request.GET.get('lang')
+    epoch = request.GET.get('epoch')
+    kind = request.GET.get('kind')
+    genre = request.GET.get('genre')
+
     if len(query) < 2:
         return render(
             request, 'catalogue/search_too_short.html',
     if len(query) < 2:
         return render(
             request, 'catalogue/search_too_short.html',
@@ -116,10 +159,33 @@ def main(request):
             {'prefix': query})
 
     query = prepare_query(query)
             {'prefix': query})
 
     query = prepare_query(query)
-    pd_authors = search_pd_authors(query)
-    books = search_books(query)
-    pictures = search_pictures(query)
-    suggestion = u''
+    if not (format or lang or epoch or kind or genre):
+        pd_authors = search_pd_authors(query)
+    else:
+        pd_authors = []
+    if not format or format != 'obraz':
+        books = search_books(
+            query,
+            lang=lang,
+            only_audio=format=='audio',
+            only_synchro=format=='synchro',
+            epoch=epoch,
+            kind=kind,
+            genre=genre
+        )
+    else:
+        books = []
+    if (not format or format == 'obraz') and not lang:
+        pictures = search_pictures(
+            query,
+            epoch=epoch,
+            kind=kind,
+            genre=genre
+        )
+    else:
+        pictures = []
+    
+    suggestion = ''
 
     if not (books or pictures or pd_authors):
         form = PublishingSuggestForm(initial={"books": query + ", "})
 
     if not (books or pictures or pd_authors):
         form = PublishingSuggestForm(initial={"books": query + ", "})
@@ -141,10 +207,22 @@ def main(request):
             'pd_authors': pd_authors,
             'books': books,
             'pictures': pictures,
             'pd_authors': pd_authors,
             'books': books,
             'pictures': pictures,
-            'did_you_mean': suggestion
+            'did_you_mean': suggestion,
+            'set': {
+                'lang': lang,
+                'format': format,
+                'epoch': epoch,
+                'kind': kind,
+                'genre': genre,
+            },
+            'tags': {
+                'epoch': Tag.objects.filter(category='epoch', for_books=True),
+                'genre': Tag.objects.filter(category='genre', for_books=True),
+                'kind': Tag.objects.filter(category='kind', for_books=True),
+            },
         })
 
         })
 
-def search_books(query):
+def search_books(query, lang=None, only_audio=False, only_synchro=False, epoch=None, kind=None, genre=None):
     search = Search()
     results_parts = []
     search_fields = []
     search = Search()
     results_parts = []
     search_fields = []
@@ -176,15 +254,31 @@ def search_books(query):
 
     def ensure_exists(r):
         try:
 
     def ensure_exists(r):
         try:
-            return r.book
+            if not r.book:
+                return False
         except Book.DoesNotExist:
             return False
 
         except Book.DoesNotExist:
             return False
 
-    results = filter(ensure_exists, results)
+        if lang and r.book.language != lang:
+            return False
+        if only_audio and not r.book.has_mp3_file():
+            return False
+        if only_synchro and not r.book.has_daisy_file():
+            return False
+        if epoch and not r.book.tags.filter(category='epoch', slug=epoch).exists():
+            return False
+        if kind and not r.book.tags.filter(category='kind', slug=kind).exists():
+            return False
+        if genre and not r.book.tags.filter(category='genre', slug=genre).exists():
+            return False
+
+        return True
+
+    results = [r for r in results if ensure_exists(r)]
     return results
 
 
     return results
 
 
-def search_pictures(query):
+def search_pictures(query, epoch=None, kind=None, genre=None):
     search = Search()
     results_parts = []
     search_fields = []
     search = Search()
     results_parts = []
     search_fields = []
@@ -211,11 +305,21 @@ def search_pictures(query):
 
     def ensure_exists(r):
         try:
 
     def ensure_exists(r):
         try:
-            return r.picture
+            if not r.picture:
+                return False
         except Picture.DoesNotExist:
             return False
 
         except Picture.DoesNotExist:
             return False
 
-    results = filter(ensure_exists, results)
+        if epoch and not r.picture.tags.filter(category='epoch', slug=epoch).exists():
+            return False
+        if kind and not r.picture.tags.filter(category='kind', slug=kind).exists():
+            return False
+        if genre and not r.picture.tags.filter(category='genre', slug=genre).exists():
+            return False
+
+        return True
+
+    results = [r for r in results if ensure_exists(r)]
     return results
 
 
     return results