Merge remote-tracking branch 'tootsuite/master' into glitchsoc/master
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::FetchFeaturedCollectionService < BaseService
|
||||
include JsonLdHelper
|
||||
|
||||
def call(account)
|
||||
@account = account
|
||||
@json = fetch_resource(@account.featured_collection_url, true)
|
||||
|
||||
return unless supported_context?
|
||||
return if @account.suspended? || @account.local?
|
||||
|
||||
case @json['type']
|
||||
when 'Collection', 'CollectionPage'
|
||||
process_items @json['items']
|
||||
when 'OrderedCollection', 'OrderedCollectionPage'
|
||||
process_items @json['orderedItems']
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_items(items)
|
||||
status_ids = items.map { |item| value_or_id(item) }
|
||||
.reject { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }
|
||||
.map { |uri| ActivityPub::FetchRemoteStatusService.new.call(uri) }
|
||||
.compact
|
||||
.select { |status| status.account_id == @account.id }
|
||||
.map(&:id)
|
||||
|
||||
to_remove = []
|
||||
to_add = status_ids
|
||||
|
||||
StatusPin.where(account: @account).pluck(:status_id).each do |status_id|
|
||||
if status_ids.include?(status_id)
|
||||
to_add.delete(status_id)
|
||||
else
|
||||
to_remove << status_id
|
||||
end
|
||||
end
|
||||
|
||||
StatusPin.where(account: @account, status_id: to_remove).delete_all unless to_remove.empty?
|
||||
|
||||
to_add.each do |status_id|
|
||||
StatusPin.create!(account: @account, status_id: status_id)
|
||||
end
|
||||
end
|
||||
|
||||
def supported_context?
|
||||
super(@json)
|
||||
end
|
||||
end
|
||||
@@ -27,6 +27,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||
|
||||
after_protocol_change! if protocol_changed?
|
||||
after_key_change! if key_changed?
|
||||
check_featured_collection! if @account.featured_collection_url.present?
|
||||
|
||||
@account
|
||||
rescue Oj::ParseError
|
||||
@@ -57,14 +58,15 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||
end
|
||||
|
||||
def set_immediate_attributes!
|
||||
@account.inbox_url = @json['inbox'] || ''
|
||||
@account.outbox_url = @json['outbox'] || ''
|
||||
@account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || ''
|
||||
@account.followers_url = @json['followers'] || ''
|
||||
@account.url = url || @uri
|
||||
@account.display_name = @json['name'] || ''
|
||||
@account.note = @json['summary'] || ''
|
||||
@account.locked = @json['manuallyApprovesFollowers'] || false
|
||||
@account.inbox_url = @json['inbox'] || ''
|
||||
@account.outbox_url = @json['outbox'] || ''
|
||||
@account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || ''
|
||||
@account.followers_url = @json['followers'] || ''
|
||||
@account.featured_collection_url = @json['featured'] || ''
|
||||
@account.url = url || @uri
|
||||
@account.display_name = @json['name'] || ''
|
||||
@account.note = @json['summary'] || ''
|
||||
@account.locked = @json['manuallyApprovesFollowers'] || false
|
||||
end
|
||||
|
||||
def set_fetchable_attributes!
|
||||
@@ -85,6 +87,10 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||
RefollowWorker.perform_async(@account.id)
|
||||
end
|
||||
|
||||
def check_featured_collection!
|
||||
ActivityPub::SynchronizeFeaturedCollectionWorker.perform_async(@account.id)
|
||||
end
|
||||
|
||||
def image_url(key)
|
||||
value = first_of_value(@json[key])
|
||||
|
||||
|
||||
@@ -5,13 +5,14 @@ class BlockDomainService < BaseService
|
||||
|
||||
def call(domain_block)
|
||||
@domain_block = domain_block
|
||||
process_domain_block
|
||||
process_domain_block!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process_domain_block
|
||||
def process_domain_block!
|
||||
clear_media! if domain_block.reject_media?
|
||||
|
||||
if domain_block.silence?
|
||||
silence_accounts!
|
||||
elsif domain_block.suspend?
|
||||
@@ -19,14 +20,26 @@ class BlockDomainService < BaseService
|
||||
end
|
||||
end
|
||||
|
||||
def invalidate_association_caches!
|
||||
# Normally, associated models of a status are immutable (except for accounts)
|
||||
# so they are aggressively cached. After updating the media attachments to no
|
||||
# longer point to a local file, we need to clear the cache to make those
|
||||
# changes appear in the API and UI
|
||||
@affected_status_ids.each { |id| Rails.cache.delete_matched("statuses/#{id}-*") }
|
||||
end
|
||||
|
||||
def silence_accounts!
|
||||
blocked_domain_accounts.in_batches.update_all(silenced: true)
|
||||
end
|
||||
|
||||
def clear_media!
|
||||
clear_account_images
|
||||
clear_account_attachments
|
||||
clear_emojos
|
||||
@affected_status_ids = []
|
||||
|
||||
clear_account_images!
|
||||
clear_account_attachments!
|
||||
clear_emojos!
|
||||
|
||||
invalidate_association_caches!
|
||||
end
|
||||
|
||||
def suspend_accounts!
|
||||
@@ -36,23 +49,25 @@ class BlockDomainService < BaseService
|
||||
end
|
||||
end
|
||||
|
||||
def clear_account_images
|
||||
def clear_account_images!
|
||||
blocked_domain_accounts.find_each do |account|
|
||||
account.avatar.destroy
|
||||
account.header.destroy
|
||||
account.avatar.destroy if account.avatar.exists?
|
||||
account.header.destroy if account.header.exists?
|
||||
account.save
|
||||
end
|
||||
end
|
||||
|
||||
def clear_account_attachments
|
||||
def clear_account_attachments!
|
||||
media_from_blocked_domain.find_each do |attachment|
|
||||
attachment.file.destroy
|
||||
@affected_status_ids << attachment.status_id if attachment.status_id.present?
|
||||
|
||||
attachment.file.destroy if attachment.file.exists?
|
||||
attachment.type = :unknown
|
||||
attachment.save
|
||||
end
|
||||
end
|
||||
|
||||
def clear_emojos
|
||||
def clear_emojos!
|
||||
emojis_from_blocked_domains.destroy_all
|
||||
end
|
||||
|
||||
|
||||
@@ -21,17 +21,18 @@ class PostStatusService < BaseService
|
||||
|
||||
media = validate_media!(options[:media_ids])
|
||||
status = nil
|
||||
text = options.delete(:spoiler_text) if text.blank? && options[:spoiler_text].present?
|
||||
text = '.' if text.blank? && !media.empty?
|
||||
|
||||
ApplicationRecord.transaction do
|
||||
status = account.statuses.create!(text: text,
|
||||
media_attachments: media || [],
|
||||
thread: in_reply_to,
|
||||
sensitive: options[:sensitive],
|
||||
spoiler_text: options[:spoiler_text] || '',
|
||||
visibility: options[:visibility] || account.user&.setting_default_privacy,
|
||||
language: LanguageDetector.instance.detect(text, account),
|
||||
application: options[:application])
|
||||
|
||||
attach_media(status, media)
|
||||
end
|
||||
|
||||
process_mentions_service.call(status)
|
||||
@@ -67,11 +68,6 @@ class PostStatusService < BaseService
|
||||
media
|
||||
end
|
||||
|
||||
def attach_media(status, media)
|
||||
return if media.nil?
|
||||
media.update(status_id: status.id)
|
||||
end
|
||||
|
||||
def process_mentions_service
|
||||
ProcessMentionsService.new
|
||||
end
|
||||
|
||||
@@ -29,7 +29,9 @@ class SearchService < BaseService
|
||||
def perform_statuses_search!
|
||||
statuses = StatusesIndex.filter(term: { searchable_by: account.id })
|
||||
.query(multi_match: { type: 'most_fields', query: query, operator: 'and', fields: %w(text text.stemmed) })
|
||||
.limit(limit).objects
|
||||
.limit(limit)
|
||||
.objects
|
||||
.compact
|
||||
|
||||
statuses.reject { |status| StatusFilter.new(status, account).filtered? }
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user