mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-30 03:50:40 +00:00
Simplifies recipient logic
This commit is contained in:
parent
bb3b25b7f4
commit
b1a336bb08
2 changed files with 54 additions and 99 deletions
|
@ -12,56 +12,31 @@ from fedireads import models
|
||||||
from fedireads.tasks import app
|
from fedireads.tasks import app
|
||||||
|
|
||||||
|
|
||||||
def get_recipients(user, post_privacy, direct_recipients=None, limit=False):
|
def get_public_recipients(user, software=None):
|
||||||
''' deduplicated list of recipient inboxes '''
|
''' everybody and their public inboxes '''
|
||||||
# we're always going to broadcast to any direct recipients
|
followers = user.followers.filter(local=False)
|
||||||
direct_recipients = direct_recipients or []
|
if software:
|
||||||
recipients = [u.inbox for u in direct_recipients]
|
# TODO: eventually we may want to handle particular software differently
|
||||||
|
followers = followers.filter(fedireads_user=(software == 'fedireads'))
|
||||||
|
|
||||||
# if we're federating a book, it isn't related to any user's followers, we
|
shared = followers.filter(
|
||||||
# just want to send it out. To whom? I'm not sure, but for now, everyone.
|
shared_inbox__isnull=False
|
||||||
if not user:
|
).values_list('shared_inbox', flat=True).distinct()
|
||||||
users = models.User.objects.filter(local=False).all()
|
|
||||||
recipients += list(set(
|
|
||||||
u.shared_inbox if u.shared_inbox else u.inbox for u in users
|
|
||||||
))
|
|
||||||
return recipients
|
|
||||||
|
|
||||||
if post_privacy == 'direct':
|
inboxes = followers.filter(
|
||||||
# all we care about is direct_recipients, not followers, so we're done
|
shared_inbox__isnull=True
|
||||||
return recipients
|
).values_list('inbox', flat=True)
|
||||||
|
|
||||||
# load all the followers of the user who is sending the message
|
return list(shared) + list(inboxes)
|
||||||
# "limit" refers to whether we want to send to other fedireads instances,
|
|
||||||
# or to only non-fedireads instances. this is confusing (TODO)
|
|
||||||
if not limit:
|
|
||||||
followers = user.followers.all()
|
|
||||||
else:
|
|
||||||
fedireads_user = limit == 'fedireads'
|
|
||||||
followers = user.followers.filter(fedireads_user=fedireads_user).all()
|
|
||||||
|
|
||||||
# we don't need to broadcast to ourself
|
|
||||||
followers = followers.filter(local=False)
|
|
||||||
|
|
||||||
# TODO I don't think this is actually accomplishing pubic/followers only?
|
|
||||||
if post_privacy == 'public':
|
|
||||||
# post to public shared inboxes
|
|
||||||
shared_inboxes = set(
|
|
||||||
u.shared_inbox for u in followers if u.shared_inbox
|
|
||||||
)
|
|
||||||
recipients += list(shared_inboxes)
|
|
||||||
recipients += [u.inbox for u in followers if not u.shared_inbox]
|
|
||||||
|
|
||||||
if post_privacy == 'followers':
|
|
||||||
# don't send it to the shared inboxes
|
|
||||||
inboxes = set(u.inbox for u in followers)
|
|
||||||
recipients += list(inboxes)
|
|
||||||
|
|
||||||
return recipients
|
|
||||||
|
|
||||||
|
|
||||||
def broadcast(sender, activity, recipients):
|
def broadcast(sender, activity, software=None, \
|
||||||
|
privacy='public', direct_recipients=None):
|
||||||
''' send out an event '''
|
''' send out an event '''
|
||||||
|
recipients = [u.inbox for u in direct_recipients or []]
|
||||||
|
# TODO: other kinds of privacy
|
||||||
|
if privacy == 'public':
|
||||||
|
recipients = get_public_recipients(sender, software=software)
|
||||||
broadcast_task.delay(sender.id, activity, recipients)
|
broadcast_task.delay(sender.id, activity, recipients)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import requests
|
||||||
|
|
||||||
from fedireads import activitypub
|
from fedireads import activitypub
|
||||||
from fedireads import models
|
from fedireads import models
|
||||||
from fedireads.broadcast import get_recipients, broadcast
|
from fedireads.broadcast import broadcast
|
||||||
from fedireads.status import create_review, create_status
|
from fedireads.status import create_review, create_status
|
||||||
from fedireads.status import create_quotation, create_comment
|
from fedireads.status import create_quotation, create_comment
|
||||||
from fedireads.status import create_tag, create_notification, create_rating
|
from fedireads.status import create_tag, create_notification, create_rating
|
||||||
|
@ -106,8 +106,7 @@ def handle_accept(user, to_follow, follow_request):
|
||||||
relationship.save()
|
relationship.save()
|
||||||
|
|
||||||
activity = activitypub.get_accept(to_follow, follow_request)
|
activity = activitypub.get_accept(to_follow, follow_request)
|
||||||
recipient = get_recipients(to_follow, 'direct', direct_recipients=[user])
|
broadcast(to_follow, activity, privacy='direct', direct_recipients=[user])
|
||||||
broadcast(to_follow, activity, recipient)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_reject(user, to_follow, relationship):
|
def handle_reject(user, to_follow, relationship):
|
||||||
|
@ -115,8 +114,7 @@ def handle_reject(user, to_follow, relationship):
|
||||||
relationship.delete()
|
relationship.delete()
|
||||||
|
|
||||||
activity = activitypub.get_reject(to_follow, relationship)
|
activity = activitypub.get_reject(to_follow, relationship)
|
||||||
recipient = get_recipients(to_follow, 'direct', direct_recipients=[user])
|
broadcast(to_follow, activity, privacy='direct', direct_recipients=[user])
|
||||||
broadcast(to_follow, activity, recipient)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_shelve(user, book, shelf):
|
def handle_shelve(user, book, shelf):
|
||||||
|
@ -125,8 +123,7 @@ def handle_shelve(user, book, shelf):
|
||||||
models.ShelfBook(book=book, shelf=shelf, added_by=user).save()
|
models.ShelfBook(book=book, shelf=shelf, added_by=user).save()
|
||||||
|
|
||||||
activity = activitypub.get_add(user, book, shelf)
|
activity = activitypub.get_add(user, book, shelf)
|
||||||
recipients = get_recipients(user, 'public')
|
broadcast(user, activity)
|
||||||
broadcast(user, activity, recipients)
|
|
||||||
|
|
||||||
# tell the world about this cool thing that happened
|
# tell the world about this cool thing that happened
|
||||||
verb = {
|
verb = {
|
||||||
|
@ -171,9 +168,8 @@ def handle_unshelve(user, book, shelf):
|
||||||
row.delete()
|
row.delete()
|
||||||
|
|
||||||
activity = activitypub.get_remove(user, book, shelf)
|
activity = activitypub.get_remove(user, book, shelf)
|
||||||
recipients = get_recipients(user, 'public')
|
|
||||||
|
|
||||||
broadcast(user, activity, recipients)
|
broadcast(user, activity)
|
||||||
|
|
||||||
|
|
||||||
def handle_import_books(user, items):
|
def handle_import_books(user, items):
|
||||||
|
@ -194,8 +190,7 @@ def handle_import_books(user, items):
|
||||||
if created:
|
if created:
|
||||||
new_books.append(item.book)
|
new_books.append(item.book)
|
||||||
activity = activitypub.get_add(user, item.book, desired_shelf)
|
activity = activitypub.get_add(user, item.book, desired_shelf)
|
||||||
recipients = get_recipients(user, 'public')
|
broadcast(user, activity)
|
||||||
broadcast(user, activity, recipients)
|
|
||||||
|
|
||||||
for read in item.reads:
|
for read in item.reads:
|
||||||
read.book = item.book
|
read.book = item.book
|
||||||
|
@ -210,71 +205,62 @@ def handle_import_books(user, items):
|
||||||
|
|
||||||
create_activity = activitypub.get_create(
|
create_activity = activitypub.get_create(
|
||||||
user, activitypub.get_status(status))
|
user, activitypub.get_status(status))
|
||||||
recipients = get_recipients(user, 'public')
|
broadcast(user, create_activity)
|
||||||
broadcast(user, create_activity, recipients)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_rate(user, book, rating):
|
def handle_rate(user, book, rating):
|
||||||
''' a review that's just a rating '''
|
''' a review that's just a rating '''
|
||||||
builder = create_rating
|
builder = create_rating
|
||||||
local_serializer = activitypub.get_rating
|
fr_serializer = activitypub.get_rating
|
||||||
remote_serializer = activitypub.get_rating_note
|
ap_serializer = activitypub.get_rating_note
|
||||||
|
|
||||||
handle_status(
|
handle_status(user, book, builder, fr_serializer, ap_serializer, rating)
|
||||||
user, book,
|
|
||||||
builder, local_serializer, remote_serializer,
|
|
||||||
rating
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_review(user, book, name, content, rating):
|
def handle_review(user, book, name, content, rating):
|
||||||
''' post a review '''
|
''' post a review '''
|
||||||
# validated and saves the review in the database so it has an id
|
# validated and saves the review in the database so it has an id
|
||||||
builder = create_review
|
builder = create_review
|
||||||
local_serializer = activitypub.get_review
|
fr_serializer = activitypub.get_review
|
||||||
remote_serializer = activitypub.get_review_article
|
ap_serializer = activitypub.get_review_article
|
||||||
handle_status(
|
handle_status(
|
||||||
user, book, builder, local_serializer, remote_serializer,
|
user, book, builder, fr_serializer, ap_serializer, name, content, rating)
|
||||||
name, content, rating)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_quotation(user, book, content, quote):
|
def handle_quotation(user, book, content, quote):
|
||||||
''' post a review '''
|
''' post a review '''
|
||||||
# validated and saves the review in the database so it has an id
|
# validated and saves the review in the database so it has an id
|
||||||
builder = create_quotation
|
builder = create_quotation
|
||||||
local_serializer = activitypub.get_quotation
|
fr_serializer = activitypub.get_quotation
|
||||||
remote_serializer = activitypub.get_quotation_article
|
ap_serializer = activitypub.get_quotation_article
|
||||||
handle_status(
|
handle_status(
|
||||||
user, book, builder, local_serializer, remote_serializer,
|
user, book, builder, fr_serializer, ap_serializer, content, quote)
|
||||||
content, quote)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_comment(user, book, content):
|
def handle_comment(user, book, content):
|
||||||
''' post a review '''
|
''' post a comment '''
|
||||||
# validated and saves the review in the database so it has an id
|
# validated and saves the review in the database so it has an id
|
||||||
builder = create_comment
|
builder = create_comment
|
||||||
local_serializer = activitypub.get_comment
|
fr_serializer = activitypub.get_comment
|
||||||
remote_serializer = activitypub.get_comment_article
|
ap_serializer = activitypub.get_comment_article
|
||||||
handle_status(
|
handle_status(
|
||||||
user, book, builder, local_serializer, remote_serializer, content)
|
user, book, builder, fr_serializer, ap_serializer, content)
|
||||||
|
|
||||||
|
|
||||||
def handle_status(user, book, \
|
def handle_status(user, book, \
|
||||||
builder, local_serializer, remote_serializer, *args):
|
builder, fr_serializer, ap_serializer, *args):
|
||||||
''' generic handler for statuses '''
|
''' generic handler for statuses '''
|
||||||
status = builder(user, book, *args)
|
status = builder(user, book, *args)
|
||||||
|
|
||||||
activity = local_serializer(status)
|
activity = fr_serializer(status)
|
||||||
create_activity = activitypub.get_create(user, activity)
|
create_activity = activitypub.get_create(user, activity)
|
||||||
local_recipients = get_recipients(user, 'public', limit='fedireads')
|
broadcast(user, create_activity, software='fedireads')
|
||||||
broadcast(user, create_activity, local_recipients)
|
|
||||||
|
|
||||||
# re-format the activity for non-fedireads servers
|
# re-format the activity for non-fedireads servers
|
||||||
remote_activity = remote_serializer(status)
|
remote_activity = ap_serializer(status)
|
||||||
remote_create_activity = activitypub.get_create(user, remote_activity)
|
remote_create_activity = activitypub.get_create(user, remote_activity)
|
||||||
|
|
||||||
remote_recipients = get_recipients(user, 'public', limit='other')
|
broadcast(user, remote_create_activity, software='other')
|
||||||
broadcast(user, remote_create_activity, remote_recipients)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_tag(user, book, name):
|
def handle_tag(user, book, name):
|
||||||
|
@ -282,8 +268,7 @@ def handle_tag(user, book, name):
|
||||||
tag = create_tag(user, book, name)
|
tag = create_tag(user, book, name)
|
||||||
tag_activity = activitypub.get_add_tag(tag)
|
tag_activity = activitypub.get_add_tag(tag)
|
||||||
|
|
||||||
recipients = get_recipients(user, 'public')
|
broadcast(user, tag_activity)
|
||||||
broadcast(user, tag_activity, recipients)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_untag(user, book, name):
|
def handle_untag(user, book, name):
|
||||||
|
@ -293,8 +278,7 @@ def handle_untag(user, book, name):
|
||||||
tag_activity = activitypub.get_remove_tag(tag)
|
tag_activity = activitypub.get_remove_tag(tag)
|
||||||
tag.delete()
|
tag.delete()
|
||||||
|
|
||||||
recipients = get_recipients(user, 'public')
|
broadcast(user, tag_activity)
|
||||||
broadcast(user, tag_activity, recipients)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_reply(user, review, content):
|
def handle_reply(user, review, content):
|
||||||
|
@ -311,8 +295,7 @@ def handle_reply(user, review, content):
|
||||||
reply_activity = activitypub.get_status(reply)
|
reply_activity = activitypub.get_status(reply)
|
||||||
create_activity = activitypub.get_create(user, reply_activity)
|
create_activity = activitypub.get_create(user, reply_activity)
|
||||||
|
|
||||||
recipients = get_recipients(user, 'public')
|
broadcast(user, create_activity)
|
||||||
broadcast(user, create_activity, recipients)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_favorite(user, status):
|
def handle_favorite(user, status):
|
||||||
|
@ -327,8 +310,7 @@ def handle_favorite(user, status):
|
||||||
return
|
return
|
||||||
|
|
||||||
fav_activity = activitypub.get_favorite(favorite)
|
fav_activity = activitypub.get_favorite(favorite)
|
||||||
recipients = get_recipients(user, 'direct', [status.user])
|
broadcast(user, fav_activity, privacy='direct', direct_recipients=[status.user])
|
||||||
broadcast(user, fav_activity, recipients)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_unfavorite(user, status):
|
def handle_unfavorite(user, status):
|
||||||
|
@ -343,8 +325,8 @@ def handle_unfavorite(user, status):
|
||||||
return
|
return
|
||||||
|
|
||||||
fav_activity = activitypub.get_unfavorite(favorite)
|
fav_activity = activitypub.get_unfavorite(favorite)
|
||||||
recipients = get_recipients(user, 'direct', [status.user])
|
broadcast(user, fav_activity, [status.user])
|
||||||
broadcast(user, fav_activity, recipients)
|
|
||||||
|
|
||||||
def handle_boost(user, status):
|
def handle_boost(user, status):
|
||||||
''' a user wishes to boost a status '''
|
''' a user wishes to boost a status '''
|
||||||
|
@ -359,21 +341,19 @@ def handle_boost(user, status):
|
||||||
boost.save()
|
boost.save()
|
||||||
|
|
||||||
boost_activity = activitypub.get_boost(boost)
|
boost_activity = activitypub.get_boost(boost)
|
||||||
recipients = get_recipients(user, 'public')
|
broadcast(user, boost_activity)
|
||||||
broadcast(user, boost_activity, recipients)
|
|
||||||
|
|
||||||
def handle_update_book(user, book):
|
def handle_update_book(user, book):
|
||||||
''' broadcast the news about our book '''
|
''' broadcast the news about our book '''
|
||||||
book_activity = activitypub.get_book(book)
|
book_activity = activitypub.get_book(book)
|
||||||
update_activity = activitypub.get_update(user, book_activity)
|
update_activity = activitypub.get_update(user, book_activity)
|
||||||
recipients = get_recipients(None, 'public')
|
broadcast(user, update_activity)
|
||||||
broadcast(user, update_activity, recipients)
|
|
||||||
|
|
||||||
|
|
||||||
def handle_update_user(user):
|
def handle_update_user(user):
|
||||||
''' broadcast editing a user's profile '''
|
''' broadcast editing a user's profile '''
|
||||||
actor = activitypub.get_actor(user)
|
actor = activitypub.get_actor(user)
|
||||||
update_activity = activitypub.get_update(user, actor)
|
update_activity = activitypub.get_update(user, actor)
|
||||||
recipients = get_recipients(user, 'public')
|
broadcast(user, update_activity)
|
||||||
broadcast(user, update_activity, recipients)
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue