Add reblogs and favourites counts to statuses in ActivityPub (#32007)

This commit is contained in:
Eugen Rochko 2024-09-23 15:14:15 +02:00 committed by GitHub
parent b5bdc69f7b
commit aaab6b7adc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 105 additions and 1 deletions

View file

@ -0,0 +1,36 @@
# frozen_string_literal: true
class ActivityPub::LikesController < ActivityPub::BaseController
include Authorization
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature!, if: :authorized_fetch_mode?
before_action :set_status
def index
expires_in 0, public: @status.distributable? && public_fetch_mode?
render json: likes_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
end
private
def pundit_user
signed_request_account
end
def set_status
@status = @account.statuses.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
not_found
end
def likes_collection_presenter
ActivityPub::CollectionPresenter.new(
id: account_status_likes_url(@account, @status),
type: :unordered,
size: @status.favourites_count
)
end
end

View file

@ -12,7 +12,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
before_action :set_replies before_action :set_replies
def index def index
expires_in 0, public: public_fetch_mode? expires_in 0, public: @status.distributable? && public_fetch_mode?
render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
end end

View file

@ -0,0 +1,36 @@
# frozen_string_literal: true
class ActivityPub::SharesController < ActivityPub::BaseController
include Authorization
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature!, if: :authorized_fetch_mode?
before_action :set_status
def index
expires_in 0, public: @status.distributable? && public_fetch_mode?
render json: shares_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
end
private
def pundit_user
signed_request_account
end
def set_status
@status = @account.statuses.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
not_found
end
def shares_collection_presenter
ActivityPub::CollectionPresenter.new(
id: account_status_shares_url(@account, @status),
type: :unordered,
size: @status.reblogs_count
)
end
end

View file

@ -74,6 +74,18 @@ class ActivityPub::TagManager
account_status_replies_url(target.account, target, page_params) account_status_replies_url(target.account, target, page_params)
end end
def likes_uri_for(target)
raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local?
account_status_likes_url(target.account, target)
end
def shares_uri_for(target)
raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local?
account_status_shares_url(target.account, target)
end
def followers_uri_for(target) def followers_uri_for(target)
target.local? ? account_followers_url(target) : target.followers_url.presence target.local? ? account_followers_url(target) : target.followers_url.presence
end end

View file

@ -19,6 +19,8 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
has_many :virtual_tags, key: :tag has_many :virtual_tags, key: :tag
has_one :replies, serializer: ActivityPub::CollectionSerializer, if: :local? has_one :replies, serializer: ActivityPub::CollectionSerializer, if: :local?
has_one :likes, serializer: ActivityPub::CollectionSerializer, if: :local?
has_one :shares, serializer: ActivityPub::CollectionSerializer, if: :local?
has_many :poll_options, key: :one_of, if: :poll_and_not_multiple? has_many :poll_options, key: :one_of, if: :poll_and_not_multiple?
has_many :poll_options, key: :any_of, if: :poll_and_multiple? has_many :poll_options, key: :any_of, if: :poll_and_multiple?
@ -64,6 +66,22 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
) )
end end
def likes
ActivityPub::CollectionPresenter.new(
id: ActivityPub::TagManager.instance.likes_uri_for(object),
type: :unordered,
size: object.favourites_count
)
end
def shares
ActivityPub::CollectionPresenter.new(
id: ActivityPub::TagManager.instance.shares_uri_for(object),
type: :unordered,
size: object.reblogs_count
)
end
def language? def language?
object.language.present? object.language.present?
end end

View file

@ -126,6 +126,8 @@ Rails.application.routes.draw do
end end
resources :replies, only: [:index], module: :activitypub resources :replies, only: [:index], module: :activitypub
resources :likes, only: [:index], module: :activitypub
resources :shares, only: [:index], module: :activitypub
end end
resources :followers, only: [:index], controller: :follower_accounts resources :followers, only: [:index], controller: :follower_accounts