From 4b73c37126fe052bbb4aaf7e80d6e4c679bd5d8b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 30 Apr 2021 18:06:30 -0700 Subject: [PATCH 01/24] Separate out search types --- bookwyrm/views/search.py | 80 ++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index bd5ac3c74..df80603cd 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -18,7 +18,7 @@ from .helpers import handle_remote_webfinger class Search(View): """search users or books""" - def get(self, request): + def get(self, request, search_type=None): """that search bar up top""" query = request.GET.get("q") min_confidence = request.GET.get("min_confidence", 0.1) @@ -30,32 +30,62 @@ class Search(View): ) return JsonResponse([r.json() for r in book_results], safe=False) - data = {"query": query or ""} + data = {"query": query, "type": search_type} + # make a guess about what type of query this is for + if search_type == "user" or (not search_type and "@" in query): + results = user_search(query, request.user) + elif search_type == "list": + results = list_search(query, request.user) + else: + results = book_search(query, min_confidence) + return TemplateResponse(request, "search_results.html", {**data, **results}) - # use webfinger for mastodon style account@domain.com username - if query and re.match(regex.full_username, query): - handle_remote_webfinger(query) - # do a user search - if request.user.is_authenticated: - data["user_results"] = ( - models.User.viewer_aware_objects(request.user) - .annotate( - similarity=Greatest( - TrigramSimilarity("username", query), - TrigramSimilarity("localname", query), - ) +def book_search(query, min_confidence): + """that search bar up top""" + + return { + "query": query or "", + "book_results": connector_manager.search(query, min_confidence=min_confidence), + } + + +def user_search(query, viewer): + """that search bar up top""" + # logged out viewers can't search users + if not viewer.is_authenticated: + return None + + # use webfinger for mastodon style account@domain.com username to load the user if + # they don't exist locally (handle_remote_webfinger will check the db) + if re.match(regex.full_username, query): + handle_remote_webfinger(query) + + return { + "query": query, + "user_results": ( + models.User.viewer_aware_objects(viewer) + .annotate( + similarity=Greatest( + TrigramSimilarity("username", query), + TrigramSimilarity("localname", query), ) - .filter( - similarity__gt=0.5, - ) - .order_by("-similarity")[:10] ) + .filter( + similarity__gt=0.5, + ) + .order_by("-similarity")[:10] + ), + } - # any relevent lists? - data["list_results"] = ( + +def list_search(query, viewer): + """any relevent lists?""" + return { + "query": query, + "list_results": ( privacy_filter( - request.user, + viewer, models.List.objects, privacy_levels=["public", "followers"], ) @@ -69,9 +99,5 @@ class Search(View): similarity__gt=0.1, ) .order_by("-similarity")[:10] - ) - - data["book_results"] = connector_manager.search( - query, min_confidence=min_confidence - ) - return TemplateResponse(request, "search_results.html", data) + ), + } From 5ca9d2a7b0bc233a67b7e210e7a4726a7cb08283 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 30 Apr 2021 18:35:09 -0700 Subject: [PATCH 02/24] Adds search templates --- bookwyrm/templates/search/book.html | 9 ++ bookwyrm/templates/search/layout.html | 59 +++++++++++ bookwyrm/templates/search/list.html | 9 ++ bookwyrm/templates/search/user.html | 9 ++ bookwyrm/templates/search_results.html | 133 ------------------------- bookwyrm/urls.py | 3 +- bookwyrm/views/search.py | 31 +++--- 7 files changed, 107 insertions(+), 146 deletions(-) create mode 100644 bookwyrm/templates/search/book.html create mode 100644 bookwyrm/templates/search/layout.html create mode 100644 bookwyrm/templates/search/list.html create mode 100644 bookwyrm/templates/search/user.html delete mode 100644 bookwyrm/templates/search_results.html diff --git a/bookwyrm/templates/search/book.html b/bookwyrm/templates/search/book.html new file mode 100644 index 000000000..5d66ef901 --- /dev/null +++ b/bookwyrm/templates/search/book.html @@ -0,0 +1,9 @@ +{% extends 'search/layout.html' %} + +{% block panel %} + +{% for result in results %} +hi +{% endfor %} + +{% endblock %} diff --git a/bookwyrm/templates/search/layout.html b/bookwyrm/templates/search/layout.html new file mode 100644 index 000000000..005cda9d9 --- /dev/null +++ b/bookwyrm/templates/search/layout.html @@ -0,0 +1,59 @@ +{% extends 'layout.html' %} +{% load i18n %} + +{% block title %}{% trans "Search" %}{% endblock %} + +{% block content %} +
+

