Skip to content

Commit

Permalink
他のサーバーから来た引用付き投稿を処理
Browse files Browse the repository at this point in the history
  • Loading branch information
kmycode committed Oct 1, 2023
1 parent e1b61c4 commit 3ff14e0
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 39 deletions.
25 changes: 0 additions & 25 deletions app/javascript/mastodon/components/compacted_status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,6 @@ class CompactedStatus extends ImmutablePureComponent {
this.handleToggleMediaVisibility();
};

handleUnfilterClick = e => {
this.setState({ forceFilter: false });
e.preventDefault();
};

_properStatus () {
const { status } = this.props;

Expand Down Expand Up @@ -335,26 +330,6 @@ class CompactedStatus extends ImmutablePureComponent {
const connectUp = previousId && previousId === status.get('in_reply_to_id');
const connectToRoot = rootId && rootId === status.get('in_reply_to_id');
const connectReply = nextInReplyToId && nextInReplyToId === status.get('id');
const matchedFilters = status.get('matched_filters');

if (this.state.forceFilter === undefined ? matchedFilters : this.state.forceFilter) {
const minHandlers = this.props.muted ? {} : {
moveUp: this.handleHotkeyMoveUp,
moveDown: this.handleHotkeyMoveDown,
};

return (
<HotKeys handlers={minHandlers}>
<div className='status__wrapper status__wrapper--filtered focusable' tabIndex={0} ref={this.handleRef}>
<FormattedMessage id='status.filtered' defaultMessage='Filtered' />: {matchedFilters.join(', ')}.
{' '}
<button className='status__wrapper--filtered__button' onClick={this.handleUnfilterClick}>
<FormattedMessage id='status.show_filter_reason' defaultMessage='Show anyway' />
</button>
</div>
</HotKeys>
);
}

if (showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id'])) {
const display_name_html = { __html: status.getIn(['account', 'display_name_html']) };
Expand Down
4 changes: 3 additions & 1 deletion app/javascript/mastodon/components/status.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,8 @@ class Status extends ImmutablePureComponent {
const expanded = !status.get('hidden') || status.get('spoiler_text').length === 0;

const withLimited = status.get('visibility_ex') === 'limited' && status.get('limited_scope') ? <span className='status__visibility-icon'><Icon id='get-pocket' title='Limited' /></span> : null;
const withReference = status.get('status_references_count') > 0 ? <span className='status__visibility-icon'><Icon id='link' title='Reference' /></span> : null;
const withQuote = status.get('quote_id') ? <span className='status__visibility-icon'><Icon id='quote-right' title='Quote' /></span> : null;
const withReference = (!withQuote && status.get('status_references_count') > 0) ? <span className='status__visibility-icon'><Icon id='link' title='Reference' /></span> : null;
const withExpiration = status.get('expires_at') ? <span className='status__visibility-icon'><Icon id='clock-o' title='Expiration' /></span> : null;

const quote = !muted && status.get('quote_id') && <CompactedStatusContainer id={status.get('quote_id')} />
Expand All @@ -640,6 +641,7 @@ class Status extends ImmutablePureComponent {
{/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
<div onClick={this.handleClick} className='status__info'>
<a href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
{withQuote}
{withReference}
{withExpiration}
{withLimited}
Expand Down
3 changes: 1 addition & 2 deletions app/lib/activitypub/activity/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,8 @@ def increment_voters_count!
def process_references!
references = @object['references'].nil? ? [] : ActivityPub::FetchReferencesService.new.call(@status, @object['references'])
quote = @object['quote'] || @object['quoteUrl'] || @object['quoteURL'] || @object['_misskey_quote']
references << quote if quote

ProcessReferencesService.perform_worker_async(@status, [], references)
ProcessReferencesService.perform_worker_async(@status, [], references, [quote].compact)
end

def join_group!
Expand Down
3 changes: 1 addition & 2 deletions app/services/activitypub/process_status_update_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -254,9 +254,8 @@ def update_emojis!
def update_references!
references = @json['references'].nil? ? [] : ActivityPub::FetchReferencesService.new.call(@status, @json['references'])
quote = @json['quote'] || @json['quoteUrl'] || @json['quoteURL'] || @json['_misskey_quote']
references << quote if quote

ProcessReferencesService.perform_worker_async(@status, [], references)
ProcessReferencesService.perform_worker_async(@status, [], references, [quote].compact)
end

def expected_type?
Expand Down
15 changes: 7 additions & 8 deletions app/services/process_references_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,19 @@ def call(status, reference_parameters, urls: nil, fetch_remote: true, no_fetch_u
launch_worker if @again
end

def self.need_process?(status, reference_parameters, urls)
reference_parameters.any? || (urls || []).any? || FormattingHelper.extract_status_plain_text(status).scan(REFURL_EXP).pluck(3).uniq.any?
def self.need_process?(status, reference_parameters, urls, quote_urls)
reference_parameters.any? || (urls || []).any? || (quote_urls || []).any? || FormattingHelper.extract_status_plain_text(status).scan(REFURL_EXP).pluck(3).uniq.any?
end

def self.perform_worker_async(status, reference_parameters, urls, quote_urls = [])
return unless need_process?(status, reference_parameters, urls)
def self.perform_worker_async(status, reference_parameters, urls, quote_urls)
return unless need_process?(status, reference_parameters, urls, quote_urls)

Rails.cache.write("status_reference:#{status.id}", true, expires_in: 10.minutes)
ProcessReferencesWorker.perform_async(status.id, reference_parameters, urls, [], quote_urls || [])
end

def self.call_service(status, reference_parameters, urls, quote_urls = [])
return unless need_process?(status, reference_parameters, urls)
return unless need_process?(status, reference_parameters, urls, quote_urls)

ProcessReferencesService.new.call(status, reference_parameters || [], urls: urls || [], fetch_remote: false, quote_urls: quote_urls)
end
Expand Down Expand Up @@ -92,7 +92,7 @@ def fetch_statuses!(urls)

target_urls.map do |url|
status = url_to_status(url)
@no_fetch_urls << url if !@fetch_remote && status.present? && status.local?
@no_fetch_urls << url if !@fetch_remote && status.present?
status
end
end
Expand All @@ -118,8 +118,7 @@ def add_references
statuses.each do |status|
attribute_type = quote_status_ids.include?(status.id) ? 'QT' : @attributes[status.id]
attribute_type = 'BT' unless quotable?(status)
quote_type = attribute_type.casecmp('QT').zero?
@status.quote_of_id = status.id if quote_type && @status.quote_of_id.nil?
quote_type = attribute_type.present? ? attribute_type.casecmp('QT').zero? : false
@added_objects << @status.reference_objects.new(target_status: status, attribute_type: attribute_type, quote: quote_type)

status.increment_count!(:status_referred_by_count)
Expand Down
91 changes: 91 additions & 0 deletions spec/lib/activitypub/activity/create_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,97 @@
end
end

context 'with references' do
let(:recipient) { Fabricate(:account) }
let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) }

let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
type: 'Note',
content: 'Lorem ipsum',
references: {
id: 'target_status',
type: 'Collection',
first: {
type: 'CollectionPage',
next: nil,
partOf: 'target_status',
items: [
ActivityPub::TagManager.instance.uri_for(target_status),
],
},
},
}
end

it 'creates status' do
status = sender.statuses.first

expect(status).to_not be_nil
expect(status.quote).to be_nil
expect(status.references.pluck(:id)).to eq [target_status.id]
end
end

context 'with quote' do
let(:recipient) { Fabricate(:account) }
let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) }

let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
type: 'Note',
content: 'Lorem ipsum',
quote: ActivityPub::TagManager.instance.uri_for(target_status),
}
end

it 'creates status' do
status = sender.statuses.first

expect(status).to_not be_nil
expect(status.references.pluck(:id)).to eq [target_status.id]
expect(status.quote).to_not be_nil
expect(status.quote.id).to eq target_status.id
end
end

context 'with references and quote' do
let(:recipient) { Fabricate(:account) }
let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) }

