From c1243b5c21ff64ffb520e1a0f61684d55a70ee5b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 30 Dec 2020 13:14:16 -0800 Subject: [PATCH 1/2] Makes outbox filter-able --- bookwyrm/models/__init__.py | 3 +++ bookwyrm/models/base_model.py | 4 +++- bookwyrm/models/user.py | 15 +++++++++++++-- bookwyrm/outgoing.py | 5 ++++- bookwyrm/tests/test_outgoing.py | 22 ++++++++++++++++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/bookwyrm/models/__init__.py b/bookwyrm/models/__init__.py index 0c3bf33e..76290416 100644 --- a/bookwyrm/models/__init__.py +++ b/bookwyrm/models/__init__.py @@ -25,3 +25,6 @@ from .site import SiteSettings, SiteInvite, PasswordReset cls_members = inspect.getmembers(sys.modules[__name__], inspect.isclass) activity_models = {c[1].activity_serializer.__name__: c[1] \ for c in cls_members if hasattr(c[1], 'activity_serializer')} + +status_models = [ + c.__name__ for (_, c) in activity_models.items() if issubclass(c, Status)] diff --git a/bookwyrm/models/base_model.py b/bookwyrm/models/base_model.py index 0de61fd1..469a6972 100644 --- a/bookwyrm/models/base_model.py +++ b/bookwyrm/models/base_model.py @@ -237,7 +237,9 @@ class OrderedCollectionPageMixin(ActivitypubMixin): ).serialize() -def to_ordered_collection_page(queryset, remote_id, id_only=False, page=1): +# pylint: disable=unused-argument +def to_ordered_collection_page( + queryset, remote_id, id_only=False, page=1, **kwargs): ''' serialize and pagiante a queryset ''' paginated = Paginator(queryset, PAGE_LENGTH) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index cf6dd3b2..b27ce447 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -1,6 +1,7 @@ ''' database schema for user data ''' from urllib.parse import urlparse +from django.apps import apps from django.contrib.auth.models import AbstractUser from django.db import models from django.dispatch import receiver @@ -106,9 +107,19 @@ class User(OrderedCollectionPageMixin, AbstractUser): activity_serializer = activitypub.Person - def to_outbox(self, **kwargs): + def to_outbox(self, filter_type=None, **kwargs): ''' an ordered collection of statuses ''' - queryset = Status.objects.filter( + if filter_type: + filter_class = apps.get_model( + 'bookwyrm.%s' % filter_type, require_ready=True) + if not issubclass(filter_class, Status): + raise TypeError( + 'filter_status_class must be a subclass of models.Status') + queryset = filter_class.objects + else: + queryset = Status.objects + + queryset = queryset.filter( user=self, deleted=False, privacy__in=['public', 'unlisted'], diff --git a/bookwyrm/outgoing.py b/bookwyrm/outgoing.py index de2a4cbe..aee463c9 100644 --- a/bookwyrm/outgoing.py +++ b/bookwyrm/outgoing.py @@ -26,9 +26,12 @@ from bookwyrm.utils import regex def outbox(request, username): ''' outbox for the requested user ''' user = get_object_or_404(models.User, localname=username) + filter_type = request.GET.get('type') + if filter_type not in models.status_models: + filter_type = None return JsonResponse( - user.to_outbox(**request.GET), + user.to_outbox(**request.GET, filter_type=filter_type), encoder=activitypub.ActivityEncoder ) diff --git a/bookwyrm/tests/test_outgoing.py b/bookwyrm/tests/test_outgoing.py index b89e75f6..92360034 100644 --- a/bookwyrm/tests/test_outgoing.py +++ b/bookwyrm/tests/test_outgoing.py @@ -87,6 +87,28 @@ class Outgoing(TestCase): self.assertEqual(data['type'], 'OrderedCollection') self.assertEqual(data['totalItems'], 2) + def test_outbox_filter(self): + ''' if we only care about reviews, only get reviews ''' + models.Review.objects.create( + content='look at this', name='hi', rating=1, + book=self.book, user=self.local_user) + models.Status.objects.create( + content='look at this', user=self.local_user) + + request = self.factory.get('', {'type': 'bleh'}) + result = outgoing.outbox(request, 'mouse') + self.assertIsInstance(result, JsonResponse) + data = json.loads(result.content) + self.assertEqual(data['type'], 'OrderedCollection') + self.assertEqual(data['totalItems'], 2) + + request = self.factory.get('', {'type': 'Review'}) + result = outgoing.outbox(request, 'mouse') + self.assertIsInstance(result, JsonResponse) + data = json.loads(result.content) + self.assertEqual(data['type'], 'OrderedCollection') + self.assertEqual(data['totalItems'], 1) + def test_handle_follow(self): ''' send a follow request ''' From 45c13bd76c4b416096aa06538d96861794258002 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 30 Dec 2020 13:16:09 -0800 Subject: [PATCH 2/2] Only get reviews when loading user data --- bookwyrm/models/user.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index b27ce447..e70309a7 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -284,7 +284,7 @@ def get_or_create_remote_server(domain): @app.task def get_remote_reviews(outbox): ''' ingest reviews by a new remote bookwyrm user ''' - outbox_page = outbox + '?page=true' + outbox_page = outbox + '?page=true&type=Review' data = get_data(outbox_page) # TODO: pagination?