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 '''