Merge pull request #440 from mouse-reeve/filter-outbox

Makes outbox filter-able
This commit is contained in:
Mouse Reeve 2020-12-30 14:11:15 -08:00 committed by GitHub
commit 8039885648
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 5 deletions

View file

@ -25,3 +25,6 @@ from .site import SiteSettings, SiteInvite, PasswordReset
cls_members = inspect.getmembers(sys.modules[__name__], inspect.isclass) cls_members = inspect.getmembers(sys.modules[__name__], inspect.isclass)
activity_models = {c[1].activity_serializer.__name__: c[1] \ activity_models = {c[1].activity_serializer.__name__: c[1] \
for c in cls_members if hasattr(c[1], 'activity_serializer')} 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)]

View file

@ -237,7 +237,9 @@ class OrderedCollectionPageMixin(ActivitypubMixin):
).serialize() ).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 ''' ''' serialize and pagiante a queryset '''
paginated = Paginator(queryset, PAGE_LENGTH) paginated = Paginator(queryset, PAGE_LENGTH)

View file

@ -1,6 +1,7 @@
''' database schema for user data ''' ''' database schema for user data '''
from urllib.parse import urlparse from urllib.parse import urlparse
from django.apps import apps
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
from django.dispatch import receiver from django.dispatch import receiver
@ -106,9 +107,19 @@ class User(OrderedCollectionPageMixin, AbstractUser):
activity_serializer = activitypub.Person activity_serializer = activitypub.Person
def to_outbox(self, **kwargs): def to_outbox(self, filter_type=None, **kwargs):
''' an ordered collection of statuses ''' ''' 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, user=self,
deleted=False, deleted=False,
privacy__in=['public', 'unlisted'], privacy__in=['public', 'unlisted'],
@ -273,7 +284,7 @@ def get_or_create_remote_server(domain):
@app.task @app.task
def get_remote_reviews(outbox): def get_remote_reviews(outbox):
''' ingest reviews by a new remote bookwyrm user ''' ''' 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) data = get_data(outbox_page)
# TODO: pagination? # TODO: pagination?

View file

@ -26,9 +26,12 @@ from bookwyrm.utils import regex
def outbox(request, username): def outbox(request, username):
''' outbox for the requested user ''' ''' outbox for the requested user '''
user = get_object_or_404(models.User, localname=username) 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( return JsonResponse(
user.to_outbox(**request.GET), user.to_outbox(**request.GET, filter_type=filter_type),
encoder=activitypub.ActivityEncoder encoder=activitypub.ActivityEncoder
) )

View file

@ -87,6 +87,28 @@ class Outgoing(TestCase):
self.assertEqual(data['type'], 'OrderedCollection') self.assertEqual(data['type'], 'OrderedCollection')
self.assertEqual(data['totalItems'], 2) 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): def test_handle_follow(self):
''' send a follow request ''' ''' send a follow request '''