From 0f6b5cc6be4ea11014322aa206bdc217f751405e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 26 Apr 2021 08:02:30 -0700 Subject: [PATCH] Filter list search results to hide already added books --- bookwyrm/connectors/connector_manager.py | 6 ++++-- bookwyrm/connectors/self_connector.py | 17 +++++++++-------- bookwyrm/views/list.py | 8 ++++++-- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/bookwyrm/connectors/connector_manager.py b/bookwyrm/connectors/connector_manager.py index 53198c0a..e9998906 100644 --- a/bookwyrm/connectors/connector_manager.py +++ b/bookwyrm/connectors/connector_manager.py @@ -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): diff --git a/bookwyrm/connectors/self_connector.py b/bookwyrm/connectors/self_connector.py index 500ffd74..66560f21 100644 --- a/bookwyrm/connectors/self_connector.py +++ b/bookwyrm/connectors/self_connector.py @@ -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") ) diff --git a/bookwyrm/views/list.py b/bookwyrm/views/list.py index fe7bba54..748f2b8b 100644 --- a/bookwyrm/views/list.py +++ b/bookwyrm/views/list.py @@ -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)))