Move anntotated users quuery into suggested users module

This commit is contained in:
Mouse Reeve 2021-04-23 18:26:48 -07:00
parent dda21195de
commit 9880bdc75b
4 changed files with 35 additions and 52 deletions

View file

@ -1,17 +1,16 @@
""" store recommended follows in redis """ """ store recommended follows in redis """
import math import math
from django.dispatch import receiver from django.dispatch import receiver
from django.db.models import signals, Q from django.db.models import signals, Count, Q
from bookwyrm import models from bookwyrm import models
from bookwyrm.redis_store import RedisStore, r from bookwyrm.redis_store import RedisStore, r
from bookwyrm.views.helpers import get_annotated_users
class SuggestedUsers(RedisStore): class SuggestedUsers(RedisStore):
""" suggested users for a user """ """ suggested users for a user """
max_length = 10 max_length = 30
def get_rank(self, obj): def get_rank(self, obj):
""" get computed rank """ """ get computed rank """
@ -25,7 +24,7 @@ class SuggestedUsers(RedisStore):
""" calculate mutuals count and shared books count from rank """ """ calculate mutuals count and shared books count from rank """
return { return {
"mutuals": math.floor(rank), "mutuals": math.floor(rank),
"shared_books": int(1 / (-1 * (1 % rank - 1))), "shared_books": int(1 / (-1 * (1 % rank - 1))) if rank else 0,
} }
def get_objects_for_store(self, store): def get_objects_for_store(self, store):
@ -83,6 +82,35 @@ class SuggestedUsers(RedisStore):
return results return results
def get_annotated_users(viewer, *args, **kwargs):
""" Users, annotated with things they have in common """
return (
models.User.objects.filter(discoverable=True, is_active=True, *args, **kwargs)
.exclude(Q(id__in=viewer.blocks.all()) | Q(blocks=viewer))
.annotate(
mutuals=Count(
"following",
filter=Q(
~Q(id=viewer.id),
~Q(id__in=viewer.following.all()),
following__in=viewer.following.all(),
),
distinct=True,
),
shared_books=Count(
"shelfbook",
filter=Q(
~Q(id=viewer.id),
shelfbook__book__parent_work__in=[
s.book.parent_work for s in viewer.shelfbook_set.all()
],
),
distinct=True,
),
)
)
suggested_users = SuggestedUsers() suggested_users = SuggestedUsers()

View file

@ -6,7 +6,7 @@ from django.template.response import TemplateResponse
from django.views import View from django.views import View
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from .helpers import get_annotated_users from bookwyrm import suggested_users
# pylint: disable=no-self-use # pylint: disable=no-self-use
@method_decorator(login_required, name="dispatch") @method_decorator(login_required, name="dispatch")
@ -29,7 +29,7 @@ class Directory(View):
if scope == "local": if scope == "local":
filters["local"] = True filters["local"] = True
users = get_annotated_users(request.user, **filters) users = suggested_users.get_annotated_users(request.user, **filters)
sort = request.GET.get("sort") sort = request.GET.get("sort")
if sort == "recent": if sort == "recent":
users = users.order_by("-last_active_date") users = users.order_by("-last_active_date")

View file

@ -13,7 +13,6 @@ from django.views import View
from bookwyrm import forms, models from bookwyrm import forms, models
from bookwyrm.connectors import connector_manager from bookwyrm.connectors import connector_manager
from .helpers import get_suggested_users
from .user import save_user_form from .user import save_user_form
@ -120,7 +119,7 @@ class GetStartedUsers(View):
) )
if user_results.count() < 5: if user_results.count() < 5:
suggested_users = get_suggested_users(request.user) suggested_users = None#get_suggested_users(request.user)
data = { data = {
"suggested_users": list(user_results) + list(suggested_users), "suggested_users": list(user_results) + list(suggested_users),

View file

@ -190,47 +190,3 @@ def get_discover_books():
.order_by("-review__published_date__max")[:6] .order_by("-review__published_date__max")[:6]
) )
) )
def get_suggested_users(user):
""" bookwyrm users you don't already know """
return (
get_annotated_users(
user,
~Q(id=user.id),
~Q(followers=user),
~Q(follower_requests=user),
bookwyrm_user=True,
)
.order_by("-mutuals", "-last_active_date")
.all()[:5]
)
def get_annotated_users(viewer, *args, **kwargs):
""" Users, annotated with things they have in common """
return (
models.User.objects.filter(discoverable=True, is_active=True, *args, **kwargs)
.exclude(Q(id__in=viewer.blocks.all()) | Q(blocks=viewer))
.annotate(
mutuals=Count(
"following",
filter=Q(
~Q(id=viewer.id),
~Q(id__in=viewer.following.all()),
following__in=viewer.following.all(),
),
distinct=True,
),
shared_books=Count(
"shelfbook",
filter=Q(
~Q(id=viewer.id),
shelfbook__book__parent_work__in=[
s.book.parent_work for s in viewer.shelfbook_set.all()
],
),
distinct=True,
),
)
)