2021-03-08 16:49:10 +00:00
|
|
|
""" search views"""
|
2021-01-13 20:03:27 +00:00
|
|
|
import re
|
|
|
|
|
|
|
|
from django.contrib.postgres.search import TrigramSimilarity
|
|
|
|
from django.db.models.functions import Greatest
|
|
|
|
from django.http import JsonResponse
|
|
|
|
from django.template.response import TemplateResponse
|
|
|
|
from django.views import View
|
|
|
|
|
|
|
|
from bookwyrm import models
|
|
|
|
from bookwyrm.connectors import connector_manager
|
|
|
|
from bookwyrm.utils import regex
|
2021-02-01 19:50:47 +00:00
|
|
|
from .helpers import is_api_request, privacy_filter
|
2021-01-13 20:03:27 +00:00
|
|
|
from .helpers import handle_remote_webfinger
|
|
|
|
|
|
|
|
|
|
|
|
# pylint: disable= no-self-use
|
|
|
|
class Search(View):
|
2021-03-08 16:49:10 +00:00
|
|
|
""" search users or books """
|
|
|
|
|
2021-01-13 20:03:27 +00:00
|
|
|
def get(self, request):
|
2021-03-08 16:49:10 +00:00
|
|
|
""" that search bar up top """
|
|
|
|
query = request.GET.get("q")
|
|
|
|
min_confidence = request.GET.get("min_confidence", 0.1)
|
2021-01-13 20:03:27 +00:00
|
|
|
|
|
|
|
if is_api_request(request):
|
|
|
|
# only return local book results via json so we don't cascade
|
|
|
|
book_results = connector_manager.local_search(
|
2021-03-08 16:49:10 +00:00
|
|
|
query, min_confidence=min_confidence
|
|
|
|
)
|
2021-01-13 20:03:27 +00:00
|
|
|
return JsonResponse([r.json() for r in book_results], safe=False)
|
|
|
|
|
|
|
|
# use webfinger for mastodon style account@domain.com username
|
2021-03-08 16:49:10 +00:00
|
|
|
if re.match(r"\B%s" % regex.full_username, query):
|
2021-01-13 20:03:27 +00:00
|
|
|
handle_remote_webfinger(query)
|
|
|
|
|
2021-02-01 19:50:47 +00:00
|
|
|
# do a user search
|
2021-03-08 16:49:10 +00:00
|
|
|
user_results = (
|
|
|
|
models.User.viewer_aware_objects(request.user)
|
|
|
|
.annotate(
|
|
|
|
similarity=Greatest(
|
|
|
|
TrigramSimilarity("username", query),
|
|
|
|
TrigramSimilarity("localname", query),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.filter(
|
|
|
|
similarity__gt=0.5,
|
2021-01-13 20:03:27 +00:00
|
|
|
)
|
2021-03-08 16:49:10 +00:00
|
|
|
.order_by("-similarity")[:10]
|
|
|
|
)
|
2021-01-13 20:03:27 +00:00
|
|
|
|
2021-02-01 19:50:47 +00:00
|
|
|
# any relevent lists?
|
2021-03-08 16:49:10 +00:00
|
|
|
list_results = (
|
|
|
|
privacy_filter(
|
|
|
|
request.user,
|
|
|
|
models.List.objects,
|
|
|
|
privacy_levels=["public", "followers"],
|
|
|
|
)
|
|
|
|
.annotate(
|
|
|
|
similarity=Greatest(
|
|
|
|
TrigramSimilarity("name", query),
|
|
|
|
TrigramSimilarity("description", query),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
.filter(
|
|
|
|
similarity__gt=0.1,
|
2021-02-01 19:50:47 +00:00
|
|
|
)
|
2021-03-08 16:49:10 +00:00
|
|
|
.order_by("-similarity")[:10]
|
|
|
|
)
|
2021-02-01 19:50:47 +00:00
|
|
|
|
2021-03-08 16:49:10 +00:00
|
|
|
book_results = connector_manager.search(query, min_confidence=min_confidence)
|
2021-01-13 20:03:27 +00:00
|
|
|
data = {
|
2021-03-08 16:49:10 +00:00
|
|
|
"book_results": book_results,
|
|
|
|
"user_results": user_results,
|
|
|
|
"list_results": list_results,
|
|
|
|
"query": query,
|
2021-01-13 20:03:27 +00:00
|
|
|
}
|
2021-03-08 16:49:10 +00:00
|
|
|
return TemplateResponse(request, "search_results.html", data)
|