Filtering search results.
authorRadek Czajka <rczajka@rczajka.pl>
Fri, 31 Dec 2021 12:54:50 +0000 (13:54 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Fri, 31 Dec 2021 12:54:50 +0000 (13:54 +0100)
src/catalogue/templates/catalogue/search_multiple_hits.html
src/search/mock_search.py
src/search/templatetags/set_get_parameter.py [new file with mode: 0644]
src/search/views.py
src/wolnelektury/static/scss/main/search.scss

index 4a32706..137175d 100644 (file)
@@ -3,12 +3,82 @@
 {% load pagination_tags %}
 {% load inline_tag_list from catalogue_tags %}
 {% load book_searched from search_tags %}
+{% load set_get_parameter %}
 
 {% block titleextra %}{% trans "Search" %}{% endblock %}
 
 {% block bodyid %}tagged-object-list{% endblock %}
 
 {% block body %}
+
+  <h1>{% trans "Search" %}</h1>
+
+  <div class="white-box">
+
+    <p class="search-filter">
+      <strong>format:</strong>
+      {% if not set.format %}<em>dowolny</em>{% else %}<a href="{% set_get_parameter format='' %}">dowolny</a>{% endif %}
+      {% if set.format == "tekst" %}<em>tekst</em>{% else %}<a href="{% set_get_parameter format='tekst' %}">tekst</a>{% endif %}
+      {% if set.format == "audio" %}<em>audiobook</em>{% else %}<a href="{% set_get_parameter format='audio' %}">tekst</a>{% endif %}
+      {% if set.format == "synchro" %}<em>DAISY</em>{% else %}<a href="{% set_get_parameter format='synchro' %}">DAISY</a>{% endif %}
+      {% if set.format == "obraz" %}<em>obraz</em>{% else %}<a href="{% set_get_parameter format='obraz' %}">obraz</a>{% endif %}
+    </p>
+
+    <p class="search-filter">
+      <strong>{% trans "language" %}: </strong>
+      {% if not set.lang %}<em>dowolny</em>{% else %}<a href="{% set_get_parameter lang='' %}">dowolny</a>{% endif %}
+      {% if set.lang == "pol" %}<em>polski</em>{% else %}<a href="{% set_get_parameter lang='pol' %}">polski</a>{% endif %}
+      {% if set.lang == "eng" %}<em>angielski</em>{% else %}<a href="{% set_get_parameter lang='eng' %}">angielski</a>{% endif %}
+      {% if set.lang == "fre" %}<em>francuski</em>{% else %}<a href="{% set_get_parameter lang='fre' %}">francuski</a>{% endif %}
+      {% if set.lang == "ger" %}<em>niemiecki</em>{% else %}<a href="{% set_get_parameter lang='ger' %}">niemiecki</a>{% endif %}
+      {% if set.lang == "lit" %}<em>litewski</em>{% else %}<a href="{% set_get_parameter lang='lit' %}">litewski</a>{% endif %}
+    </p>
+
+    </p>
+    <p class="search-filter">
+      <strong>{% trans "epoch" %}: </strong>
+      {% if not set.epoch %}<em>dowolna</em>{% else %}<a href="{% set_get_parameter epoch='' %}">dowolna</a>{% endif %}
+      {% for tag in tags.epoch %}
+        {% if set.epoch == tag.slug %}
+          <em>{{ tag.name }}</em>
+        {% else %}
+          <a href="{% set_get_parameter epoch=tag.slug %}">
+            {{ tag.name }}
+          </a>
+        {% endif %}
+      {% endfor %}
+    </p>
+    <p class="search-filter">
+      <strong>{% trans "kind" %}: </strong>
+      {% if not set.kind %}<em>dowolny</em>{% else %}<a href="{% set_get_parameter kind='' %}">dowolny</a>{% endif %}
+      {% for tag in tags.kind %}
+        {% if set.kind == tag.slug %}
+          <em>{{ tag.name }}</em>
+        {% else %}
+          <a href="{% set_get_parameter kind=tag.slug %}">
+            {{ tag.name }}
+          </a>
+        {% endif %}
+      {% endfor %}
+    </p>
+
+    {% comment %}
+    <p class="search-filter">
+      <strong>{% trans "genre" %}: </strong>
+      {% if not set.genre %}<em>dowolny</em>{% else %}<a href="{% set_get_parameter genre='' %}">dowolny</a>{% endif %}
+      {% for tag in tags.genre %}
+          {% if set.genre == tag.slug %}
+            <em>{{ tag.name }}</em>
+          {% else %}
+            <a href="{% set_get_parameter genre=tag.slug %}">
+              {{ tag.name }}
+            </a>
+          {% endif %}
+        {% endfor %}
+    </p>
+    {% endcomment %}
+  </div>
+
   {% if did_you_mean %}
     <span class="did_you_mean">{% trans "Did you mean" %}
       <a href="{% url 'search' %}?q={{did_you_mean|urlencode}}">{{did_you_mean|lower}}</a>?</span>
index 118078f..33d2a5e 100644 (file)
@@ -19,10 +19,13 @@ class Search(Mock):
 
     index = MockIndex()
 
-    @staticmethod
-    def _find_some_books(query_terms=None, max_results=20):
+    def search_words(self, words, fields, required=None, book=True, picture=False):
         from .index import SearchResult
 
+        max_results = 20
+        
+        if picture: return []
+
         qs = Book.objects.filter(findable=True).order_by('?')
         results = []
         for book in qs[:randint(1, max_results)]:
@@ -31,10 +34,7 @@ class Search(Mock):
                 'book_id': book.pk,
                 'published_date': randint(1000, 1920),
                 }
