From 4ad51e62c645ecd7f4a59c7e5820da53c96612af Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 9 Feb 2021 10:26:04 -0800 Subject: [PATCH] Use recipients model attribute in broadcast --- bookwyrm/models/activitypub_mixin.py | 15 +++++---------- bookwyrm/models/relationship.py | 7 ++++++- bookwyrm/models/status.py | 9 +++++++++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index 1ab5fa3f..1a536ea0 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -1,8 +1,9 @@ ''' activitypub model functionality ''' +from base64 import b64encode from functools import reduce import json import operator -from base64 import b64encode +import logging from uuid import uuid4 import requests @@ -20,6 +21,7 @@ from bookwyrm.signatures import make_signature, make_digest from bookwyrm.tasks import app from bookwyrm.models.fields import ImageField, ManyToManyField +logger = logging.getLogger(__name__) # I tried to separate these classes into mutliple files but I kept getting # circular import errors so I gave up. I'm sure it could be done though! class ActivitypubMixin: @@ -121,8 +123,7 @@ class ActivitypubMixin: # or maybe the thing itself is a user user = self # find anyone who's tagged in a status, for example - mentions = self.mention_users.all() if \ - hasattr(self, 'mention_users') else [] + mentions = self.recipients if hasattr(self, 'recipients') else [] # we always send activities to explicitly mentioned users' inboxes recipients = [u.inbox for u in mentions or []] @@ -428,17 +429,11 @@ def broadcast_task(sender_id, activity, recipients): ''' the celery task for broadcast ''' user_model = apps.get_model('bookwyrm.User', require_ready=True) sender = user_model.objects.get(id=sender_id) - errors = [] for recipient in recipients: try: sign_and_send(sender, activity, recipient) except requests.exceptions.HTTPError as e: - errors.append({ - 'error': str(e), - 'recipient': recipient, - 'activity': activity, - }) - return errors + logger.exception(e) def sign_and_send(sender, data, destination): diff --git a/bookwyrm/models/relationship.py b/bookwyrm/models/relationship.py index 171edf36..9f3bf07d 100644 --- a/bookwyrm/models/relationship.py +++ b/bookwyrm/models/relationship.py @@ -29,6 +29,11 @@ class UserRelationship(BookWyrmModel): ''' all relationships are handled directly with the participants ''' return 'direct' + @property + def recipients(self): + ''' the remote user needs to recieve direct broadcasts ''' + return [u for u in [self.user_subject, self.user_object] if not u.local] + class Meta: ''' relationships should be unique ''' abstract = True @@ -71,7 +76,7 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship): status = 'follow_request' activity_serializer = activitypub.Follow - def save(self, broadcast=True, *args, **kwargs): + def save(self, *args, broadcast=True, **kwargs): ''' make sure the follow or block relationship doesn't already exist ''' try: UserFollows.objects.get( diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index ec105a10..edf60281 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -52,6 +52,15 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): serialize_reverse_fields = [('attachments', 'attachment', 'id')] deserialize_reverse_fields = [('attachments', 'attachment')] + @property + def recipients(self): + ''' tagged users who definitely need to get this status in broadcast ''' + mentions = [u for u in self.mention_users.all() if not u.local] + if hasattr(self, 'reply_parent') and self.reply_parent \ + and not self.reply_parent.user.local: + mentions.append(self.reply_parent.user) + return list(set(mentions)) + @classmethod def ignore_activity(cls, activity): ''' keep notes if they are replies to existing statuses '''