Skip to content

Commit

Permalink
Merge pull request #3497 from manyfold3d/activitypub-presenters
Browse files Browse the repository at this point in the history
Refactor ActivityPub rendering code into presenters
  • Loading branch information
Floppy authored Jan 28, 2025
2 parents 2dfe6ba + 832f079 commit 0a66ed9
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 58 deletions.
43 changes: 6 additions & 37 deletions app/models/comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,18 @@ class Comment < ApplicationRecord
belongs_to :commentable, polymorphic: true

include Federails::DataEntity
acts_as_federails_data handles: "Note", actor_entity_method: :commenter, url_param: :public_id, should_federate_method: :public?
acts_as_federails_data handles: "Note", actor_entity_method: :commenter, url_param: :public_id, should_federate_method: :federate?

def to_activitypub_object
# Comments become Notes in ActvityPub
Federails::DataTransformer::Note.to_federation self, content: to_html,
custom: {
"context" => Rails.application.routes.url_helpers.url_for([commentable, only_path: false]),
"sensitive" => sensitive,
"tag" => activitypub_tags
}.merge(address_options)
ActivityPub::CommentPresenter.new(self).present!
end

def federate?
ActivityPub::CommentPresenter.new(self).federate?
end

def public?
Pundit::PolicyFinder.new(commenter.class).policy.new(nil, commenter).show? &&
Pundit::PolicyFinder.new(commentable.class).policy.new(nil, commentable).show?
end

private

def activitypub_tags
return nil unless commentable.respond_to?(:tags)
commentable.tags.pluck(:name).map do |tag|
{
type: "Hashtag",
name: "##{tag.tr(" ", "_").camelize}",
href: Rails.application.routes.url_helpers.url_for([commentable.class, tag: tag])
}
end
end

def to_html
[
Kramdown::Document.new(comment).to_html,
activitypub_tags&.map { |t| %(<a href="#{t[:href]}" class="mention hashtag" rel="tag">#{t[:name]}</a>) }&.join(" ")
].compact.join("\n\n")
end

def address_options
public? ?
{
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [commenter.federails_actor.followers_url]
}
: {}
end
end
22 changes: 1 addition & 21 deletions app/models/creator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ def self.find_param(param)
find_by!(slug: param)
end

def summary_html
return unless caption || notes
"<section>#{"<header>#{caption}</header>" if caption}#{Kramdown::Document.new(notes).to_html.rstrip if notes}</section>"
end

def self.create_from_activitypub_object(actor)
matches = actor.extensions["summary"].match(/<section><header>(.+)<\/header><p>(.+)<\/p><\/section>/)
create(
Expand All @@ -45,21 +40,6 @@ def self.create_from_activitypub_object(actor)
end

def to_activitypub_object
{
"@context": {
f3di: "http://purl.org/f3di/ns#",
toot: "http://joinmastodon.org/ns#",
attributionDomains: {
"@id": "toot:attributionDomains",
"@type": "@id"
}
},
summary: summary_html,
attributionDomains: [
[Rails.application.default_url_options[:host], Rails.application.default_url_options[:port]].compact.join(":")
],
"f3di:concreteType": "Creator",
attachment: links.map { |it| {type: "Link", href: it.url} }
}
ActivityPub::CreatorPresenter.new(self).present!
end
end
49 changes: 49 additions & 0 deletions app/presenters/activity_pub/base_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module ActivityPub
class BasePresenter
PUBLIC_COLLECTION = "https://www.w3.org/ns/activitystreams#Public"

def initialize(object)
@object = object
end

def present!
raise NotImplementedError
end

def federate?
true
end

def to
nil
end

def bto
nil
end

def cc
nil
end

def bcc
nil
end

def audience
nil
end

protected

def address_fields
{
"to" => to,
"bto" => bto,
"cc" => cc,
"bcc" => bcc,
"audience" => audience
}.compact
end
end
end
48 changes: 48 additions & 0 deletions app/presenters/activity_pub/comment_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
module ActivityPub
class CommentPresenter < BasePresenter
def present!
Federails::DataTransformer::Note.to_federation(
@object,
content: to_html,
custom: {
"context" => Rails.application.routes.url_helpers.url_for([@object.commentable, {only_path: false}]),
"sensitive" => @object.sensitive,
"tag" => hashtags
}.merge(address_fields)
)
end

def federate?
@object.public?
end

def to
PUBLIC_COLLECTION if @object.public?
end

def cc
@object.commenter.federails_actor.followers_url
end

private

def hashtags
return nil unless @object.commentable.respond_to?(:tags)

@object.commentable.tags.pluck(:name).map do |tag|
{
type: "Hashtag",
name: "##{tag.tr(" ", "_").camelize}",
href: Rails.application.routes.url_helpers.url_for([@object.commentable.class, {tag: tag}])
}
end
end

def to_html
[
Kramdown::Document.new(@object.comment).to_html,
hashtags&.map { |t| %(<a href="#{t[:href]}" class="mention hashtag" rel="tag">#{t[:name]}</a>) }&.join(" ")
].compact.join("\n\n")
end
end
end
46 changes: 46 additions & 0 deletions app/presenters/activity_pub/creator_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module ActivityPub
class CreatorPresenter < BasePresenter
def present!
{
"@context": {
f3di: "http://purl.org/f3di/ns#",
toot: "http://joinmastodon.org/ns#",
attributionDomains: {
"@id": "toot:attributionDomains",
"@type": "@id"
}
},
summary: summary_html,
attributionDomains: [
[Rails.application.default_url_options[:host], Rails.application.default_url_options[:port]].compact.join(":")
],
"f3di:concreteType": "Creator",
attachment: @object.links.map { |it| {type: "Link", href: it.url} }
}.merge(address_fields)
end

def federate?
# Currently unused
public?
end

def to
PUBLIC_COLLECTION if public?
end

def cc
@object.federails_actor.followers_url
end

private

def public?
CreatorPolicy.new(nil, @object).show?
end

def summary_html
return unless @object.caption || @object.notes
"<section>#{"<header>#{@object.caption}</header>" if @object.caption}#{Kramdown::Document.new(@object.notes).to_html.rstrip if @object.notes}</section>"
end
end
end

0 comments on commit 0a66ed9

Please sign in to comment.