Filter list search results to hide already added books

This commit is contained in:
Mouse Reeve 2021-04-26 08:02:30 -07:00
parent 0cb80aeb55
commit 0f6b5cc6be
3 changed files with 19 additions and 12 deletions

View file

@ -67,10 +67,12 @@ def search(query, min_confidence=0.1):
return results
def local_search(query, min_confidence=0.1, raw=False):
def local_search(query, min_confidence=0.1, raw=False, filters=None):
""" only look at local search results """
connector = load_connector(models.Connector.objects.get(local=True))
return connector.search(query, min_confidence=min_confidence, raw=raw)
return connector.search(
query, min_confidence=min_confidence, raw=raw, filters=filters
)
def isbn_local_search(query, raw=False):

View file

@ -13,15 +13,16 @@ class Connector(AbstractConnector):
""" instantiate a connector """
# pylint: disable=arguments-differ
def search(self, query, min_confidence=0.1, raw=False):
def search(self, query, min_confidence=0.1, raw=False, filters=None):
""" search your local database """
filters = filters or []
if not query:
return []
# first, try searching unqiue identifiers
results = search_identifiers(query)
results = search_identifiers(query, *filters)
if not results:
# then try searching title/author
results = search_title_author(query, min_confidence)
results = search_title_author(query, min_confidence, *filters)
search_results = []
for result in results:
if raw:
@ -98,15 +99,15 @@ class Connector(AbstractConnector):
pass
def search_identifiers(query):
def search_identifiers(query, *filters):
""" tries remote_id, isbn; defined as dedupe fields on the model """
filters = [
or_filters = [
{f.name: query}
for f in models.Edition._meta.get_fields()
if hasattr(f, "deduplication_field") and f.deduplication_field
]
results = models.Edition.objects.filter(
reduce(operator.or_, (Q(**f) for f in filters))
*filters, reduce(operator.or_, (Q(**f) for f in or_filters))
).distinct()
# when there are multiple editions of the same work, pick the default.
@ -114,7 +115,7 @@ def search_identifiers(query):
return results.filter(parent_work__default_edition__id=F("id")) or results
def search_title_author(query, min_confidence):
def search_title_author(query, min_confidence, *filters):
""" searches for title and author """
vector = (
SearchVector("title", weight="A")
@ -126,7 +127,7 @@ def search_title_author(query, min_confidence):
results = (
models.Edition.objects.annotate(search=vector)
.annotate(rank=SearchRank(vector, query))
.filter(rank__gt=min_confidence)
.filter(*filters, rank__gt=min_confidence)
.order_by("-rank")
)

View file

@ -137,7 +137,11 @@ class List(View):
if query and request.user.is_authenticated:
# search for books
suggestions = connector_manager.local_search(query, raw=True)
suggestions = connector_manager.local_search(
query,
raw=True,
filters=[~Q(parent_work__editions__in=book_list.books.all())],
)
elif request.user.is_authenticated:
# just suggest whatever books are nearby
suggestions = request.user.shelfbook_set.filter(
@ -265,7 +269,7 @@ def add_book(request):
# if the book is already on the list, don't flip out
pass
path = reverse('list', args=[book_list.id])
path = reverse("list", args=[book_list.id])
return redirect("{:s}?{:s}".format(path, urlencode(request.GET)))