-            res = SearchResult(doc, how_found='mock', query_terms=query_terms)
+            res = SearchResult(doc, how_found='mock', query_terms=words)
             results.append(res)
         return results
 
-    def search_everywhere(self, searched, query_terms=None):
-        return []
-
diff --git a/src/search/templatetags/set_get_parameter.py b/src/search/templatetags/set_get_parameter.py
new file mode 100644 (file)
index 0000000..36e2245
--- /dev/null
@@ -0,0 +1,49 @@
+# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
+# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
+#
+from re import split
+
+from django import template
+
+register = template.Library()
+
+
+"""
+In template:
+    {% set_get_paramater param1='const_value',param2=,param3=variable %}
+results with changes to query string:
+    param1 is set to `const_value' string
+    param2 is unset, if exists,
+    param3 is set to the value of variable in context
+
+Using 'django.core.context_processors.request' is required.
+
+"""
+
+
+class SetGetParameter(template.Node):
+    def __init__(self, values):
+        self.values = values
+        
+    def render(self, context):
+        request = template.Variable('request').resolve(context)
+        params = request.GET.copy()
+        for key, value in self.values.items():
+            if value == '':
+                if key in params:
+                    del(params[key])
+            else:
+                params[key] = template.Variable(value).resolve(context)
+        return '?%s' %  params.urlencode()
+
+
+@register.tag
+def set_get_parameter(parser, token):
+    parts = split(r'\s+', token.contents, 2)
+
+    values = {}
+    for pair in parts[1].split(','):
+        s = pair.split('=')
+        values[s[0]] = s[1]
+
+    return SetGetParameter(values)
index da3a767..e06b1cc 100644 (file)
@@ -115,6 +115,13 @@ def hint(request, mozhint=False, param='term'):
 @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:
         return render(
             request, 'catalogue/search_too_short.html',
@@ -125,9 +132,32 @@ def main(request):
             {'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):
@@ -150,10 +180,22 @@ def main(request):
             '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'),
+                'genre': Tag.objects.filter(category='genre'),
+                'kind': Tag.objects.filter(category='kind'),
+            },
         })
 
-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 = []
@@ -185,15 +227,31 @@ def search_books(query):
 
     def ensure_exists(r):
         try:
-            return r.book
+            r.book
         except Book.DoesNotExist:
             return False
 
+        print(lang, r.book.language)
+        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
 
 
-def search_pictures(query):
+def search_pictures(query, epoch=None, kind=None, genre=None):
     search = Search()
     results_parts = []
     search_fields = []
@@ -224,6 +282,13 @@ def search_pictures(query):
         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
+
     results = [r for r in results if ensure_exists(r)]
     return results
 
index 3d992b3..6017d21 100644 (file)
     //@include size(width, 275px);
     line-height: 1.636em;
 }
+
+
+
+
+.search-filter {
+    a {
+        margin-right: 1em;
+    }
+    strong {
+        display: inline-block;
+        width: 5em;
+    }
+    em {
+        margin-right: 1em;
+    }
+        
+}