+ {% blocktrans %}Search{% endblocktrans %} +

+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ + + +
+
+ {% block panel %} + {% endblock %} +
+
+{% endblock %} diff --git a/bookwyrm/templates/search/list.html b/bookwyrm/templates/search/list.html new file mode 100644 index 000000000..5d66ef901 --- /dev/null +++ b/bookwyrm/templates/search/list.html @@ -0,0 +1,9 @@ +{% extends 'search/layout.html' %} + +{% block panel %} + +{% for result in results %} +hi +{% endfor %} + +{% endblock %} diff --git a/bookwyrm/templates/search/user.html b/bookwyrm/templates/search/user.html new file mode 100644 index 000000000..5d66ef901 --- /dev/null +++ b/bookwyrm/templates/search/user.html @@ -0,0 +1,9 @@ +{% extends 'search/layout.html' %} + +{% block panel %} + +{% for result in results %} +hi +{% endfor %} + +{% endblock %} diff --git a/bookwyrm/templates/search_results.html b/bookwyrm/templates/search_results.html deleted file mode 100644 index fdb77f728..000000000 --- a/bookwyrm/templates/search_results.html +++ /dev/null @@ -1,133 +0,0 @@ -{% extends 'layout.html' %} -{% load i18n %} - -{% block title %}{% trans "Search Results" %}{% endblock %} - -{% block content %} -{% with book_results|first as local_results %} -
-

{% blocktrans %}Search Results for "{{ query }}"{% endblocktrans %}

-
- -
-
-

{% trans "Matching Books" %}

-
- {% if not local_results.results %} -

{% blocktrans %}No books found for "{{ query }}"{% endblocktrans %}

- {% if not user.is_authenticated %} -

- {% trans "Log in to import or add books." %} -

- {% endif %} - {% else %} -
    - {% for result in local_results.results %} -
  • - {% include 'snippets/search_result_text.html' with result=result %} -
  • - {% endfor %} -
- {% endif %} -
- - {% if request.user.is_authenticated %} - {% if book_results|slice:":1" and local_results.results %} -
-

- {% trans "Didn't find what you were looking for?" %} -

- {% trans "Show results from other catalogues" as button_text %} - {% include 'snippets/toggle/open_button.html' with text=button_text small=True controls_text="more-results" %} - - {% if local_results.results %} - {% trans "Hide results from other catalogues" as button_text %} - {% include 'snippets/toggle/close_button.html' with text=button_text small=True controls_text="more-results" %} - {% endif %} -
- {% endif %} - -
- {% for result_set in book_results|slice:"1:" %} - {% if result_set.results %} -
- {% if not result_set.connector.local %} -
- -
- {% trans "Show" as button_text %} - {% include 'snippets/toggle/open_button.html' with text=button_text small=True controls_text="more-results-panel" controls_uid=result_set.connector.identifier class="is-small" icon="arrow-down" pressed=forloop.first %} -
-
- {% endif %} - -
-
-
- {% trans "Close" as button_text %} - {% include 'snippets/toggle/toggle_button.html' with label=button_text class="delete" nonbutton=True controls_text="more-results-panel" controls_uid=result_set.connector.identifier pressed=forloop.first %} -
- -
    - {% for result in result_set.results %} -
  • - {% include 'snippets/search_result_text.html' with result=result remote_result=True %} -
  • - {% endfor %} -
-
-
-
- {% endif %} - {% endfor %} -
- - - {% endif %} -
-
- {% if request.user.is_authenticated %} -
-

{% trans "Matching Users" %}

