about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-09-08 12:00:17 +0200
committerGitHub <noreply@github.com>2017-09-08 12:00:17 +0200
commita4caa7eb6258ff7f8eea8e6791b86b1c7f4d172e (patch)
tree73618aed49160ece71b17df7fef4efa7a0dd261a
parent7c2d84910cf427787b9fea2bdba67ec426c0b97d (diff)
Fetch statuses/following/followers numbers from ActivityPub collections (#4840)
-rw-r--r--app/services/activitypub/process_account_service.rb37
-rw-r--r--spec/lib/activitypub/activity/update_spec.rb8
-rw-r--r--spec/services/activitypub/fetch_remote_account_service_spec.rb2
3 files changed, 39 insertions, 8 deletions
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index 29eb1c2e1..c63577fe5 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -8,11 +8,12 @@ class ActivityPub::ProcessAccountService < BaseService
   def call(username, domain, json)
     return if json['inbox'].blank?
 
-    @json     = json
-    @uri      = @json['id']
-    @username = username
-    @domain   = domain
-    @account  = Account.find_by(uri: @uri)
+    @json        = json
+    @uri         = @json['id']
+    @username    = username
+    @domain      = domain
+    @account     = Account.find_by(uri: @uri)
+    @collections = {}
 
     create_account  if @account.nil?
     upgrade_account if @account.ostatus?
@@ -51,6 +52,9 @@ class ActivityPub::ProcessAccountService < BaseService
     @account.header_remote_url   = image_url('image')
     @account.public_key          = public_key || ''
     @account.locked              = @json['manuallyApprovesFollowers'] || false
+    @account.statuses_count      = outbox_total_items    if outbox_total_items.present?
+    @account.following_count     = following_total_items if following_total_items.present?
+    @account.followers_count     = followers_total_items if followers_total_items.present?
     @account.save!
   end
 
@@ -88,6 +92,29 @@ class ActivityPub::ProcessAccountService < BaseService
     value['href']
   end
 
+  def outbox_total_items
+    collection_total_items('outbox')
+  end
+
+  def following_total_items
+    collection_total_items('following')
+  end
+
+  def followers_total_items
+    collection_total_items('followers')
+  end
+
+  def collection_total_items(type)
+    return if @json[type].blank?
+    return @collections[type] if @collections.key?(type)
+
+    collection = fetch_resource(@json[type])
+
+    @collections[type] = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil
+  rescue HTTP::Error, OpenSSL::SSL::SSLError
+    @collections[type] = nil
+  end
+
   def auto_suspend?
     domain_block && domain_block.suspend?
   end
diff --git a/spec/lib/activitypub/activity/update_spec.rb b/spec/lib/activitypub/activity/update_spec.rb
index 0bd6d00d9..ea308e35c 100644
--- a/spec/lib/activitypub/activity/update_spec.rb
+++ b/spec/lib/activitypub/activity/update_spec.rb
@@ -2,12 +2,16 @@ require 'rails_helper'
 
 RSpec.describe ActivityPub::Activity::Update do
   let!(:sender) { Fabricate(:account) }
-  
+
   before do
+    stub_request(:get, actor_json[:outbox]).to_return(status: 404)
+    stub_request(:get, actor_json[:followers]).to_return(status: 404)
+    stub_request(:get, actor_json[:following]).to_return(status: 404)
+
     sender.update!(uri: ActivityPub::TagManager.instance.uri_for(sender))
   end
 
-  let(:modified_sender) do 
+  let(:modified_sender) do
     sender.dup.tap do |modified_sender|
       modified_sender.display_name = 'Totally modified now'
     end
diff --git a/spec/services/activitypub/fetch_remote_account_service_spec.rb b/spec/services/activitypub/fetch_remote_account_service_spec.rb
index 391d051c1..ed7e9bba8 100644
--- a/spec/services/activitypub/fetch_remote_account_service_spec.rb
+++ b/spec/services/activitypub/fetch_remote_account_service_spec.rb
@@ -41,7 +41,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do
 
       before do
         actor[:inbox] = nil
-        
+
         stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor))
         stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
       end