Add reblogs and favourites counts to statuses in ActivityPub (#32007)
This commit is contained in:
		
							
								
								
									
										36
									
								
								app/controllers/activitypub/likes_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/controllers/activitypub/likes_controller.rb
									
									
									
									
									
										Normal 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
 | 
			
		||||
@@ -12,7 +12,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
 | 
			
		||||
  before_action :set_replies
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								app/controllers/activitypub/shares_controller.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/controllers/activitypub/shares_controller.rb
									
									
									
									
									
										Normal 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
 | 
			
		||||
@@ -74,6 +74,18 @@ class ActivityPub::TagManager
 | 
			
		||||
    account_status_replies_url(target.account, target, page_params)
 | 
			
		||||
  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)
 | 
			
		||||
    target.local? ? account_followers_url(target) : target.followers_url.presence
 | 
			
		||||
  end
 | 
			
		||||
 
 | 
			
		||||
@@ -19,6 +19,8 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
 | 
			
		||||
  has_many :virtual_tags, key: :tag
 | 
			
		||||
 | 
			
		||||
  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: :any_of, if: :poll_and_multiple?
 | 
			
		||||
@@ -64,6 +66,22 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
 | 
			
		||||
    )
 | 
			
		||||
  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?
 | 
			
		||||
    object.language.present?
 | 
			
		||||
  end
 | 
			
		||||
 
 | 
			
		||||
@@ -126,6 +126,8 @@ Rails.application.routes.draw do
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      resources :replies, only: [:index], module: :activitypub
 | 
			
		||||
      resources :likes, only: [:index], module: :activitypub
 | 
			
		||||
      resources :shares, only: [:index], module: :activitypub
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    resources :followers, only: [:index], controller: :follower_accounts
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user