Theme page.
[wolnelektury.git] / src / search / views.py
index 970734a..6ff0f7a 100644 (file)
@@ -11,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
@@ -59,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)
 
@@ -85,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(findable=True, 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)),
@@ -102,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',
@@ -115,9 +159,32 @@ 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)
+    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):
     suggestion = ''
 
     if not (books or pictures or pd_authors):
@@ -140,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 = []
@@ -175,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
 
+        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
 
 
     results = [r for r in results if ensure_exists(r)]
     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 = []
@@ -210,10 +305,20 @@ 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
 
+        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
 
     results = [r for r in results if ensure_exists(r)]
     return results