let(:object_json) do
{
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
type: 'Note',
content: 'Lorem ipsum',
quote: ActivityPub::TagManager.instance.uri_for(target_status),
references: {
id: 'target_status',
type: 'Collection',
first: {
type: 'CollectionPage',
next: nil,
partOf: 'target_status',
items: [
ActivityPub::TagManager.instance.uri_for(target_status),
],
},
},
}
end

it 'creates status' do
status = sender.statuses.first

expect(status).to_not be_nil
expect(status.references.pluck(:id)).to eq [target_status.id]
expect(status.quote).to_not be_nil
expect(status.quote.id).to eq target_status.id
end
end

context 'with language' do
let(:to) { 'https://www.w3.org/ns/activitystreams#Public' }
let(:object_json) do
Expand Down
17 changes: 16 additions & 1 deletion spec/services/process_references_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
let(:status) { Fabricate(:status, account: account, text: text, visibility: visibility) }
let(:target_status) { Fabricate(:status, account: Fabricate(:user).account, visibility: target_status_visibility) }
let(:target_status_uri) { ActivityPub::TagManager.instance.uri_for(target_status) }
let(:quote_urls) { nil }

def notify?(target_status_id = nil)
target_status_id ||= target_status.id
Expand All @@ -18,7 +19,7 @@ def notify?(target_status_id = nil)

describe 'posting new status' do
subject do
described_class.new.call(status, reference_parameters, urls: urls, fetch_remote: fetch_remote)
described_class.new.call(status, reference_parameters, urls: urls, fetch_remote: fetch_remote, quote_urls: quote_urls)
status.reference_objects.pluck(:target_status_id, :attribute_type)
end

Expand Down Expand Up @@ -90,6 +91,20 @@ def notify?(target_status_id = nil)
end
end

context 'with quote as parameter only' do
let(:text) { 'Hello' }
let(:quote_urls) { [ActivityPub::TagManager.instance.uri_for(target_status)] }

it 'post status' do
expect(subject.size).to eq 1
expect(subject.pluck(0)).to include target_status.id
expect(subject.pluck(1)).to include 'QT'
expect(status.quote).to_not be_nil
expect(status.quote.id).to eq target_status.id
expect(notify?).to be true
end
end

context 'with quote and reference' do
let(:target_status2) { Fabricate(:status) }
let(:target_status2_uri) { ActivityPub::TagManager.instance.uri_for(target_status2) }
Expand Down

0 comments on commit 3ff14e0

Please sign in to comment.