Add support for Update of converted object types (#36322)
This commit is contained in:
@@ -1,8 +1,6 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ActivityPub::Activity::Create < ActivityPub::Activity
|
class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
include FormattingHelper
|
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
@account.schedule_refresh_if_stale!
|
@account.schedule_refresh_if_stale!
|
||||||
|
|
||||||
@@ -99,9 +97,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||||||
uri: @status_parser.uri,
|
uri: @status_parser.uri,
|
||||||
url: @status_parser.url || @status_parser.uri,
|
url: @status_parser.url || @status_parser.uri,
|
||||||
account: @account,
|
account: @account,
|
||||||
text: converted_object_type? ? converted_text : (@status_parser.text || ''),
|
text: @status_parser.processed_text,
|
||||||
language: @status_parser.language,
|
language: @status_parser.language,
|
||||||
spoiler_text: converted_object_type? ? '' : (@status_parser.spoiler_text || ''),
|
spoiler_text: @status_parser.processed_spoiler_text,
|
||||||
created_at: @status_parser.created_at,
|
created_at: @status_parser.created_at,
|
||||||
edited_at: @status_parser.edited_at && @status_parser.edited_at != @status_parser.created_at ? @status_parser.edited_at : nil,
|
edited_at: @status_parser.edited_at && @status_parser.edited_at != @status_parser.created_at ? @status_parser.edited_at : nil,
|
||||||
override_timestamps: @options[:override_timestamps],
|
override_timestamps: @options[:override_timestamps],
|
||||||
@@ -405,18 +403,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||||||
value_or_id(@object['inReplyTo'])
|
value_or_id(@object['inReplyTo'])
|
||||||
end
|
end
|
||||||
|
|
||||||
def converted_text
|
|
||||||
[formatted_title, @status_parser.spoiler_text.presence, formatted_url].compact.join("\n\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
def formatted_title
|
|
||||||
"<h2>#{@status_parser.title}</h2>" if @status_parser.title.present?
|
|
||||||
end
|
|
||||||
|
|
||||||
def formatted_url
|
|
||||||
linkify(@status_parser.url || @status_parser.uri)
|
|
||||||
end
|
|
||||||
|
|
||||||
def unsupported_media_type?(mime_type)
|
def unsupported_media_type?(mime_type)
|
||||||
mime_type.present? && !MediaAttachment.supported_mime_types.include?(mime_type)
|
mime_type.present? && !MediaAttachment.supported_mime_types.include?(mime_type)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,10 +8,8 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
|
|||||||
|
|
||||||
if equals_or_includes_any?(@object['type'], %w(Application Group Organization Person Service))
|
if equals_or_includes_any?(@object['type'], %w(Application Group Organization Person Service))
|
||||||
update_account
|
update_account
|
||||||
elsif equals_or_includes_any?(@object['type'], %w(Note Question))
|
elsif supported_object_type? || converted_object_type?
|
||||||
update_status
|
update_status
|
||||||
elsif converted_object_type?
|
|
||||||
Status.find_by(uri: object_uri, account_id: @account.id)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ActivityPub::Parser::StatusParser
|
class ActivityPub::Parser::StatusParser
|
||||||
|
include FormattingHelper
|
||||||
include JsonLdHelper
|
include JsonLdHelper
|
||||||
|
|
||||||
NORMALIZED_LOCALE_NAMES = LanguagesHelper::SUPPORTED_LOCALES.keys.index_by(&:downcase).freeze
|
NORMALIZED_LOCALE_NAMES = LanguagesHelper::SUPPORTED_LOCALES.keys.index_by(&:downcase).freeze
|
||||||
@@ -44,6 +45,16 @@ class ActivityPub::Parser::StatusParser
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def processed_text
|
||||||
|
return text || '' unless converted_object_type?
|
||||||
|
|
||||||
|
[
|
||||||
|
title.presence && "<h2>#{title}</h2>",
|
||||||
|
spoiler_text.presence,
|
||||||
|
linkify(url || uri),
|
||||||
|
].compact.join("\n\n")
|
||||||
|
end
|
||||||
|
|
||||||
def spoiler_text
|
def spoiler_text
|
||||||
if @object['summary'].present?
|
if @object['summary'].present?
|
||||||
@object['summary']
|
@object['summary']
|
||||||
@@ -52,6 +63,12 @@ class ActivityPub::Parser::StatusParser
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def processed_spoiler_text
|
||||||
|
return '' if converted_object_type?
|
||||||
|
|
||||||
|
spoiler_text || ''
|
||||||
|
end
|
||||||
|
|
||||||
def title
|
def title
|
||||||
if @object['name'].present?
|
if @object['name'].present?
|
||||||
@object['name']
|
@object['name']
|
||||||
@@ -145,6 +162,10 @@ class ActivityPub::Parser::StatusParser
|
|||||||
as_array(@object['quoteAuthorization']).first
|
as_array(@object['quoteAuthorization']).first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def converted_object_type?
|
||||||
|
equals_or_includes_any?(@object['type'], ActivityPub::Activity::CONVERTED_TYPES)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def quote_subpolicy(subpolicy)
|
def quote_subpolicy(subpolicy)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
|||||||
@request_id = request_id
|
@request_id = request_id
|
||||||
@quote = nil
|
@quote = nil
|
||||||
|
|
||||||
# Only native types can be updated at the moment
|
|
||||||
return @status if !expected_type? || already_updated_more_recently?
|
return @status if !expected_type? || already_updated_more_recently?
|
||||||
|
|
||||||
if @status_parser.edited_at.present? && (@status.edited_at.nil? || @status_parser.edited_at > @status.edited_at)
|
if @status_parser.edited_at.present? && (@status.edited_at.nil? || @status_parser.edited_at > @status.edited_at)
|
||||||
@@ -170,8 +169,8 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def update_immediate_attributes!
|
def update_immediate_attributes!
|
||||||
@status.text = @status_parser.text || ''
|
@status.text = @status_parser.processed_text
|
||||||
@status.spoiler_text = @status_parser.spoiler_text || ''
|
@status.spoiler_text = @status_parser.processed_spoiler_text
|
||||||
@status.sensitive = @account.sensitized? || @status_parser.sensitive || false
|
@status.sensitive = @account.sensitized? || @status_parser.sensitive || false
|
||||||
@status.language = @status_parser.language
|
@status.language = @status_parser.language
|
||||||
|
|
||||||
@@ -351,7 +350,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
|||||||
end
|
end
|
||||||
|
|
||||||
def expected_type?
|
def expected_type?
|
||||||
equals_or_includes_any?(@json['type'], %w(Note Question))
|
equals_or_includes_any?(@json['type'], ActivityPub::Activity::SUPPORTED_TYPES) || equals_or_includes_any?(@json['type'], ActivityPub::Activity::CONVERTED_TYPES)
|
||||||
end
|
end
|
||||||
|
|
||||||
def record_previous_edit!
|
def record_previous_edit!
|
||||||
|
|||||||
@@ -149,18 +149,17 @@ RSpec.describe ActivityPub::Activity::Update do
|
|||||||
|
|
||||||
shared_examples 'updates counts' do
|
shared_examples 'updates counts' do
|
||||||
it 'updates the reblog count' do
|
it 'updates the reblog count' do
|
||||||
expect(status.untrusted_reblogs_count).to eq reblogs
|
expect { subject.perform }.to change { status.reload.untrusted_reblogs_count }.to(reblogs)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'updates the favourites count' do
|
it 'updates the favourites count' do
|
||||||
expect(status.untrusted_favourites_count).to eq favourites
|
expect { subject.perform }.to change { status.reload.untrusted_favourites_count }.to(favourites)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with an implicit update' do
|
context 'with an implicit update' do
|
||||||
before do
|
before do
|
||||||
status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
|
status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
|
||||||
subject.perform
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'updates counts'
|
it_behaves_like 'updates counts'
|
||||||
@@ -173,11 +172,89 @@ RSpec.describe ActivityPub::Activity::Update do
|
|||||||
|
|
||||||
before do
|
before do
|
||||||
status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
|
status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
|
||||||
subject.perform
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'updates counts'
|
it_behaves_like 'updates counts'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with an Article object' do
|
||||||
|
let(:updated) { nil }
|
||||||
|
let(:favourites) { 50 }
|
||||||
|
let(:reblogs) { 100 }
|
||||||
|
|
||||||
|
let!(:status) do
|
||||||
|
Fabricate(
|
||||||
|
:status,
|
||||||
|
uri: 'https://example.com/statuses/article',
|
||||||
|
account: sender,
|
||||||
|
text: "<h2>Future of the Fediverse</h2>\n\n<p>Guest article by John Mastodon</p><p>The fediverse is great reading this you will find out why!</p>"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:json) do
|
||||||
|
{
|
||||||
|
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||||
|
id: 'foo',
|
||||||
|
type: 'Update',
|
||||||
|
actor: sender.uri,
|
||||||
|
object: {
|
||||||
|
type: 'Article',
|
||||||
|
id: status.uri,
|
||||||
|
name: 'Future of the Fediverse',
|
||||||
|
summary: '<p>Guest article by Jane Mastodon</p><p>The fediverse is great reading this you will find out why!</p>',
|
||||||
|
content: 'Foo',
|
||||||
|
updated: updated,
|
||||||
|
likes: {
|
||||||
|
id: "#{status.uri}/likes",
|
||||||
|
type: 'Collection',
|
||||||
|
totalItems: favourites,
|
||||||
|
},
|
||||||
|
shares: {
|
||||||
|
id: "#{status.uri}/shares",
|
||||||
|
type: 'Collection',
|
||||||
|
totalItems: reblogs,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}.with_indifferent_access
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples 'updates counts' do
|
||||||
|
it 'updates the reblog count' do
|
||||||
|
expect { subject.perform }.to change { status.reload.untrusted_reblogs_count }.to(reblogs)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates the favourites count' do
|
||||||
|
expect { subject.perform }.to change { status.reload.untrusted_favourites_count }.to(favourites)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with an implicit update' do
|
||||||
|
before do
|
||||||
|
status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'updates counts'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with an explicit update' do
|
||||||
|
let(:favourites) { 150 }
|
||||||
|
let(:reblogs) { 200 }
|
||||||
|
let(:updated) { Time.now.utc.iso8601 }
|
||||||
|
|
||||||
|
before do
|
||||||
|
status.update!(uri: ActivityPub::TagManager.instance.uri_for(status))
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'updates counts'
|
||||||
|
|
||||||
|
it 'changes the contents as expected' do
|
||||||
|
expect { subject.perform }
|
||||||
|
.to(change { status.reload.text })
|
||||||
|
|
||||||
|
expect(status.text).to start_with("<h2>Future of the Fediverse</h2>\n\n<p>Guest article by Jane Mastodon</p><p>The fediverse is great reading this you will find out why!</p>")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user