Add account and trend data sharing

This commit is contained in:
David Roetzel 2024-12-18 09:51:44 +01:00
parent 3f5c040d7c
commit d132bc6fa1
No known key found for this signature in database
8 changed files with 126 additions and 7 deletions

View File

@ -85,6 +85,7 @@ class Account < ApplicationRecord
include Account::Associations
include Account::Avatar
include Account::Counters
include Account::FaspConcern
include Account::FinderConcern
include Account::Header
include Account::Interactions

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
module Account::FaspConcern
extend ActiveSupport::Concern
included do
after_commit :announce_new_account_to_subscribed_fasp, on: :create
after_commit :announce_updated_account_to_subscribed_fasp, on: :update
after_commit :announce_deleted_account_to_subscribed_fasp, on: :destroy
end
private
def announce_new_account_to_subscribed_fasp
uri = ActivityPub::TagManager.instance.uri_for(self)
Fasp::AnnounceAccountLifecycleEventWorker.perform_async(uri, 'new')
end
def announce_updated_account_to_subscribed_fasp
uri = ActivityPub::TagManager.instance.uri_for(self)
Fasp::AnnounceAccountLifecycleEventWorker.perform_async(uri, 'update')
end
def announce_deleted_account_to_subscribed_fasp
uri = ActivityPub::TagManager.instance.uri_for(self)
Fasp::AnnounceAccountLifecycleEventWorker.perform_async(uri, 'delete')
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
module Favourite::FaspConcern
extend ActiveSupport::Concern
included do
after_commit :announce_trends_to_subscribed_fasp, on: :create
end
private
def announce_trends_to_subscribed_fasp
Fasp::AnnounceTrendWorker.perform_async(status_id, 'favourite')
end
end

View File

@ -7,6 +7,7 @@ module Status::FaspConcern
after_commit :announce_new_content_to_subscribed_fasp, on: :create
after_commit :announce_updated_content_to_subscribed_fasp, on: :update
after_commit :announce_deleted_content_to_subscribed_fasp, on: :destroy
after_commit :announce_trends_to_subscribed_fasp, on: :create
end
private
@ -23,4 +24,14 @@ module Status::FaspConcern
def announce_deleted_content_to_subscribed_fasp
Fasp::AnnounceContentLifecycleEventWorker.perform_async(uri, 'delete')
end
def announce_trends_to_subscribed_fasp
candidate_id, trend_source =
if reblog_of_id
[reblog_of_id, 'reblog']
elsif in_reply_to_id
[in_reply_to_id, 'reply']
end
Fasp::AnnounceTrendWorker.perform_async(candidate_id, trend_source) if candidate_id
end
end

View File

@ -37,4 +37,8 @@ class Fasp::Subscription < ApplicationRecord
self.threshold_likes = threshold['likes'] || 3
self.threshold_replies = threshold['replies'] || 3
end
def timeframe_start
threshold_timeframe.minutes.ago
end
end

View File

@ -13,6 +13,7 @@
class Favourite < ApplicationRecord
include Paginable
include Favourite::FaspConcern
update_index('statuses', :status)

View File

@ -1,27 +1,27 @@
# frozen_string_literal: true
class Fasp::AnnounceNewContentWorker
class Fasp::AnnounceAccountLifecycleEventWorker
include Sidekiq::Worker
sidekiq_options queue: 'fasp', retry: 5
def perform(uri)
Fasp::Subscription.includes(:fasp_provider).content.lifecycle.each do |subscription|
announce(subscription, uri)
def perform(uri, event_type)
Fasp::Subscription.includes(:fasp_provider).account.lifecycle.each do |subscription|
announce(subscription, uri, event_type)
end
end
private
def announce(subscription, uri)
def announce(subscription, uri, event_type)
Fasp::Request.new(subscription.fasp_provider).post('/data_sharing/v0/announcements', body: {
source: {
subscription: {
id: subscription.id.to_s,
},
},
category: 'content',
eventType: 'new',
category: 'account',
eventType: event_type,
objectUris: [uri],
})
end

View File

@ -0,0 +1,59 @@
# frozen_string_literal: true
class Fasp::AnnounceTrendWorker
include Sidekiq::Worker
sidekiq_options queue: 'fasp', retry: 5
def perform(status_id, trend_source)
status = ::Status.find(status_id)
Fasp::Subscription.includes(:fasp_provider).content.trends.each do |subscription|
announce(subscription, status.uri) if trending?(subscription, status, trend_source)
end
rescue ActiveRecord::RecordNotFound
# status might not exist anymore, in which case there is nothing to do
end
private
def trending?(subscription, status, trend_source)
scope = scope_for(status, trend_source)
threshold = threshold_for(subscription, trend_source)
scope.where(created_at: subscription.timeframe_start..).count >= threshold
end
def scope_for(status, trend_source)
case trend_source
when 'favourite'
status.favourites
when 'reblog'
status.reblogs
when 'reply'
status.replies
end
end
def threshold_for(subscription, trend_source)
case trend_source
when 'favourite'
subscription.threshold_likes
when 'reblog'
subscription.threshold_shares
when 'reply'
subscription.threshold_replies
end
end
def announce(subscription, uri)
Fasp::Request.new(subscription.fasp_provider).post('/data_sharing/v0/announcements', body: {
source: {
subscription: {
id: subscription.id.to_s,
},
},
category: 'content',
eventType: 'trending',
objectUris: [uri],
})
end
end