about summary refs log tree commit diff
path: root/app/serializers
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-07-15 03:01:39 +0200
committerGitHub <noreply@github.com>2017-07-15 03:01:39 +0200
commit8c45cd0e3683b528b65f416681c8272d5650f32d (patch)
treeaee4a1e6d339446f7d9cc59fab61547353b89e56 /app/serializers
parent3fbf1bf35acf89d1e397fa2e632529bf5105fe02 (diff)
Improve ActivityPub representations (#3844)
* Improve webfinger templates and make tests more flexible

* Clean up AS2 representation of actor

* Refactor outbox

* Create activities representation

* Add representations of followers/following collections, do not redirect /users/:username route if format is empty

* Remove unused translations

* ActivityPub endpoint for single statuses, add ActivityPub::TagManager for better
URL/URI generation

* Add ActivityPub::TagManager#to

* Represent all attachments as Document instead of Image/Video specifically
(Because for remote ones we may not know for sure)

Add mentions and hashtags representation to AP notes

* Add AP-resolvable hashtag URIs

* Use ActiveModelSerializers for ActivityPub

* Clean up unused translations

* Separate route for object and activity

* Adjust cc/to matrices

* Add to/cc to activities, ensure announce activity embeds target status and
not the wrapper status, add "id" to all collections
Diffstat (limited to 'app/serializers')
-rw-r--r--app/serializers/activitypub/activity_serializer.rb27
-rw-r--r--app/serializers/activitypub/actor_serializer.rb53
-rw-r--r--app/serializers/activitypub/collection_serializer.rb26
-rw-r--r--app/serializers/activitypub/note_serializer.rb106
4 files changed, 212 insertions, 0 deletions
diff --git a/app/serializers/activitypub/activity_serializer.rb b/app/serializers/activitypub/activity_serializer.rb
new file mode 100644
index 000000000..69e2160c5
--- /dev/null
+++ b/app/serializers/activitypub/activity_serializer.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ActivityPub::ActivitySerializer < ActiveModel::Serializer
+  attributes :id, :type, :actor, :to, :cc
+
+  has_one :proper, key: :object, serializer: ActivityPub::NoteSerializer
+
+  def id
+    [ActivityPub::TagManager.instance.uri_for(object), '/activity'].join
+  end
+
+  def type
+    object.reblog? ? 'Announce' : 'Create'
+  end
+
+  def actor
+    ActivityPub::TagManager.instance.uri_for(object.account)
+  end
+
+  def to
+    ActivityPub::TagManager.instance.to(object)
+  end
+
+  def cc
+    ActivityPub::TagManager.instance.cc(object)
+  end
+end
diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb
new file mode 100644
index 000000000..56806152e
--- /dev/null
+++ b/app/serializers/activitypub/actor_serializer.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+class ActivityPub::ActorSerializer < ActiveModel::Serializer
+  include RoutingHelper
+
+  attributes :id, :type, :following, :followers,
+             :inbox, :outbox, :preferred_username,
+             :name, :summary, :icon, :image
+
+  def id
+    account_url(object)
+  end
+
+  def type
+    'Person'
+  end
+
+  def following
+    account_following_index_url(object)
+  end
+
+  def followers
+    account_followers_url(object)
+  end
+
+  def inbox
+    nil
+  end
+
+  def outbox
+    account_outbox_url(object)
+  end
+
+  def preferred_username
+    object.username
+  end
+
+  def name
+    object.display_name
+  end
+
+  def summary
+    Formatter.instance.simplified_format(object)
+  end
+
+  def icon
+    full_asset_url(object.avatar.url(:original))
+  end
+
+  def image
+    full_asset_url(object.header.url(:original))
+  end
+end
diff --git a/app/serializers/activitypub/collection_serializer.rb b/app/serializers/activitypub/collection_serializer.rb
new file mode 100644
index 000000000..baaba7654
--- /dev/null
+++ b/app/serializers/activitypub/collection_serializer.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class ActivityPub::CollectionSerializer < ActiveModel::Serializer
+  def self.serializer_for(model, options)
+    return ActivityPub::ActivitySerializer if model.class.name == 'Status'
+    super
+  end
+
+  attributes :id, :type, :total_items,
+             :current
+
+  has_many :items, key: :ordered_items
+
+  def type
+    case object.type
+    when :ordered
+      'OrderedCollection'
+    else
+      'Collection'
+    end
+  end
+
+  def total_items
+    object.size
+  end
+end
diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb
new file mode 100644
index 000000000..ffdc6175d
--- /dev/null
+++ b/app/serializers/activitypub/note_serializer.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+class ActivityPub::NoteSerializer < ActiveModel::Serializer
+  attributes :id, :type, :summary, :content,
+             :in_reply_to, :published, :url,
+             :actor, :to, :cc, :sensitive
+
+  has_many :media_attachments, key: :attachment
+  has_many :virtual_tags, key: :tag
+
+  def id
+    ActivityPub::TagManager.instance.uri_for(object)
+  end
+
+  def type
+    'Note'
+  end
+
+  def summary
+    object.spoiler_text.presence
+  end
+
+  def content
+    Formatter.instance.format(object)
+  end
+
+  def in_reply_to
+    ActivityPub::TagManager.instance.uri_for(object.thread) if object.reply?
+  end
+
+  def published
+    object.created_at.iso8601
+  end
+
+  def url
+    ActivityPub::TagManager.instance.url_for(object)
+  end
+
+  def actor
+    ActivityPub::TagManager.instance.uri_for(object.account)
+  end
+
+  def to
+    ActivityPub::TagManager.instance.to(object)
+  end
+
+  def cc
+    ActivityPub::TagManager.instance.cc(object)
+  end
+
+  def virtual_tags
+    object.mentions + object.tags
+  end
+
+  class MediaAttachmentSerializer < ActiveModel::Serializer
+    include RoutingHelper
+
+    attributes :type, :media_type, :url
+
+    def type
+      'Document'
+    end
+
+    def media_type
+      object.file_content_type
+    end
+
+    def url
+      object.local? ? full_asset_url(object.file.url(:original, false)) : object.remote_url
+    end
+  end
+
+  class MentionSerializer < ActiveModel::Serializer
+    attributes :type, :href, :name
+
+    def type
+      'Mention'
+    end
+
+    def href
+      ActivityPub::TagManager.instance.uri_for(object.account)
+    end
+
+    def name
+      "@#{object.account.acct}"
+    end
+  end
+
+  class TagSerializer < ActiveModel::Serializer
+    include RoutingHelper
+
+    attributes :type, :href, :name
+
+    def type
+      'Hashtag'
+    end
+
+    def href
+      tag_url(object)
+    end
+
+    def name
+      "##{object.name}"
+    end
+  end
+end