1 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. 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
13 from .forms import SearchFilters
17 from wolnelektury.utils import re_escape
20 query_syntax_chars = re.compile(r"[\\/*:(){}?.[\]+]")
23 def remove_query_syntax_chars(query, replace=' '):
24 return query_syntax_chars.sub(replace, query)
28 def hint(request, mozhint=False, param='term'):
29 prefix = request.GET.get(param, '')
31 return JsonResponse([], safe=False)
33 prefix = re_escape(' '.join(remove_query_syntax_chars(prefix).split()))
36 limit = int(request.GET.get('max', ''))
45 authors = catalogue.models.Tag.objects.filter(
46 category='author', name_pl__iregex='\m' + prefix).only('name', 'id', 'slug', 'category')
51 'url': author.get_absolute_gallery_url() if author.for_pictures else author.get_absolute_url(),
52 'img': get_thumbnail(author.photo, '72x72', crop='top').url if author.photo else '',
54 for author in authors[:limit - len(data)]
56 if request.user.is_authenticated and len(data) < limit:
57 tags = catalogue.models.Tag.objects.filter(
58 category='set', user=request.user, name_pl__iregex='\m' + prefix).only('name', 'id', 'slug', 'category')
63 'url': tag.get_absolute_url(),
65 for tag in tags[:limit - len(data)]
68 tags = catalogue.models.Tag.objects.filter(
69 category__in=('theme', 'genre', 'epoch', 'kind'), name_pl__iregex='\m' + prefix).only('name', 'id', 'slug', 'category')
74 'url': tag.get_absolute_gallery_url() if tag.for_pictures else tag.get_absolute_url(),
76 for tag in tags[:limit - len(data)]
79 collections = catalogue.models.Collection.objects.filter(
80 title_pl__iregex='\m' + prefix).only('title', 'slug')
84 'label': collection.title,
85 'url': collection.get_absolute_url(),
87 for collection in collections[:limit - len(data)]
90 for b in catalogue.models.Book.objects.filter(findable=True, title__iregex='\m' + prefix)[:limit-len(data)]:
91 author_str = b.author_unicode()
92 translator = b.translator()
94 author_str += ' (tłum. ' + translator + ')'
100 'url': b.get_absolute_url(),
101 'img': get_thumbnail(b.cover_clean, '72x72').url if b.cover_clean else '',
104 if len(data) < limit:
105 arts = picture.models.Picture.objects.filter(
106 title__iregex='\m' + prefix).only('title', 'id', 'slug') # img?
111 'author': art.author_unicode(),
112 'url': art.get_absolute_url(),
113 'img': get_thumbnail(art.image_file, '72x72').url if art.image_file else '',
115 for art in arts[:limit - len(data)]
117 if len(data) < limit:
118 infos = infopages.models.InfoPage.objects.filter(
119 title_pl__iregex='\m' + prefix).only('title', 'id', 'slug')
124 'url': info.get_absolute_url(),
126 for info in infos[:limit - len(data)]
138 callback = request.GET.get('callback', None)
140 return HttpResponse("%s(%s);" % (callback, json.dumps(data)),
141 content_type="application/json; charset=utf-8")
143 return JsonResponse(data, safe=False)
149 filters = SearchFilters(request.GET)
151 'title': 'Wynik wyszukiwania',
152 'query': request.GET.get('q', ''),
155 if filters.is_valid():
156 ctx['results'] = filters.results()
157 for k, v in ctx['results'].items():
159 ctx['hasresults'] = True
161 return render(request, 'search/results.html', ctx)