From: Radek Czajka Date: Tue, 5 Aug 2025 14:21:15 +0000 (+0200) Subject: Simple search in api X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/aa20c637378d84ac13f7820662792cb69ffe0826?ds=sidebyside;hp=078017198692badda854eb70f7a5431112aed007 Simple search in api --- diff --git a/src/api/urls.py b/src/api/urls.py index 38f619252..5b1942c3a 100644 --- a/src/api/urls.py +++ b/src/api/urls.py @@ -17,7 +17,8 @@ urlpatterns1 = [ path('me/', views.UserView.as_view()), path('', include('catalogue.api.urls2')), path('', include('social.api.urls2')), - path('', include('bookmarks.api.urls')) + path('', include('bookmarks.api.urls')), + path('', include('search.api.urls')), ] diff --git a/src/search/api/urls.py b/src/search/api/urls.py new file mode 100644 index 000000000..93ddf6d90 --- /dev/null +++ b/src/search/api/urls.py @@ -0,0 +1,13 @@ +# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Wolne Lektury. See NOTICE for more information. +# +from django.urls import path +from . import views + + +urlpatterns = [ + path('search/hint/', views.HintView.as_view()), + path('search/', views.SearchView.as_view()), + path('search/books/', views.BookSearchView.as_view()), + path('search/text/', views.TextSearchView.as_view()), +] diff --git a/src/search/api/views.py b/src/search/api/views.py new file mode 100644 index 000000000..1ce66a964 --- /dev/null +++ b/src/search/api/views.py @@ -0,0 +1,33 @@ +# This file is part of Wolne Lektury, licensed under GNU Affero GPLv3 or later. +# Copyright © Fundacja Wolne Lektury. See NOTICE for more information. +# +from rest_framework.generics import ListAPIView +from rest_framework.response import Response +from rest_framework.views import APIView +from search.views import get_hints +from search.forms import SearchFilters + + +class HintView(APIView): + def get(self, request): + term = request.query_params.get('q') + hints = get_hints(term, request.user) + return Response(hints) + + +class SearchView(APIView): + def get(self, request): + term = self.request.query_params.get('q') + f = SearchFilters({'q': term}) + r = {} + if f.is_valid(): + r = f.results() + return Response(r) + +class BookSearchView(ListAPIView): + def get_queryset(self, request): + term = self.request.query_params.get('q') + +class TextSearchView(ListAPIView): + def get_queryset(self, request): + term = self.request.query_params.get('q') diff --git a/src/search/views.py b/src/search/views.py index 459190d28..01abfc526 100644 --- a/src/search/views.py +++ b/src/search/views.py @@ -24,22 +24,8 @@ def remove_query_syntax_chars(query, replace=' '): return query_syntax_chars.sub(replace, query) -@cache.never_cache -def hint(request, mozhint=False, param='term'): - prefix = request.GET.get(param, '') - if len(prefix) < 2: - return JsonResponse([], safe=False) - - prefix = re_escape(' '.join(remove_query_syntax_chars(prefix).split())) - - try: - limit = int(request.GET.get('max', '')) - except ValueError: - limit = 20 - else: - if limit < 1: - limit = 20 - +def get_hints(prefix, user=None, limit=10): + if not prefix: return [] data = [] if len(data) < limit: authors = catalogue.models.Tag.objects.filter( @@ -53,9 +39,10 @@ def hint(request, mozhint=False, param='term'): } for author in authors[:limit - len(data)] ]) - if request.user.is_authenticated and len(data) < limit: + + if user is not None and user.is_authenticated and len(data) < limit: tags = social.models.UserList.objects.filter( - user=request.user, name__iregex='\m' + prefix).only('name', 'id', 'slug') + user=user, name__iregex='\m' + prefix).only('name', 'id', 'slug') data.extend([ { 'type': 'set', @@ -114,6 +101,30 @@ def hint(request, mozhint=False, param='term'): } for info in infos[:limit - len(data)] ]) + return data + + +@cache.never_cache +def hint(request, mozhint=False, param='term'): + prefix = request.GET.get(param, '') + if len(prefix) < 2: + return JsonResponse([], safe=False) + + prefix = re_escape(' '.join(remove_query_syntax_chars(prefix).split())) + + try: + limit = int(request.GET.get('max', '')) + except ValueError: + limit = 20 + else: + if limit < 1: + limit = 20 + + data = get_hints( + prefix, + user=request.user if request.user.is_authenticated else None, + limit=limit + ) if mozhint: data = [