Merge pull request #233 from mouse-reeve/search-results-page

Search results page
This commit is contained in:
Mouse Reeve 2020-10-14 10:06:36 -07:00 committed by GitHub
commit cdf23fce31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 22 deletions

View file

@ -0,0 +1,15 @@
# Generated by Django 3.0.7 on 2020-10-14 17:00
from django.contrib.postgres.operations import TrigramExtension
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('bookwyrm', '0052_auto_20201005_2145'),
]
operations = [
TrigramExtension()
]

View file

@ -34,7 +34,7 @@ def outbox(request, username):
)
def handle_account_search(query):
def handle_remote_webfinger(query):
''' webfingerin' other servers '''
user = None
domain = query.split('@')[1]
@ -61,14 +61,10 @@ def handle_account_search(query):
def handle_follow(user, to_follow):
''' someone local wants to follow someone '''
try:
relationship, _ = models.UserFollowRequest.objects.get_or_create(
user_subject=user,
user_object=to_follow,
)
except IntegrityError as err:
if err.__cause__.diag.constraint_name != 'userfollowrequest_unique':
raise
relationship, _ = models.UserFollowRequest.objects.get_or_create(
user_subject=user,
user_object=to_follow,
)
activity = relationship.to_activity()
broadcast(user, activity, direct_recipients=[to_follow])

View file

@ -0,0 +1,45 @@
{% extends 'layout.html' %}
{% block content %}
<div class="block columns">
<div class="column">
<h2 class="title">Matching Books</h2>
{% for result_set in book_results %}
{% if result_set.results %}
<section>
{% if not result_set.connector.local %}
<h3>
Results from <a href="{{ result_set.connector.base_url }}" target="_blank">{% if result_set.connector.name %}{{ result_set.connector.name }}{% else %}{{ result_set.connector.identifier }}{% endif %}</a>
</h3>
{% endif %}
{% for result in result_set.results %}
<div>
<form action="/resolve_book" method="POST">
{% csrf_token %}
<input type="hidden" name="remote_id" value="{{ result.key }}">
<button type="submit">{{ result.title }} by {{ result.author }} ({{ result.year }})</button>
</form>
</div>
{% endfor %}
</section>
{% endif %}
{% endfor %}
{% if not book_results %}
<p>No books found for "{{ query }}"</p>
{% endif %}
</div>
<div class="column">
<h2 class="title">Matching Users</h2>
{% if not user_results %}
<p>No users found for "{{ query }}"</p>
{% endif %}
{% for result in user_results %}
<div class="block">
{% include 'snippets/avatar.html' with user=result %}</h2>
{% include 'snippets/username.html' with user=result show_full=True %}</h2>
{% include 'snippets/follow_button.html' with user=result %}
</div>
{% endfor %}
</div>
</div>
{% endblock %}

View file

@ -6,6 +6,7 @@
<p>No results found for "{{ query }}"</p>
{% endif %}
{% for result in results %}
{{ result }}
<div class="block">
{% include 'snippets/avatar.html' with user=result %}</h2>
{% include 'snippets/username.html' with user=result show_full=True %}</h2>

View file

@ -2,6 +2,7 @@
import re
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.postgres.search import TrigramSimilarity
from django.db.models import Avg, Count, Q
from django.http import HttpResponseBadRequest, HttpResponseNotFound,\
JsonResponse
@ -147,22 +148,30 @@ def get_activity_feed(user, filter_level, model=models.Status):
def search(request):
''' that search bar up top '''
query = request.GET.get('q')
if re.match(r'\w+@\w+.\w+', query):
# if something looks like a username, search with webfinger
results = outgoing.handle_account_search(query)
return TemplateResponse(
request, 'user_results.html', {'results': results, 'query': query}
)
# or just send the question over to book search
if is_api_request(request):
# only return local results via json so we don't cause a cascade
results = books_manager.local_search(query)
return JsonResponse([r.__dict__ for r in results], safe=False)
# only return local book results via json so we don't cause a cascade
book_results = books_manager.local_search(query)
return JsonResponse([r.__dict__ for r in book_results], safe=False)
results = books_manager.search(query)
return TemplateResponse(request, 'book_results.html', {'results': results})
# use webfinger looks like a mastodon style account@domain.com username
if re.match(r'\w+@\w+.\w+', query):
outgoing.handle_remote_webfinger(query)
# do a local user search
user_results = models.User.objects.annotate(
similarity=TrigramSimilarity('username', query),
).filter(
similarity__gt=0.1,
).order_by('-similarity')[:10]
book_results = books_manager.search(query)
data = {
'book_results': book_results,
'user_results': user_results,
'query': query,
}
return TemplateResponse(request, 'search_results.html', data)
@login_required