1 # This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
4 from django.conf import settings
5 from django.shortcuts import render
6 from django.views.decorators import cache
7 from django.http import HttpResponse, JsonResponse
8 from sorl.thumbnail import get_thumbnail
10 import catalogue.models
11 import infopages.models
12 from .forms import SearchFilters
16 from wolnelektury.utils import re_escape
19 query_syntax_chars = re.compile(r"[\\/*:(){}?.[\]+]")
22 def remove_query_syntax_chars(query, replace=' '):
23 return query_syntax_chars.sub(replace, query)
27 def hint(request, mozhint=False, param='term'):
28 prefix = request.GET.get(param, '')
30 return JsonResponse([], safe=False)
32 prefix = re_escape(' '.join(remove_query_syntax_chars(prefix).split()))
35 limit = int(request.GET.get('max', ''))
44 authors = catalogue.models.Tag.objects.filter(
45 category='author', name_pl__iregex='\m' + prefix).only('name', 'id', 'slug', 'category')
50 'url': author.get_absolute_url(),
51 'img': get_thumbnail(author.photo, '72x72', crop='top').url if author.photo else '',
53 for author in authors[:limit - len(data)]
55 if request.user.is_authenticated and len(data) < limit:
56 tags = catalogue.models.Tag.objects.filter(
57 category='set', user=request.user, name_pl__iregex='\m' + prefix).only('name', 'id', 'slug', 'category')
62 'url': tag.get_absolute_url(),
64 for tag in tags[:limit - len(data)]
67 tags = catalogue.models.Tag.objects.filter(
68 category__in=('theme', 'genre', 'epoch', 'kind'), name_pl__iregex='\m' + prefix).only('name', 'id', 'slug', 'category')
73 'url': tag.get_absolute_url(),
75 for tag in tags[:limit - len(data)]
78 collections = catalogue.models.Collection.objects.filter(
79 title_pl__iregex='\m' + prefix).only('title', 'slug')
83 'label': collection.title,
84 'url': collection.get_absolute_url(),
86 for collection in collections[:limit - len(data)]
89 for b in catalogue.models.Book.objects.filter(findable=True, title__iregex='\m' + prefix)[:limit-len(data)]:
90 author_str = b.author_unicode()
91 translator = b.translator()
93 author_str += ' (tłum. ' + translator + ')'
99 'url': b.get_absolute_url(),
100 'img': get_thumbnail(b.cover_clean, '72x72').url if b.cover_clean else '',
103 if len(data) < limit:
104 infos = infopages.models.InfoPage.objects.filter(
107 title_pl__iregex='\m' + prefix).only('title', 'id', 'slug')
112 'url': info.get_absolute_url(),
114 for info in infos[:limit - len(data)]
125 item.get('author', '')
134 callback = request.GET.get('callback', None)
136 return HttpResponse("%s(%s);" % (callback, json.dumps(data)),
137 content_type="application/json; charset=utf-8")
139 return JsonResponse(data, safe=False)
145 filters = SearchFilters(request.GET)
147 'title': 'Wynik wyszukiwania',
148 'query': request.GET.get('q', ''),
151 if filters.is_valid():
152 ctx['results'] = filters.results()
153 for k, v in ctx['results'].items():
155 ctx['hasresults'] = True
157 return render(request, 'search/results.html', ctx)