Federate and store a collection url (#38697)
This commit is contained in:
parent
543db6d24c
commit
fee38e57f0
@ -15,6 +15,7 @@
|
|||||||
# original_number_of_items :integer
|
# original_number_of_items :integer
|
||||||
# sensitive :boolean not null
|
# sensitive :boolean not null
|
||||||
# uri :string
|
# uri :string
|
||||||
|
# url :string
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
# account_id :bigint(8) not null
|
# account_id :bigint(8) not null
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ActivityPub::FeaturedCollectionSerializer < ActivityPub::Serializer
|
class ActivityPub::FeaturedCollectionSerializer < ActivityPub::Serializer
|
||||||
attributes :id, :type, :total_items, :name, :attributed_to,
|
# include Rails.application.routes.url_helpers
|
||||||
|
include RoutingHelper
|
||||||
|
|
||||||
|
attributes :id, :type, :total_items, :name, :attributed_to, :url,
|
||||||
:sensitive, :discoverable, :published, :updated
|
:sensitive, :discoverable, :published, :updated
|
||||||
|
|
||||||
attribute :summary, unless: :language_present?
|
attribute :summary, unless: :language_present?
|
||||||
attribute :summary_map, if: :language_present?
|
attribute :summary_map, if: :language_present?
|
||||||
|
|
||||||
has_one :tag, key: :topic, serializer: ActivityPub::NoteSerializer::TagSerializer
|
has_one :topic, serializer: ActivityPub::NoteSerializer::TagSerializer
|
||||||
|
|
||||||
has_many :collection_items, key: :ordered_items, serializer: ActivityPub::FeaturedItemSerializer
|
has_many :collection_items, key: :ordered_items, serializer: ActivityPub::FeaturedItemSerializer
|
||||||
|
|
||||||
@ -31,6 +34,10 @@ class ActivityPub::FeaturedCollectionSerializer < ActivityPub::Serializer
|
|||||||
ActivityPub::TagManager.instance.uri_for(object.account)
|
ActivityPub::TagManager.instance.uri_for(object.account)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
account_collection_url(object.account, object)
|
||||||
|
end
|
||||||
|
|
||||||
def total_items
|
def total_items
|
||||||
object.accepted_collection_items.size
|
object.accepted_collection_items.size
|
||||||
end
|
end
|
||||||
@ -50,4 +57,8 @@ class ActivityPub::FeaturedCollectionSerializer < ActivityPub::Serializer
|
|||||||
def collection_items
|
def collection_items
|
||||||
object.accepted_collection_items
|
object.accepted_collection_items
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def topic
|
||||||
|
object.tag
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -46,6 +46,13 @@ class ActivityPub::ProcessFeaturedCollectionService
|
|||||||
@json['summaryMap']&.keys&.first
|
@json['summaryMap']&.keys&.first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
url = url_to_href(@json['url'], 'text/html')
|
||||||
|
return @json['id'] if url.blank? || unsupported_uri_scheme?(url)
|
||||||
|
|
||||||
|
url
|
||||||
|
end
|
||||||
|
|
||||||
def collection_attributes
|
def collection_attributes
|
||||||
{
|
{
|
||||||
local: false,
|
local: false,
|
||||||
@ -56,6 +63,7 @@ class ActivityPub::ProcessFeaturedCollectionService
|
|||||||
discoverable: @json['discoverable'],
|
discoverable: @json['discoverable'],
|
||||||
original_number_of_items: @json['totalItems'] || 0,
|
original_number_of_items: @json['totalItems'] || 0,
|
||||||
tag_name: @json.dig('topic', 'name'),
|
tag_name: @json.dig('topic', 'name'),
|
||||||
|
url:,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
7
db/migrate/20260415133505_add_url_to_collections.rb
Normal file
7
db/migrate/20260415133505_add_url_to_collections.rb
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddURLToCollections < ActiveRecord::Migration[8.1]
|
||||||
|
def change
|
||||||
|
add_column :collections, :url, :string
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.1].define(version: 2026_04_10_083500) do
|
ActiveRecord::Schema[8.1].define(version: 2026_04_15_133505) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_catalog.plpgsql"
|
enable_extension "pg_catalog.plpgsql"
|
||||||
|
|
||||||
@ -400,6 +400,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_04_10_083500) do
|
|||||||
t.bigint "tag_id"
|
t.bigint "tag_id"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.string "uri"
|
t.string "uri"
|
||||||
|
t.string "url"
|
||||||
t.index ["account_id"], name: "index_collections_on_account_id"
|
t.index ["account_id"], name: "index_collections_on_account_id"
|
||||||
t.index ["tag_id"], name: "index_collections_on_tag_id"
|
t.index ["tag_id"], name: "index_collections_on_tag_id"
|
||||||
t.index ["uri"], name: "index_collections_on_uri", unique: true, where: "(uri IS NOT NULL)"
|
t.index ["uri"], name: "index_collections_on_uri", unique: true, where: "(uri IS NOT NULL)"
|
||||||
|
|||||||
@ -25,6 +25,7 @@ RSpec.describe ActivityPub::FeaturedCollectionSerializer do
|
|||||||
'attributedTo' => ActivityPub::TagManager.instance.uri_for(collection.account),
|
'attributedTo' => ActivityPub::TagManager.instance.uri_for(collection.account),
|
||||||
'sensitive' => false,
|
'sensitive' => false,
|
||||||
'discoverable' => false,
|
'discoverable' => false,
|
||||||
|
'url' => account_collection_url(collection.account, collection),
|
||||||
'topic' => {
|
'topic' => {
|
||||||
'href' => match(%r{/tags/people$}),
|
'href' => match(%r{/tags/people$}),
|
||||||
'type' => 'Hashtag',
|
'type' => 'Hashtag',
|
||||||
|
|||||||
@ -16,6 +16,7 @@ RSpec.describe ActivityPub::ProcessFeaturedCollectionService do
|
|||||||
'name' => 'Good people from other servers',
|
'name' => 'Good people from other servers',
|
||||||
'sensitive' => false,
|
'sensitive' => false,
|
||||||
'discoverable' => true,
|
'discoverable' => true,
|
||||||
|
'url' => 'https://example.com/c/1',
|
||||||
'topic' => {
|
'topic' => {
|
||||||
'type' => 'Hashtag',
|
'type' => 'Hashtag',
|
||||||
'name' => '#people',
|
'name' => '#people',
|
||||||
@ -50,6 +51,7 @@ RSpec.describe ActivityPub::ProcessFeaturedCollectionService do
|
|||||||
expect(new_collection.description_html).to eq '<p>A list of remote actors you should follow.</p>'
|
expect(new_collection.description_html).to eq '<p>A list of remote actors you should follow.</p>'
|
||||||
expect(new_collection.sensitive).to be false
|
expect(new_collection.sensitive).to be false
|
||||||
expect(new_collection.discoverable).to be true
|
expect(new_collection.discoverable).to be true
|
||||||
|
expect(new_collection.url).to eq 'https://example.com/c/1'
|
||||||
expect(new_collection.tag.formatted_name).to eq '#people'
|
expect(new_collection.tag.formatted_name).to eq '#people'
|
||||||
|
|
||||||
expect(ActivityPub::ProcessFeaturedItemWorker).to have_enqueued_sidekiq_job.with(new_collection.id, 'https://example.com/featured_items/1', 1, nil)
|
expect(ActivityPub::ProcessFeaturedItemWorker).to have_enqueued_sidekiq_job.with(new_collection.id, 'https://example.com/featured_items/1', 1, nil)
|
||||||
@ -75,6 +77,18 @@ RSpec.describe ActivityPub::ProcessFeaturedCollectionService do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the json does not include a `url`' do
|
||||||
|
let(:featured_collection_json) do
|
||||||
|
base_json.except('url')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses the `id` instead' do
|
||||||
|
subject.call(account, featured_collection_json)
|
||||||
|
|
||||||
|
expect(Collection.last.url).to eq 'https://example.com/featured_collections/1'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the collection already exists' do
|
context 'when the collection already exists' do
|
||||||
let(:collection) { Fabricate(:remote_collection, account:, uri: base_json['id'], name: 'placeholder') }
|
let(:collection) { Fabricate(:remote_collection, account:, uri: base_json['id'], name: 'placeholder') }
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user