- {% if not user_results %} -

{% blocktrans %}No users found for "{{ query }}"{% endblocktrans %}

- {% endif %} - -
- {% endif %} -
-

{% trans "Lists" %}

- {% if not list_results %} -

{% blocktrans %}No lists found for "{{ query }}"{% endblocktrans %}

- {% endif %} - {% for result in list_results %} -
- -
- {% endfor %} -
-
-
-{% endwith %} -{% endblock %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 99e51ff3c..a06e0bd40 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -163,7 +163,8 @@ urlpatterns = [ name="direct-messages-user", ), # search - re_path(r"^search/?$", views.Search.as_view()), + re_path(r"^search/?$", views.Search.as_view(), name="search"), + re_path(r"^search/(?Puser|list|book)/?$", views.Search.as_view(), name="search"), # imports re_path(r"^import/?$", views.Import.as_view()), re_path(r"^import/(\d+)/?$", views.ImportStatus.as_view()), diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index df80603cd..aaca73779 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -30,15 +30,22 @@ class Search(View): ) return JsonResponse([r.json() for r in book_results], safe=False) - data = {"query": query, "type": search_type} - # make a guess about what type of query this is for - if search_type == "user" or (not search_type and "@" in query): - results = user_search(query, request.user) - elif search_type == "list": - results = list_search(query, request.user) - else: - results = book_search(query, min_confidence) - return TemplateResponse(request, "search_results.html", {**data, **results}) + data = {"query": query or "", "type": search_type} + results = {} + if query: + # make a guess about what type of query this is for + if search_type == "user" or (not search_type and "@" in query): + results = user_search(query, request.user) + elif search_type == "list": + results = list_search(query, request.user) + else: + results = book_search(query, min_confidence) + + return TemplateResponse( + request, + "search/{:s}.html".format(search_type or "book"), + {**data, **results} + ) def book_search(query, min_confidence): @@ -46,7 +53,7 @@ def book_search(query, min_confidence): return { "query": query or "", - "book_results": connector_manager.search(query, min_confidence=min_confidence), + "results": connector_manager.search(query, min_confidence=min_confidence), } @@ -63,7 +70,7 @@ def user_search(query, viewer): return { "query": query, - "user_results": ( + "results": ( models.User.viewer_aware_objects(viewer) .annotate( similarity=Greatest( @@ -83,7 +90,7 @@ def list_search(query, viewer): """any relevent lists?""" return { "query": query, - "list_results": ( + "results": ( privacy_filter( viewer, models.List.objects, From 21a5147c3c523f57c945bc64efc2311dfda4472a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 30 Apr 2021 18:59:02 -0700 Subject: [PATCH 03/24] Controls search type --- bookwyrm/templates/search/layout.html | 36 ++++++++++++------------ bookwyrm/templates/search/list.html | 4 +-- bookwyrm/urls.py | 1 - bookwyrm/views/search.py | 40 +++++++++++++-------------- 4 files changed, 39 insertions(+), 42 deletions(-) diff --git a/bookwyrm/templates/search/layout.html b/bookwyrm/templates/search/layout.html index 005cda9d9..da0f651af 100644 --- a/bookwyrm/templates/search/layout.html +++ b/bookwyrm/templates/search/layout.html @@ -10,14 +10,14 @@ -
+
- +
- @@ -35,25 +35,25 @@ -
-
- {% block panel %} - {% endblock %} -
-
+
+ {% block panel %} + {% endblock %} + {% if not results %} +

+ {% blocktrans %}No results found for "{{ query }}"{% endblocktrans %} +

+ {% endif %} +
{% endblock %} diff --git a/bookwyrm/templates/search/list.html b/bookwyrm/templates/search/list.html index 5d66ef901..d7e48f51c 100644 --- a/bookwyrm/templates/search/list.html +++ b/bookwyrm/templates/search/list.html @@ -2,8 +2,6 @@ {% block panel %} -{% for result in results %} -hi -{% endfor %} +{% include 'lists/list_items.html' with lists=results %} {% endblock %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index a06e0bd40..5412378e6 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -164,7 +164,6 @@ urlpatterns = [ ), # search re_path(r"^search/?$", views.Search.as_view(), name="search"), - re_path(r"^search/(?Puser|list|book)/?$", views.Search.as_view(), name="search"), # imports re_path(r"^import/?$", views.Import.as_view()), re_path(r"^import/(\d+)/?$", views.ImportStatus.as_view()), diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index aaca73779..cfbc1f0ba 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -18,10 +18,11 @@ from .helpers import handle_remote_webfinger class Search(View): """search users or books""" - def get(self, request, search_type=None): + def get(self, request): """that search bar up top""" query = request.GET.get("q") min_confidence = request.GET.get("min_confidence", 0.1) + search_type = request.GET.get("type") if is_api_request(request): # only return local book results via json so we don't cascade @@ -30,38 +31,39 @@ class Search(View): ) return JsonResponse([r.json() for r in book_results], safe=False) + if not search_type: + search_type = "user" if "@" in query else "book" + + endpoints = { + "book": book_search, + "user": user_search, + "list": list_search, + } + if not search_type in endpoints: + search_type = "book" + endpoint = endpoints[search_type] + data = {"query": query or "", "type": search_type} - results = {} - if query: - # make a guess about what type of query this is for - if search_type == "user" or (not search_type and "@" in query): - results = user_search(query, request.user) - elif search_type == "list": - results = list_search(query, request.user) - else: - results = book_search(query, min_confidence) + results = endpoint(query, request.user, min_confidence) if query else {} return TemplateResponse( - request, - "search/{:s}.html".format(search_type or "book"), - {**data, **results} + request, "search/{:s}.html".format(search_type), {**data, **results} ) -def book_search(query, min_confidence): +def book_search(query, _, min_confidence): """that search bar up top""" return { - "query": query or "", "results": connector_manager.search(query, min_confidence=min_confidence), } -def user_search(query, viewer): +def user_search(query, viewer, _): """that search bar up top""" # logged out viewers can't search users if not viewer.is_authenticated: - return None + return {} # use webfinger for mastodon style account@domain.com username to load the user if # they don't exist locally (handle_remote_webfinger will check the db) @@ -69,7 +71,6 @@ def user_search(query, viewer): handle_remote_webfinger(query) return { - "query": query, "results": ( models.User.viewer_aware_objects(viewer) .annotate( @@ -86,10 +87,9 @@ def user_search(query, viewer): } -def list_search(query, viewer): +def list_search(query, viewer, _): """any relevent lists?""" return { - "query": query, "results": ( privacy_filter( viewer, From cb6c0035d7ee97ee531894e6227df22fffbb7700 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 30 Apr 2021 19:19:10 -0700 Subject: [PATCH 04/24] List and user previews --- bookwyrm/templates/directory/directory.html | 56 +-------------- bookwyrm/templates/directory/user_card.html | 57 +++++++++++++++ bookwyrm/templates/search/layout.html | 3 + bookwyrm/templates/search/user.html | 9 ++- bookwyrm/views/search.py | 80 ++++++++++----------- 5 files changed, 105 insertions(+), 100 deletions(-) create mode 100644 bookwyrm/templates/directory/user_card.html diff --git a/bookwyrm/templates/directory/directory.html b/bookwyrm/templates/directory/directory.html index 2fa8a5aea..f97a84814 100644 --- a/bookwyrm/templates/directory/directory.html +++ b/bookwyrm/templates/directory/directory.html @@ -1,7 +1,5 @@ {% extends 'layout.html' %} {% load i18n %} -{% load bookwyrm_tags %} -{% load humanize %} {% block title %}{% trans "Directory" %}{% endblock %} @@ -41,59 +39,7 @@
{% for user in users %}
-
-
- - -
- {% if user.summary %} - {{ user.summary | to_markdown | safe | truncatechars_html:40 }} - {% else %} {% endif %} -
-
-
- {% if user != request.user %} - {% if user.mutuals %} - - {% elif user.shared_books %} - - {% endif %} - {% endif %} - - -
-
+ {% include 'directory/user_card.html' %}
{% endfor %}
diff --git a/bookwyrm/templates/directory/user_card.html b/bookwyrm/templates/directory/user_card.html new file mode 100644 index 000000000..8e7538c89 --- /dev/null +++ b/bookwyrm/templates/directory/user_card.html @@ -0,0 +1,57 @@ +{% load i18n %} +{% load bookwyrm_tags %} +{% load humanize %} + +
+
+ + +
+ {% if user.summary %} + {{ user.summary | to_markdown | safe | truncatechars_html:40 }} + {% else %} {% endif %} +
+
+
+ {% if user != request.user %} + {% if user.mutuals %} + + {% elif user.shared_books %} + + {% endif %} + {% endif %} + + +
+
diff --git a/bookwyrm/templates/search/layout.html b/bookwyrm/templates/search/layout.html index da0f651af..b122d7e25 100644 --- a/bookwyrm/templates/search/layout.html +++ b/bookwyrm/templates/search/layout.html @@ -33,6 +33,7 @@
+{% if query %}
- {% block panel %} - {% endblock %} {% if not results %}

{% blocktrans %}No results found for "{{ query }}"{% endblocktrans %}

{% endif %} + {% block panel %} + {% endblock %}
{% endif %} diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index 603ed2117..9fa07e2ed 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -23,6 +23,7 @@ class Search(View): query = request.GET.get("q") min_confidence = request.GET.get("min_confidence", 0.1) search_type = request.GET.get("type") + search_remote = request.GET.get("remote", False) if is_api_request(request): # only return local book results via json so we don't cascade @@ -41,23 +42,31 @@ class Search(View): } if not search_type in endpoints: search_type = "book" - endpoint = endpoints[search_type] data = { "query": query or "", "type": search_type, - "results": endpoint(query, request.user, min_confidence) if query else {}, + "remote": search_remote, } + if query: + data["results"] = endpoints[search_type]( + query, request.user, min_confidence, search_remote + ) return TemplateResponse(request, "search/{:s}.html".format(search_type), data) -def book_search(query, _, min_confidence): +def book_search(query, _, min_confidence, search_remote=False): """the real business is elsewhere""" - return connector_manager.search(query, min_confidence=min_confidence) + if search_remote: + return connector_manager.search(query, min_confidence=min_confidence) + results = connector_manager.local_search(query, min_confidence=min_confidence) + if not results: + return None + return [{"results": results}] -def user_search(query, viewer, _): +def user_search(query, viewer, *_): """cool kids members only user search""" # logged out viewers can't search users if not viewer.is_authenticated: @@ -83,7 +92,7 @@ def user_search(query, viewer, _): ) -def list_search(query, viewer, _): +def list_search(query, viewer, *_): """any relevent lists?""" return ( privacy_filter( From 9caad56ffcfc1d900163df1b3f50b4d5e0081bdc Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 30 Apr 2021 20:08:05 -0700 Subject: [PATCH 06/24] Don't allow remote search results for logged out users --- bookwyrm/views/search.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index 9fa07e2ed..c216170da 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -23,7 +23,9 @@ class Search(View): query = request.GET.get("q") min_confidence = request.GET.get("min_confidence", 0.1) search_type = request.GET.get("type") - search_remote = request.GET.get("remote", False) + search_remote = ( + request.GET.get("remote", False) and request.user.is_authenticated + ) if is_api_request(request): # only return local book results via json so we don't cascade From 5f7191a976331fea2bc8cd16db17126bd0c175db Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 30 Apr 2021 20:09:43 -0700 Subject: [PATCH 07/24] Safer logged out search --- bookwyrm/templates/search/layout.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bookwyrm/templates/search/layout.html b/bookwyrm/templates/search/layout.html index 17e14f0fe..8c81f5b75 100644 --- a/bookwyrm/templates/search/layout.html +++ b/bookwyrm/templates/search/layout.html @@ -19,7 +19,9 @@
From f9c1ecfabed82ee1da0c116d3d8e31304e3174dc Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 30 Apr 2021 20:16:34 -0700 Subject: [PATCH 08/24] Fixes bad whitespace --- bookwyrm/templates/search/book.html | 60 ++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/bookwyrm/templates/search/book.html b/bookwyrm/templates/search/book.html index 9d42dd7f2..53aadb63e 100644 --- a/bookwyrm/templates/search/book.html +++ b/bookwyrm/templates/search/book.html @@ -8,7 +8,7 @@
    {% for result in local_results.results %}
  • - {% include 'snippets/search_result_text.html' with result=result %} + {% include 'snippets/search_result_text.html' with result=result %}
  • {% endfor %}
@@ -18,37 +18,37 @@ {% for result_set in results|slice:"1:" %} {% if result_set.results %}
- {% if not result_set.connector.local %} -
- -
- {% trans "Show" as button_text %} - {% include 'snippets/toggle/open_button.html' with text=button_text small=True controls_text="more-results-panel" controls_uid=result_set.connector.identifier class="is-small" icon="arrow-down" pressed=forloop.first %} -
-
- {% endif %} + {% if not result_set.connector.local %} +
+ +
+ {% trans "Show" as button_text %} + {% include 'snippets/toggle/open_button.html' with text=button_text small=True controls_text="more-results-panel" controls_uid=result_set.connector.identifier class="is-small" icon="arrow-down" pressed=forloop.first %} +
+
+ {% endif %} -
-
-
- {% trans "Close" as button_text %} - {% include 'snippets/toggle/toggle_button.html' with label=button_text class="delete" nonbutton=True controls_text="more-results-panel" controls_uid=result_set.connector.identifier pressed=forloop.first %} -
+
+
+
+ {% trans "Close" as button_text %} + {% include 'snippets/toggle/toggle_button.html' with label=button_text class="delete" nonbutton=True controls_text="more-results-panel" controls_uid=result_set.connector.identifier pressed=forloop.first %} +
-
    - {% for result in result_set.results %} -
  • - {% include 'snippets/search_result_text.html' with result=result remote_result=True %} -
  • - {% endfor %} -
-
-
+
    + {% for result in result_set.results %} +
  • + {% include 'snippets/search_result_text.html' with result=result remote_result=True %} +
  • + {% endfor %} +
+
+
{% endif %} {% endfor %} From 64b54510d9270f78e2b267e87525937d7d269254 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 1 May 2021 10:39:05 -0700 Subject: [PATCH 09/24] Updates unit tests --- bookwyrm/tests/views/test_search.py | 47 +++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/bookwyrm/tests/views/test_search.py b/bookwyrm/tests/views/test_search.py index 777275222..7661d5a6f 100644 --- a/bookwyrm/tests/views/test_search.py +++ b/bookwyrm/tests/views/test_search.py @@ -2,6 +2,7 @@ import json from unittest.mock import patch +from django.contrib.auth.models import AnonymousUser from django.http import JsonResponse from django.template.response import TemplateResponse from django.test import TestCase @@ -52,7 +53,7 @@ class ShelfViews(TestCase): self.assertEqual(data[0]["title"], "Test Book") self.assertEqual(data[0]["key"], "https://%s/book/%d" % (DOMAIN, self.book.id)) - def test_search_html_response(self): + def test_search_books(self): """searches remote connectors""" view = views.Search.as_view() @@ -92,7 +93,7 @@ class ShelfViews(TestCase): connector=connector, ) - request = self.factory.get("", {"q": "Test Book"}) + request = self.factory.get("", {"q": "Test Book", "remote": True}) request.user = self.local_user with patch("bookwyrm.views.search.is_api_request") as is_api: is_api.return_value = False @@ -101,19 +102,41 @@ class ShelfViews(TestCase): response = view(request) self.assertIsInstance(response, TemplateResponse) response.render() - self.assertEqual( - response.context_data["book_results"][0].title, "Gideon the Ninth" - ) + self.assertEqual(response.context_data["results"][0].title, "Gideon the Ninth") - def test_search_html_response_users(self): + def test_search_users(self): """searches remote connectors""" view = views.Search.as_view() - request = self.factory.get("", {"q": "mouse"}) + request = self.factory.get("", {"q": "mouse", "type": "user"}) request.user = self.local_user - with patch("bookwyrm.views.search.is_api_request") as is_api: - is_api.return_value = False - with patch("bookwyrm.connectors.connector_manager.search"): - response = view(request) + response = view(request) + self.assertIsInstance(response, TemplateResponse) response.render() - self.assertEqual(response.context_data["user_results"][0], self.local_user) + self.assertEqual(response.context_data["results"][0], self.local_user) + + def test_search_users_logged_out(self): + """searches remote connectors""" + view = views.Search.as_view() + request = self.factory.get("", {"q": "mouse", "type": "user"}) + + anonymous_user = AnonymousUser + anonymous_user.is_authenticated = False + request.user = anonymous_user + + response = view(request) + + response.render() + self.assertEqual(response.context_data["results"], {}) + + def test_search_lists(self): + """searches remote connectors""" + booklist = models.List.objects.create(user=self.local_user, name="test list") + view = views.Search.as_view() + request = self.factory.get("", {"q": "test", "type": "list"}) + request.user = self.local_user + response = view(request) + + self.assertIsInstance(response, TemplateResponse) + response.render() + self.assertEqual(response.context_data["results"][0], booklist) From c42be7a5892e4502355d707ec4c6b5b742cd331a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 1 May 2021 10:47:01 -0700 Subject: [PATCH 10/24] Adds pagination --- bookwyrm/templates/search/layout.html | 4 ++++ bookwyrm/views/search.py | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/bookwyrm/templates/search/layout.html b/bookwyrm/templates/search/layout.html index 8c81f5b75..00b49b93b 100644 --- a/bookwyrm/templates/search/layout.html +++ b/bookwyrm/templates/search/layout.html @@ -60,6 +60,10 @@ {% endif %} {% block panel %} {% endblock %} + +
+ {% include 'snippets/pagination.html' with page=results path=request.path %} +
{% endif %} diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index c216170da..ebaa937c7 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -2,6 +2,7 @@ import re from django.contrib.postgres.search import TrigramSimilarity +from django.core.paginator import Paginator from django.db.models.functions import Greatest from django.http import JsonResponse from django.template.response import TemplateResponse @@ -9,6 +10,7 @@ from django.views import View from bookwyrm import models from bookwyrm.connectors import connector_manager +from bookwyrm.settings import PAGE_LENGTH from bookwyrm.utils import regex from .helpers import is_api_request, privacy_filter from .helpers import handle_remote_webfinger @@ -51,9 +53,11 @@ class Search(View): "remote": search_remote, } if query: - data["results"] = endpoints[search_type]( + results = endpoints[search_type]( query, request.user, min_confidence, search_remote ) + paginated = Paginator(results, PAGE_LENGTH).get_page(request.GET.get("page")) + data["results"] = paginated return TemplateResponse(request, "search/{:s}.html".format(search_type), data) From bb50bd8121cd857f483b46134161da989eab1c57 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 1 May 2021 10:49:34 -0700 Subject: [PATCH 11/24] Python formatting --- bookwyrm/views/search.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index ebaa937c7..b76f23929 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -56,7 +56,9 @@ class Search(View): results = endpoints[search_type]( query, request.user, min_confidence, search_remote ) - paginated = Paginator(results, PAGE_LENGTH).get_page(request.GET.get("page")) + paginated = Paginator(results, PAGE_LENGTH).get_page( + request.GET.get("page") + ) data["results"] = paginated return TemplateResponse(request, "search/{:s}.html".format(search_type), data) From 037362e49fa13d6f66755bad51a49d5f6184697d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 1 May 2021 10:55:10 -0700 Subject: [PATCH 12/24] Adds labels for form elements --- bookwyrm/templates/search/layout.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bookwyrm/templates/search/layout.html b/bookwyrm/templates/search/layout.html index 00b49b93b..239586efa 100644 --- a/bookwyrm/templates/search/layout.html +++ b/bookwyrm/templates/search/layout.html @@ -13,10 +13,10 @@
- +
-
+