Improve interaction fanout

This commit is contained in:
Andrew Godwin 2022-12-31 14:47:46 -07:00
parent 002276ab9a
commit b522f43ffc

View file

@ -3,10 +3,8 @@ from django.utils import timezone
from activities.models.fan_out import FanOut
from activities.models.post import Post
from activities.models.timeline_event import TimelineEvent
from core.ld import format_ld_date, get_str_or_id, parse_ld_date
from stator.models import State, StateField, StateGraph, StatorModel
from users.models.follow import Follow
from users.models.identity import Identity
@ -30,33 +28,37 @@ class PostInteractionStates(StateGraph):
Creates all needed fan-out objects for a new PostInteraction.
"""
interaction = await instance.afetch_full()
# Boost: send a copy to all people who follow this user
# Boost: send a copy to all people who follow this user (limiting
# to just local follows if it's a remote post)
if interaction.type == interaction.Types.boost:
async for follow in interaction.identity.inbound_follows.filter(
boosts=True
).select_related("source", "target"):
if follow.source.local or follow.target.local:
if interaction.post.local or follow.source.local:
await FanOut.objects.acreate(
type=FanOut.Types.interaction,
identity_id=follow.source_id,
subject_post=interaction.post,
subject_post_interaction=interaction,
)
# And one to the post's author
await FanOut.objects.acreate(
type=FanOut.Types.interaction,
identity_id=interaction.post.author_id,
subject_post=interaction.post,
subject_post_interaction=interaction,
)
# Like: send a copy to the original post author only
# And one to the post's author, if the booster is local or they are
if interaction.identity.local or interaction.post.local:
await FanOut.objects.acreate(
type=FanOut.Types.interaction,
identity_id=interaction.post.author_id,
subject_post=interaction.post,
subject_post_interaction=interaction,
)
# Like: send a copy to the original post author only,
# if the liker is local or they are
elif interaction.type == interaction.Types.like:
await FanOut.objects.acreate(
type=FanOut.Types.interaction,
identity_id=interaction.post.author_id,
subject_post=interaction.post,
subject_post_interaction=interaction,
)
if interaction.identity.local or interaction.post.local:
await FanOut.objects.acreate(
type=FanOut.Types.interaction,
identity_id=interaction.post.author_id,
subject_post=interaction.post,
subject_post_interaction=interaction,
)
else:
raise ValueError("Cannot fan out unknown type")
# And one for themselves if they're local and it's a boost
@ -291,18 +293,6 @@ class PostInteraction(StatorModel):
# That post is gone, boss
# TODO: Limited retry state?
return
# Boosts (announces) go to everyone who follows locally
if interaction.type == cls.Types.boost:
for follow in Follow.objects.filter(
target=interaction.identity, source__local=True, boosts=True
):
TimelineEvent.add_post_interaction(follow.source, interaction)
# Likes go to just the author of the post
elif interaction.type == cls.Types.like:
TimelineEvent.add_post_interaction(interaction.post.author, interaction)
# Force it into fanned_out as it's not ours
interaction.transition_perform(PostInteractionStates.fanned_out)
# Recalculate post stats
interaction.post.calculate_stats()
@classmethod