Allow author creation by api.
[wolnelektury.git] / src / search / views.py
index 9be6732..b6e290b 100644 (file)
@@ -1,11 +1,9 @@
-# -*- 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.
 #
 from django.conf import settings
 from django.http.response import HttpResponseRedirect
 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
 # 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.shortcuts import render
 from django.views.decorators import cache
 from django.http import HttpResponse, JsonResponse
 
 from django.views.decorators import cache
 from django.http import HttpResponse, JsonResponse
 
@@ -27,7 +25,7 @@ def match_word_re(word):
         return "[[:<:]]%s[[:>:]]" % word
 
 
         return "[[:<:]]%s[[:>:]]" % word
 
 
-query_syntax_chars = re.compile(r"[\\/*:(){}?.]")
+query_syntax_chars = re.compile(r"[\\/*:(){}?.[\]+]")
 
 
 def remove_query_syntax_chars(query, replace=' '):
 
 
 def remove_query_syntax_chars(query, replace=' '):
@@ -61,8 +59,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)
 
@@ -94,8 +92,18 @@ def hint(request):
                 'id': b.id,
                 'url': b.get_absolute_url()
             }
                 '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)]
         ]
         ]
+
+    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)),
@@ -107,54 +115,96 @@ def hint(request):
 @cache.never_cache
 def main(request):
     query = request.GET.get('q', '')
 @cache.never_cache
 def main(request):
     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:
     if len(query) < 2:
-        return render_to_response(
-            'catalogue/search_too_short.html', {'prefix': query},
-            context_instance=RequestContext(request))
+        return render(
+            request, 'catalogue/search_too_short.html',
+            {'prefix': query})
     elif len(query) > 256:
     elif len(query) > 256:
-        return render_to_response(
-            'catalogue/search_too_long.html', {'prefix': query}, context_instance=RequestContext(request))
+        return render(
+            request, 'catalogue/search_too_long.html',
+            {'prefix': query})
 
     query = prepare_query(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 + ", "})
-        return render_to_response(
+        return render(
+            request,
             'catalogue/search_no_hits.html',
             {
                 'form': form,
                 'did_you_mean': suggestion
             'catalogue/search_no_hits.html',
             {
                 'form': form,
                 'did_you_mean': suggestion
-            },
-            context_instance=RequestContext(request))
+            })
 
     if not (books or pictures) and len(pd_authors) == 1:
         return HttpResponseRedirect(pd_authors[0].get_absolute_url())
 
 
     if not (books or pictures) and len(pd_authors) == 1:
         return HttpResponseRedirect(pd_authors[0].get_absolute_url())
 
-    return render_to_response(
+    return render(
+        request,
         'catalogue/search_multiple_hits.html',
         {
             'pd_authors': pd_authors,
             'books': books,
             'pictures': pictures,
         'catalogue/search_multiple_hits.html',
         {
             'pd_authors': pd_authors,
             'books': books,
             'pictures': pictures,
-            'did_you_mean': suggestion
-        },
-        context_instance=RequestContext(request))
-
+            '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 = []
     words = query.split()
     fieldsets = (
     search = Search()
     results_parts = []
     search_fields = []
     words = query.split()
     fieldsets = (
-        (['authors'], True),
-        (['title'], True),
-        (['metadata'], True),
-        (['text', 'themes_pl'], False),
+        (['authors', 'authors_nonstem'], True),
+        (['title', 'title_nonstem'], True),
+        (['metadata', 'metadata_nonstem'], True),
+        (['text', 'text_nonstem', 'themes_pl', 'themes_pl_nonstem'], False),
     )
     for fields, is_book in fieldsets:
         search_fields += fields
     )
     for fields, is_book in fieldsets:
         search_fields += fields
@@ -177,24 +227,40 @@ 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 = []
     words = query.split()
     fieldsets = (
     search = Search()
     results_parts = []
     search_fields = []
     words = query.split()
     fieldsets = (
-        (['authors'], True),
-        (['title'], True),
-        (['metadata'], True),
-        (['themes_pl'], False),
+        (['authors', 'authors_nonstem'], True),
+        (['title', 'title_nonstem'], True),
+        (['metadata', 'metadata_nonstem'], True),
+        (['themes_pl', 'themes_pl_nonstem'], False),
     )
     for fields, is_book in fieldsets:
         search_fields += fields
     )
     for fields, is_book in fieldsets:
         search_fields += fields
@@ -212,11 +278,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