Use recipients model attribute in broadcast

This commit is contained in:
Mouse Reeve 2021-02-09 10:26:04 -08:00
parent 0fd2885e7e
commit 4ad51e62c6
3 changed files with 20 additions and 11 deletions

View file

@ -1,8 +1,9 @@
''' activitypub model functionality ''' ''' activitypub model functionality '''
from base64 import b64encode
from functools import reduce from functools import reduce
import json import json
import operator import operator
from base64 import b64encode import logging
from uuid import uuid4 from uuid import uuid4
import requests import requests
@ -20,6 +21,7 @@ from bookwyrm.signatures import make_signature, make_digest
from bookwyrm.tasks import app from bookwyrm.tasks import app
from bookwyrm.models.fields import ImageField, ManyToManyField from bookwyrm.models.fields import ImageField, ManyToManyField
logger = logging.getLogger(__name__)
# I tried to separate these classes into mutliple files but I kept getting # 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! # circular import errors so I gave up. I'm sure it could be done though!
class ActivitypubMixin: class ActivitypubMixin:
@ -121,8 +123,7 @@ class ActivitypubMixin:
# or maybe the thing itself is a user # or maybe the thing itself is a user
user = self user = self
# find anyone who's tagged in a status, for example # find anyone who's tagged in a status, for example
mentions = self.mention_users.all() if \ mentions = self.recipients if hasattr(self, 'recipients') else []
hasattr(self, 'mention_users') else []
# we always send activities to explicitly mentioned users' inboxes # we always send activities to explicitly mentioned users' inboxes
recipients = [u.inbox for u in mentions or []] recipients = [u.inbox for u in mentions or []]
@ -428,17 +429,11 @@ def broadcast_task(sender_id, activity, recipients):
''' the celery task for broadcast ''' ''' the celery task for broadcast '''
user_model = apps.get_model('bookwyrm.User', require_ready=True) user_model = apps.get_model('bookwyrm.User', require_ready=True)
sender = user_model.objects.get(id=sender_id) sender = user_model.objects.get(id=sender_id)
errors = []
for recipient in recipients: for recipient in recipients:
try: try:
sign_and_send(sender, activity, recipient) sign_and_send(sender, activity, recipient)
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
errors.append({ logger.exception(e)
'error': str(e),
'recipient': recipient,
'activity': activity,
})
return errors
def sign_and_send(sender, data, destination): def sign_and_send(sender, data, destination):

View file

@ -29,6 +29,11 @@ class UserRelationship(BookWyrmModel):
''' all relationships are handled directly with the participants ''' ''' all relationships are handled directly with the participants '''
return 'direct' 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: class Meta:
''' relationships should be unique ''' ''' relationships should be unique '''
abstract = True abstract = True
@ -71,7 +76,7 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship):
status = 'follow_request' status = 'follow_request'
activity_serializer = activitypub.Follow 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 ''' ''' make sure the follow or block relationship doesn't already exist '''
try: try:
UserFollows.objects.get( UserFollows.objects.get(

View file

@ -52,6 +52,15 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
serialize_reverse_fields = [('attachments', 'attachment', 'id')] serialize_reverse_fields = [('attachments', 'attachment', 'id')]
deserialize_reverse_fields = [('attachments', 'attachment')] 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 @classmethod
def ignore_activity(cls, activity): def ignore_activity(cls, activity):
''' keep notes if they are replies to existing statuses ''' ''' keep notes if they are replies to existing statuses '''