Skip to content

Commit

Permalink
Merge pull request #3398 from manyfold3d/federails-data-entities
Browse files Browse the repository at this point in the history
Refactor comment code to use new Federails data entity system
  • Loading branch information
Floppy authored Jan 14, 2025
2 parents 49a3970 + 1db15ee commit f0f3bba
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 72 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ gem "better_content_security_policy", "~> 0.1.4"
gem "devise_zxcvbn", "~> 6.0"

gem "ransack", "~> 4.2"
gem "federails", "~> 0.4"
gem "federails", git: "https://gitlab.com/experimentslabs/federails", branch: "22-data-binding-for-incoming-outgoing-objects"
gem "federails-moderation", "~> 0.2"
gem "caber"

Expand Down
24 changes: 15 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,20 @@ GIT
activerecord (>= 3.2)
sqlite3

GIT
remote: https://gitlab.com/experimentslabs/federails
revision: e366dc4ff8aa34f7884547180bc94998d320423a
branch: 22-data-binding-for-incoming-outgoing-objects
specs:
federails (0.4.0)
faraday
faraday-follow_redirects
json-ld (>= 3.2.0)
json-ld-preloaded (>= 3.2.0)
kaminari (>= 1.2.0)
pundit (>= 2.3.0)
rails (>= 7.0.4)

GEM
remote: https://rubygems.org/
specs:
Expand Down Expand Up @@ -224,14 +238,6 @@ GEM
faraday (>= 1, < 3)
faraday-net_http (3.4.0)
net-http (>= 0.5.0)
federails (0.4.0)
faraday
faraday-follow_redirects
json-ld (>= 3.2.0)
json-ld-preloaded (>= 3.2.0)
kaminari (>= 1.2.0)
pundit (>= 2.3.0)
rails (>= 7.0.4)
federails-moderation (0.2.0)
federails (~> 0.4)
public_suffix (~> 6.0)
Expand Down Expand Up @@ -792,7 +798,7 @@ DEPENDENCIES
erb_lint (~> 0.8.0)
factory_bot
faker (~> 3.5)
federails (~> 0.4)
federails!
federails-moderation (~> 0.2)
ffi-libarchive (~> 1.1)
get_process_mem (~> 1.0)
Expand Down
80 changes: 33 additions & 47 deletions app/models/comment.rb
Original file line number Diff line number Diff line change
@@ -1,45 +1,22 @@
require "federails/data_transformer/note"

class Comment < ApplicationRecord
include PublicIDable

belongs_to :commenter, polymorphic: true
belongs_to :commenter, polymorphic: true, optional: true
belongs_to :commentable, polymorphic: true

after_create :post_create_activity
after_update :post_update_activity

def federated_url
return nil unless public?
Rails.application.routes.url_helpers.url_for([commentable, self, {only_path: false}])
end
include Federails::DataEntity
acts_as_federails_data handles: "Note", actor_entity_method: :commenter, url_param: :public_id, should_federate_method: :public?

def to_activitypub_object
# Build tag structure
tags = 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
: nil
tag_html = tags&.map { |t| %(<a href="#{t[:href]}" class="mention hashtag" rel="tag">#{t[:name]}</a>) }&.join(" ")
# Comments become Notes in ActvityPub world
{
id: federated_url,
type: "Note",
content: [
Kramdown::Document.new(comment).to_html,
tag_html
].compact.join("\n\n"),
context: Rails.application.routes.url_helpers.url_for([commentable, only_path: false]),
published: created_at&.iso8601,
attributedTo: (commenter&.federails_actor&.respond_to?(:federated_url) ? commenter.federails_actor.federated_url : nil),
sensitive: sensitive,
to: ["https://www.w3.org/ns/activitystreams#Public"],
cc: [commenter.federails_actor.followers_url],
tag: tags
}.compact
# 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)
end

def public?
Expand All @@ -49,21 +26,30 @@ def public?

private

def post_create_activity
post_activity "Create"
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 post_update_activity
post_activity "Update"
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 post_activity(action)
if public?
Federails::Activity.create!(
actor: commenter.federails_actor,
action: action,
entity: self
)
end
def address_options
public? ?
{
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
"cc" => [commenter.federails_actor.followers_url]
}
: {}
end
end
10 changes: 10 additions & 0 deletions db/migrate/20250114105808_add_federation_attributes_to_comments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class AddFederationAttributesToComments < ActiveRecord::Migration[7.2]
def change
# Commenter is now optional
change_column_null :comments, :commenter_id, true
change_column_null :comments, :commenter_type, true
# New columns for federation work
add_column :comments, :federated_url, :string, null: true, default: nil
add_reference :comments, :federails_actor, null: true, foreign_key: true
end
end
10 changes: 7 additions & 3 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 12 additions & 12 deletions spec/models/comment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,57 +25,57 @@
end

it "has a federated_url method" do
expect(comment.federated_url).to eq "http://localhost:3214/models/#{commentable.public_id}/comments/#{comment.public_id}"
expect(comment.federated_url).to eq "http://localhost:3214/federation/objects/comments/#{comment.public_id}"
end

context "when serializing to an ActivityPub Note" do
let(:ap_object) { comment.to_activitypub_object }

it "creates a Note" do
expect(ap_object[:type]).to eq "Note"
expect(ap_object["type"]).to eq "Note"
end

it "includes content" do
expect(ap_object[:content]).to be_present
expect(ap_object["content"]).to be_present
end

it "includes id" do
expect(ap_object[:id]).to eq comment.federated_url
expect(ap_object["id"]).to eq comment.federated_url
end

it "includes commentable ID in context" do
expect(ap_object[:context]).to eq "http://localhost:3214/models/#{commentable.public_id}"
expect(ap_object["context"]).to eq "http://localhost:3214/models/#{commentable.public_id}"
end

it "includes publication time" do
expect(ap_object[:published]).to be_present
expect(ap_object["published"]).to be_present
end

it "includes sensitive flag" do
expect(ap_object[:sensitive]).to be true
expect(ap_object["sensitive"]).to be true
end

it "includes attribution" do
expect(ap_object[:attributedTo]).to eq commenter.federails_actor.federated_url
expect(ap_object["attributedTo"]).to eq commenter.federails_actor.federated_url
end

it "includes to field" do
expect(ap_object[:to]).to include "https://www.w3.org/ns/activitystreams#Public"
expect(ap_object["to"]).to include "https://www.w3.org/ns/activitystreams#Public"
end

it "includes cc field" do
expect(ap_object[:cc]).to include commenter.federails_actor.followers_url
expect(ap_object["cc"]).to include commenter.federails_actor.followers_url
end

it "includes tags appended to content" do
{"tag+one": "#TagOne", tag2: "#Tag2"}.each_pair do |link, hashtag|
expect(ap_object[:content]).to include %(<a href="http://localhost:3214/models?tag=#{link}" class="mention hashtag" rel="tag">#{hashtag}</a>)
expect(ap_object["content"]).to include %(<a href="http://localhost:3214/models?tag=#{link}" class="mention hashtag" rel="tag">#{hashtag}</a>)
end
end

it "includes tags as mentions" do # rubocop:disable RSpec/ExampleLength
{"tag+one": "#TagOne", tag2: "#Tag2"}.each_pair do |link, hashtag|
expect(ap_object[:tag]).to include(
expect(ap_object["tag"]).to include(
type: "Hashtag",
href: "http://localhost:3214/models?tag=#{link}",
name: hashtag
Expand Down

0 comments on commit f0f3bba

Please sign in to comment.