From d132bc6fa15b89e00614b078c11a61e118a79ceb Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Wed, 18 Dec 2024 09:51:44 +0100 Subject: [PATCH] Add account and trend data sharing --- app/models/account.rb | 1 + app/models/concerns/account/fasp_concern.rb | 28 +++++++++ app/models/concerns/favourite/fasp_concern.rb | 15 +++++ app/models/concerns/status/fasp_concern.rb | 11 ++++ app/models/fasp/subscription.rb | 4 ++ app/models/favourite.rb | 1 + ...nnounce_account_lifecycle_event_worker.rb} | 14 ++--- app/workers/fasp/announce_trend_worker.rb | 59 +++++++++++++++++++ 8 files changed, 126 insertions(+), 7 deletions(-) create mode 100644 app/models/concerns/account/fasp_concern.rb create mode 100644 app/models/concerns/favourite/fasp_concern.rb rename app/workers/fasp/{announce_new_content_worker.rb => announce_account_lifecycle_event_worker.rb} (57%) create mode 100644 app/workers/fasp/announce_trend_worker.rb diff --git a/app/models/account.rb b/app/models/account.rb index 206529301e..127f10bcdc 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -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 diff --git a/app/models/concerns/account/fasp_concern.rb b/app/models/concerns/account/fasp_concern.rb new file mode 100644 index 0000000000..01717d396c --- /dev/null +++ b/app/models/concerns/account/fasp_concern.rb @@ -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 diff --git a/app/models/concerns/favourite/fasp_concern.rb b/app/models/concerns/favourite/fasp_concern.rb new file mode 100644 index 0000000000..2293411f3d --- /dev/null +++ b/app/models/concerns/favourite/fasp_concern.rb @@ -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 diff --git a/app/models/concerns/status/fasp_concern.rb b/app/models/concerns/status/fasp_concern.rb index 84b95dcc5b..30c7898324 100644 --- a/app/models/concerns/status/fasp_concern.rb +++ b/app/models/concerns/status/fasp_concern.rb @@ -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 diff --git a/app/models/fasp/subscription.rb b/app/models/fasp/subscription.rb index 4c98db27ab..1523613450 100644 --- a/app/models/fasp/subscription.rb +++ b/app/models/fasp/subscription.rb @@ -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 diff --git a/app/models/favourite.rb b/app/models/favourite.rb index 042f72beae..7bf793e2a1 100644 --- a/app/models/favourite.rb +++ b/app/models/favourite.rb @@ -13,6 +13,7 @@ class Favourite < ApplicationRecord include Paginable + include Favourite::FaspConcern update_index('statuses', :status) diff --git a/app/workers/fasp/announce_new_content_worker.rb b/app/workers/fasp/announce_account_lifecycle_event_worker.rb similarity index 57% rename from app/workers/fasp/announce_new_content_worker.rb rename to app/workers/fasp/announce_account_lifecycle_event_worker.rb index cc7b3d3b68..9a19892e73 100644 --- a/app/workers/fasp/announce_new_content_worker.rb +++ b/app/workers/fasp/announce_account_lifecycle_event_worker.rb @@ -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 diff --git a/app/workers/fasp/announce_trend_worker.rb b/app/workers/fasp/announce_trend_worker.rb new file mode 100644 index 0000000000..0d5fc6db48 --- /dev/null +++ b/app/workers/fasp/announce_trend_worker.rb @@ -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