mirror of
https://github.com/jointakahe/takahe.git
synced 2024-11-25 16:51:00 +00:00
parent
33b24d99bc
commit
427744f5a7
1 changed files with 46 additions and 14 deletions
|
@ -1,3 +1,5 @@
|
|||
from collections.abc import Iterable
|
||||
|
||||
from django.db import models, transaction
|
||||
from django.utils import timezone
|
||||
|
||||
|
@ -31,23 +33,12 @@ class PostInteractionStates(StateGraph):
|
|||
"""
|
||||
interaction = await instance.afetch_full()
|
||||
# Boost: send a copy to all people who follow this user (limiting
|
||||
# to just local follows if it's a remote post)
|
||||
# to just local follows if it's a remote boost)
|
||||
if interaction.type == interaction.Types.boost:
|
||||
async for follow in interaction.identity.inbound_follows.filter(
|
||||
boosts=True
|
||||
).select_related("source", "target"):
|
||||
if interaction.post.local or follow.source.local:
|
||||
for target in await interaction.aget_boost_targets():
|
||||
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, 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,
|
||||
identity=target,
|
||||
subject_post=interaction.post,
|
||||
subject_post_interaction=interaction,
|
||||
)
|
||||
|
@ -224,6 +215,47 @@ class PostInteraction(StatorModel):
|
|||
"identity", "post", "post__author"
|
||||
).aget(pk=self.pk)
|
||||
|
||||
async def aget_boost_targets(self) -> Iterable[Identity]:
|
||||
"""
|
||||
Returns an iterable with Identities of followers that have unique
|
||||
shared_inbox among each other to be used as target to the boost
|
||||
"""
|
||||
# Start including the post author
|
||||
targets = {self.post.author}
|
||||
|
||||
# Include all followers that are following the boosts
|
||||
async for follow in self.identity.inbound_follows.active().filter(
|
||||
boosts=True
|
||||
).select_related("source"):
|
||||
targets.add(follow.source)
|
||||
|
||||
# Fetch the full blocks and remove them as targets
|
||||
async for block in self.identity.outbound_blocks.active().filter(
|
||||
mute=False
|
||||
).select_related("target"):
|
||||
try:
|
||||
targets.remove(block.target)
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
deduped_targets = set()
|
||||
shared_inboxes = set()
|
||||
for target in targets:
|
||||
if target.local:
|
||||
# Local targets always gets the boosts
|
||||
# despite its creator locality
|
||||
deduped_targets.add(target)
|
||||
elif self.identity.local:
|
||||
# Dedupe the targets based on shared inboxes
|
||||
# (we only keep one per shared inbox)
|
||||
if not target.shared_inbox_uri:
|
||||
deduped_targets.add(target)
|
||||
elif target.shared_inbox_uri not in shared_inboxes:
|
||||
shared_inboxes.add(target.shared_inbox_uri)
|
||||
deduped_targets.add(target)
|
||||
|
||||
return deduped_targets
|
||||
|
||||
### Create helpers ###
|
||||
|
||||
@classmethod
|
||||
|
|
Loading…
Reference in a new issue