2020-02-22 17:02:03 -05:00
|
|
|
''' views for pages you can go to in the application '''
|
2020-05-04 00:13:43 -04:00
|
|
|
import re
|
|
|
|
|
2020-10-14 13:04:03 -04:00
|
|
|
from django.contrib.postgres.search import TrigramSimilarity
|
2021-01-03 10:48:57 -05:00
|
|
|
from django.db.models.functions import Greatest
|
2021-01-13 14:45:08 -05:00
|
|
|
from django.http import JsonResponse
|
2020-01-25 18:25:19 -05:00
|
|
|
from django.template.response import TemplateResponse
|
2020-11-28 11:22:25 -05:00
|
|
|
from django.views.decorators.http import require_GET
|
2020-01-25 01:32:41 -05:00
|
|
|
|
2020-09-21 11:10:37 -04:00
|
|
|
from bookwyrm import outgoing
|
2021-01-13 12:54:35 -05:00
|
|
|
from bookwyrm import models
|
2021-01-02 11:14:28 -05:00
|
|
|
from bookwyrm.connectors import connector_manager
|
2020-11-01 13:42:48 -05:00
|
|
|
from bookwyrm.utils import regex
|
2020-01-28 14:45:27 -05:00
|
|
|
|
2020-02-22 17:02:03 -05:00
|
|
|
|
2020-03-13 20:57:36 -04:00
|
|
|
def is_api_request(request):
|
|
|
|
''' check whether a request is asking for html or data '''
|
|
|
|
return 'json' in request.headers.get('Accept') or \
|
|
|
|
request.path[-5:] == '.json'
|
|
|
|
|
2020-03-29 19:05:33 -04:00
|
|
|
def server_error_page(request):
|
|
|
|
''' 500 errors '''
|
2020-12-30 14:42:07 -05:00
|
|
|
return TemplateResponse(
|
|
|
|
request, 'error.html', {'title': 'Oops!'}, status=500)
|
2020-03-29 19:05:33 -04:00
|
|
|
|
|
|
|
|
|
|
|
def not_found_page(request, _):
|
|
|
|
''' 404s '''
|
2020-12-30 14:42:07 -05:00
|
|
|
return TemplateResponse(
|
|
|
|
request, 'notfound.html', {'title': 'Not found'}, status=404)
|
2020-03-29 19:05:33 -04:00
|
|
|
|
|
|
|
|
2020-11-28 11:22:25 -05:00
|
|
|
@require_GET
|
2020-05-04 00:13:43 -04:00
|
|
|
def search(request):
|
|
|
|
''' that search bar up top '''
|
|
|
|
query = request.GET.get('q')
|
2021-01-07 12:26:05 -05:00
|
|
|
min_confidence = request.GET.get('min_confidence', 0.1)
|
2020-05-04 13:15:41 -04:00
|
|
|
|
|
|
|
if is_api_request(request):
|
2020-10-14 12:19:23 -04:00
|
|
|
# only return local book results via json so we don't cause a cascade
|
2021-01-07 12:26:05 -05:00
|
|
|
book_results = connector_manager.local_search(
|
|
|
|
query, min_confidence=min_confidence)
|
2020-12-30 14:37:26 -05:00
|
|
|
return JsonResponse([r.json() for r in book_results], safe=False)
|
2020-05-04 00:13:43 -04:00
|
|
|
|
2020-11-11 01:06:06 -05:00
|
|
|
# use webfinger for mastodon style account@domain.com username
|
2021-01-06 19:01:13 -05:00
|
|
|
if re.match(r'\B%s' % regex.full_username, query):
|
2020-10-14 12:54:07 -04:00
|
|
|
outgoing.handle_remote_webfinger(query)
|
|
|
|
|
|
|
|
# do a local user search
|
|
|
|
user_results = models.User.objects.annotate(
|
2021-01-03 10:48:57 -05:00
|
|
|
similarity=Greatest(
|
|
|
|
TrigramSimilarity('username', query),
|
|
|
|
TrigramSimilarity('localname', query),
|
|
|
|
)
|
2020-10-14 12:54:07 -04:00
|
|
|
).filter(
|
2020-11-11 01:06:06 -05:00
|
|
|
similarity__gt=0.5,
|
2020-10-14 13:04:03 -04:00
|
|
|
).order_by('-similarity')[:10]
|
2020-10-14 12:19:23 -04:00
|
|
|
|
2021-01-07 12:26:05 -05:00
|
|
|
book_results = connector_manager.search(
|
|
|
|
query, min_confidence=min_confidence)
|
2020-10-14 12:19:23 -04:00
|
|
|
data = {
|
2020-11-02 17:25:16 -05:00
|
|
|
'title': 'Search Results',
|
2020-10-14 12:19:23 -04:00
|
|
|
'book_results': book_results,
|
|
|
|
'user_results': user_results,
|
|
|
|
'query': query,
|
|
|
|
}
|
|
|
|
return TemplateResponse(request, 'search_results.html', data)
|