about summary refs log tree commit diff
path: root/app/services
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2018-03-04 09:19:11 +0100
committerGitHub <noreply@github.com>2018-03-04 09:19:11 +0100
commit9110db41c53a2f3f22affc23b364362133997d3e (patch)
tree16c5c7428bdd04831e85b09f6c0bc3e50258b7e3 /app/services
parent45feb439bd22c0999b8531879461e8d18fabe8a5 (diff)
Federate pinned statuses over ActivityPub (#6610)
* Federate pinned statuses over ActivityPub

* Display pinned toots in web UI

Fix #6117

* Fix migration

* Fix tests

* Update outbox_serializer.rb

* Update remove_serializer.rb

* Update add_serializer.rb

* Update fetch_featured_collection_service.rb
Diffstat (limited to 'app/services')
-rw-r--r--app/services/activitypub/fetch_featured_collection_service.rb52
-rw-r--r--app/services/activitypub/process_account_service.rb22
2 files changed, 66 insertions, 8 deletions
diff --git a/app/services/activitypub/fetch_featured_collection_service.rb b/app/services/activitypub/fetch_featured_collection_service.rb
new file mode 100644
index 000000000..40714e980
--- /dev/null
+++ b/app/services/activitypub/fetch_featured_collection_service.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+class ActivityPub::FetchFeaturedCollectionService < BaseService
+  include JsonLdHelper
+
+  def call(account)
+    @account = account
+    @json    = fetch_resource(@account.featured_collection_url, true)
+
+    return unless supported_context?
+    return if @account.suspended? || @account.local?
+
+    case @json['type']
+    when 'Collection', 'CollectionPage'
+      process_items @json['items']
+    when 'OrderedCollection', 'OrderedCollectionPage'
+      process_items @json['orderedItems']
+    end
+  end
+
+  private
+
+  def process_items(items)
+    status_ids = items.map { |item| value_or_id(item) }
+                      .reject { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }
+                      .map { |uri| ActivityPub::FetchRemoteStatusService.new.call(uri) }
+                      .compact
+                      .select { |status| status.account_id == @account.id }
+                      .map(&:id)
+
+    to_remove = []
+    to_add    = status_ids
+
+    StatusPin.where(account: @account).pluck(:status_id).each do |status_id|
+      if status_ids.include?(status_id)
+        to_add.delete(status_id)
+      else
+        to_remove << status_id
+      end
+    end
+
+    StatusPin.where(account: @account, status_id: to_remove).delete_all unless to_remove.empty?
+
+    to_add.each do |status_id|
+      StatusPin.create!(account: @account, status_id: status_id)
+    end
+  end
+
+  def supported_context?
+    super(@json)
+  end
+end
diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb
index f43edafe7..68e9db766 100644
--- a/app/services/activitypub/process_account_service.rb
+++ b/app/services/activitypub/process_account_service.rb
@@ -27,6 +27,7 @@ class ActivityPub::ProcessAccountService < BaseService
 
     after_protocol_change! if protocol_changed?
     after_key_change! if key_changed?
+    check_featured_collection! if @account.featured_collection_url.present?
 
     @account
   rescue Oj::ParseError
@@ -57,14 +58,15 @@ class ActivityPub::ProcessAccountService < BaseService
   end
 
   def set_immediate_attributes!
-    @account.inbox_url        = @json['inbox'] || ''
-    @account.outbox_url       = @json['outbox'] || ''
-    @account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || ''
-    @account.followers_url    = @json['followers'] || ''
-    @account.url              = url || @uri
-    @account.display_name     = @json['name'] || ''
-    @account.note             = @json['summary'] || ''
-    @account.locked           = @json['manuallyApprovesFollowers'] || false
+    @account.inbox_url               = @json['inbox'] || ''
+    @account.outbox_url              = @json['outbox'] || ''
+    @account.shared_inbox_url        = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || ''
+    @account.followers_url           = @json['followers'] || ''
+    @account.featured_collection_url = @json['featured'] || ''
+    @account.url                     = url || @uri
+    @account.display_name            = @json['name'] || ''
+    @account.note                    = @json['summary'] || ''
+    @account.locked                  = @json['manuallyApprovesFollowers'] || false
   end
 
   def set_fetchable_attributes!
@@ -85,6 +87,10 @@ class ActivityPub::ProcessAccountService < BaseService
     RefollowWorker.perform_async(@account.id)
   end
 
+  def check_featured_collection!
+    ActivityPub::SynchronizeFeaturedCollectionWorker.perform_async(@account.id)
+  end
+
   def image_url(key)
     value = first_of_value(@json[key])