Merge tag 'v3.4.0' into hometown-dev
This commit is contained in:
@ -175,7 +175,7 @@ class AccountSearchService < BaseService
|
||||
end
|
||||
|
||||
def username_complete?
|
||||
query.include?('@') && "@#{query}" =~ /\A#{Account::MENTION_RE}\Z/
|
||||
query.include?('@') && "@#{query}".match?(/\A#{Account::MENTION_RE}\Z/)
|
||||
end
|
||||
|
||||
def likely_acct?
|
||||
|
||||
@ -23,12 +23,8 @@ class ActivityPub::FetchFeaturedCollectionService < BaseService
|
||||
|
||||
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)
|
||||
|
||||
.filter_map { |uri| ActivityPub::FetchRemoteStatusService.new.call(uri) unless ActivityPub::TagManager.instance.local_uri?(uri) }
|
||||
.filter_map { |status| status.id if status.account_id == @account.id }
|
||||
to_remove = []
|
||||
to_add = status_ids
|
||||
|
||||
|
||||
@ -5,6 +5,8 @@ class ActivityPub::FetchRemoteKeyService < BaseService
|
||||
|
||||
# Returns account that owns the key
|
||||
def call(uri, id: true, prefetched_body: nil)
|
||||
return if uri.blank?
|
||||
|
||||
if prefetched_body.nil?
|
||||
if id
|
||||
@json = fetch_resource_without_id_validation(uri)
|
||||
|
||||
@ -87,6 +87,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||
@account.url = url || @uri
|
||||
@account.uri = @uri
|
||||
@account.actor_type = actor_type
|
||||
@account.created_at = @json['published'] if @json['published'].present?
|
||||
end
|
||||
|
||||
def set_immediate_attributes!
|
||||
@ -101,12 +102,20 @@ class ActivityPub::ProcessAccountService < BaseService
|
||||
end
|
||||
|
||||
def set_fetchable_key!
|
||||
@account.public_key = public_key || ''
|
||||
@account.public_key = public_key || ''
|
||||
end
|
||||
|
||||
def set_fetchable_attributes!
|
||||
@account.avatar_remote_url = image_url('icon') || '' unless skip_download?
|
||||
@account.header_remote_url = image_url('image') || '' unless skip_download?
|
||||
begin
|
||||
@account.avatar_remote_url = image_url('icon') || '' unless skip_download?
|
||||
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
|
||||
RedownloadAvatarWorker.perform_in(rand(30..600).seconds, @account.id)
|
||||
end
|
||||
begin
|
||||
@account.header_remote_url = image_url('image') || '' unless skip_download?
|
||||
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError
|
||||
RedownloadHeaderWorker.perform_in(rand(30..600).seconds, @account.id)
|
||||
end
|
||||
@account.statuses_count = outbox_total_items if outbox_total_items.present?
|
||||
@account.following_count = following_total_items if following_total_items.present?
|
||||
@account.followers_count = followers_total_items if followers_total_items.present?
|
||||
|
||||
@ -37,7 +37,7 @@ class ActivityPub::ProcessCollectionService < BaseService
|
||||
end
|
||||
|
||||
def process_items(items)
|
||||
items.reverse_each.map { |item| process_item(item) }.compact
|
||||
items.reverse_each.filter_map { |item| process_item(item) }
|
||||
end
|
||||
|
||||
def supported_context?
|
||||
|
||||
@ -30,7 +30,7 @@ class ActivityPub::ProcessPollService < BaseService
|
||||
|
||||
voters_count = @json['votersCount']
|
||||
|
||||
latest_options = items.map { |item| item['name'].presence || item['content'] }.compact
|
||||
latest_options = items.filter_map { |item| item['name'].presence || item['content'] }
|
||||
|
||||
# If for some reasons the options were changed, it invalidates all previous
|
||||
# votes, so we need to remove them
|
||||
|
||||
@ -14,7 +14,7 @@ class ActivityPub::SynchronizeFollowersService < BaseService
|
||||
# should never happen in practice, since in almost all cases we keep an
|
||||
# Account record, and should we not do that, we should have sent a Delete.
|
||||
# In any case there is not much we can do if that occurs.
|
||||
@expected_followers = items.map { |uri| ActivityPub::TagManager.instance.uri_to_resource(uri, Account) }.compact
|
||||
@expected_followers = items.filter_map { |uri| ActivityPub::TagManager.instance.uri_to_resource(uri, Account) }
|
||||
|
||||
remove_unexpected_local_followers!
|
||||
handle_unexpected_outgoing_follows!
|
||||
|
||||
@ -6,6 +6,7 @@ class AfterBlockService < BaseService
|
||||
@target_account = target_account
|
||||
|
||||
clear_home_feed!
|
||||
clear_list_feeds!
|
||||
clear_notifications!
|
||||
clear_conversations!
|
||||
end
|
||||
@ -16,6 +17,10 @@ class AfterBlockService < BaseService
|
||||
FeedManager.instance.clear_from_home(@account, @target_account)
|
||||
end
|
||||
|
||||
def clear_list_feeds!
|
||||
FeedManager.instance.clear_from_lists(@account, @target_account)
|
||||
end
|
||||
|
||||
def clear_conversations!
|
||||
AccountConversation.where(account: @account).where('? = ANY(participant_account_ids)', @target_account.id).in_batches.destroy_all
|
||||
end
|
||||
|
||||
@ -5,48 +5,13 @@ class BootstrapTimelineService < BaseService
|
||||
@source_account = source_account
|
||||
|
||||
autofollow_inviter!
|
||||
autofollow_bootstrap_timeline_accounts! if Setting.enable_bootstrap_timeline_accounts
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def autofollow_inviter!
|
||||
return unless @source_account&.user&.invite&.autofollow?
|
||||
|
||||
FollowService.new.call(@source_account, @source_account.user.invite.user.account)
|
||||
end
|
||||
|
||||
def autofollow_bootstrap_timeline_accounts!
|
||||
bootstrap_timeline_accounts.each do |target_account|
|
||||
begin
|
||||
FollowService.new.call(@source_account, target_account)
|
||||
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def bootstrap_timeline_accounts
|
||||
return @bootstrap_timeline_accounts if defined?(@bootstrap_timeline_accounts)
|
||||
|
||||
@bootstrap_timeline_accounts = bootstrap_timeline_accounts_usernames.empty? ? admin_accounts : local_unlocked_accounts(bootstrap_timeline_accounts_usernames)
|
||||
end
|
||||
|
||||
def bootstrap_timeline_accounts_usernames
|
||||
@bootstrap_timeline_accounts_usernames ||= (Setting.bootstrap_timeline_accounts || '').split(',').map { |str| str.strip.gsub(/\A@/, '') }.reject(&:blank?)
|
||||
end
|
||||
|
||||
def admin_accounts
|
||||
User.admins
|
||||
.includes(:account)
|
||||
.where(accounts: { locked: false })
|
||||
.map(&:account)
|
||||
end
|
||||
|
||||
def local_unlocked_accounts(usernames)
|
||||
Account.local
|
||||
.without_suspended
|
||||
.where(username: usernames)
|
||||
.where(locked: false)
|
||||
.where(moved_to_account_id: nil)
|
||||
end
|
||||
end
|
||||
|
||||
@ -188,8 +188,7 @@ class DeleteAccountService < BaseService
|
||||
ids = favourites.pluck(:status_id)
|
||||
StatusStat.where(status_id: ids).update_all('favourites_count = GREATEST(0, favourites_count - 1)')
|
||||
Chewy.strategy.current.update(StatusesIndex::Status, ids) if Chewy.enabled?
|
||||
# Rails.cache.delete_multi would be better, but we don't have it yet
|
||||
ids.each { |id| Rails.cache.delete("statuses/#{id}") }
|
||||
Rails.cache.delete_multi(ids.map { |id| "statuses/#{id}" })
|
||||
favourites.delete_all
|
||||
end
|
||||
end
|
||||
|
||||
@ -2,12 +2,13 @@
|
||||
|
||||
class FetchLinkCardService < BaseService
|
||||
URL_PATTERN = %r{
|
||||
( # $1 URL
|
||||
(https?:\/\/) # $2 Protocol (required)
|
||||
(#{Twitter::Regex[:valid_domain]}) # $3 Domain(s)
|
||||
(?::(#{Twitter::Regex[:valid_port_number]}))? # $4 Port number (optional)
|
||||
(/#{Twitter::Regex[:valid_url_path]}*)? # $5 URL Path and anchor
|
||||
(\?#{Twitter::Regex[:valid_url_query_chars]}*#{Twitter::Regex[:valid_url_query_ending_chars]})? # $6 Query String
|
||||
(#{Twitter::TwitterText::Regex[:valid_url_preceding_chars]}) # $1 preceeding chars
|
||||
( # $2 URL
|
||||
(https?:\/\/) # $3 Protocol (required)
|
||||
(#{Twitter::TwitterText::Regex[:valid_domain]}) # $4 Domain(s)
|
||||
(?::(#{Twitter::TwitterText::Regex[:valid_port_number]}))? # $5 Port number (optional)
|
||||
(/#{Twitter::TwitterText::Regex[:valid_url_path]}*)? # $6 URL Path and anchor
|
||||
(\?#{Twitter::TwitterText::Regex[:valid_url_query_chars]}*#{Twitter::TwitterText::Regex[:valid_url_query_ending_chars]})? # $7 Query String
|
||||
)
|
||||
}iox
|
||||
|
||||
@ -47,11 +48,11 @@ class FetchLinkCardService < BaseService
|
||||
|
||||
Request.new(:get, @url).add_headers('Accept' => 'text/html', 'User-Agent' => Mastodon::Version.user_agent + ' Bot').perform do |res|
|
||||
if res.code == 200 && res.mime_type == 'text/html'
|
||||
@html = res.body_with_limit
|
||||
@html_charset = res.charset
|
||||
@html = res.body_with_limit
|
||||
else
|
||||
@html = nil
|
||||
@html_charset = nil
|
||||
@html = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -63,11 +64,11 @@ class FetchLinkCardService < BaseService
|
||||
|
||||
def parse_urls
|
||||
if @status.local?
|
||||
urls = @status.text.scan(URL_PATTERN).map { |array| Addressable::URI.parse(array[0]).normalize }
|
||||
urls = @status.text.scan(URL_PATTERN).map { |array| Addressable::URI.parse(array[1]).normalize }
|
||||
else
|
||||
html = Nokogiri::HTML(@status.text)
|
||||
links = html.css('a')
|
||||
urls = links.map { |a| Addressable::URI.parse(a['href']) unless skip_link?(a) }.compact.map(&:normalize).compact
|
||||
urls = links.filter_map { |a| Addressable::URI.parse(a['href']) unless skip_link?(a) }.filter_map(&:normalize)
|
||||
end
|
||||
|
||||
urls.reject { |uri| bad_url?(uri) }.first
|
||||
|
||||
@ -38,7 +38,17 @@ class FetchOEmbedService
|
||||
|
||||
return if @endpoint_url.blank?
|
||||
|
||||
@endpoint_url = (Addressable::URI.parse(@url) + @endpoint_url).to_s
|
||||
@endpoint_url = begin
|
||||
base_url = Addressable::URI.parse(@url)
|
||||
|
||||
# If the OEmbed endpoint is given as http but the URL we opened
|
||||
# was served over https, we can assume OEmbed will be available
|
||||
# through https as well
|
||||
|
||||
(base_url + @endpoint_url).tap do |absolute_url|
|
||||
absolute_url.scheme = base_url.scheme if base_url.scheme == 'https'
|
||||
end.to_s
|
||||
end
|
||||
|
||||
cache_endpoint!
|
||||
rescue Addressable::URI::InvalidURIError
|
||||
|
||||
@ -3,10 +3,11 @@
|
||||
class FollowService < BaseService
|
||||
include Redisable
|
||||
include Payloadable
|
||||
include DomainControlHelper
|
||||
|
||||
# Follow a remote user, notify remote user about the follow
|
||||
# @param [Account] source_account From which to follow
|
||||
# @param [String, Account] uri User URI to follow in the form of username@domain (or account record)
|
||||
# @param [Account] target_account Account to follow
|
||||
# @param [Hash] options
|
||||
# @option [Boolean] :reblogs Whether or not to show reblogs, defaults to true
|
||||
# @option [Boolean] :notify Whether to create notifications about new posts, defaults to false
|
||||
@ -15,7 +16,7 @@ class FollowService < BaseService
|
||||
# @option [Boolean] :with_rate_limit
|
||||
def call(source_account, target_account, options = {})
|
||||
@source_account = source_account
|
||||
@target_account = ResolveAccountService.new.call(target_account, skip_webfinger: true)
|
||||
@target_account = target_account
|
||||
@options = { bypass_locked: false, bypass_limit: false, with_rate_limit: false }.merge(options)
|
||||
|
||||
raise ActiveRecord::RecordNotFound if following_not_possible?
|
||||
@ -29,6 +30,11 @@ class FollowService < BaseService
|
||||
|
||||
ActivityTracker.increment('activity:interactions')
|
||||
|
||||
# When an account follows someone for the first time, avoid showing
|
||||
# an empty home feed while the follow request is being processed
|
||||
# and the feeds are being merged
|
||||
mark_home_feed_as_partial! if @source_account.not_following_anyone?
|
||||
|
||||
if (@target_account.locked? && !@options[:bypass_locked]) || @source_account.silenced? || @target_account.activitypub?
|
||||
request_follow!
|
||||
elsif @target_account.local?
|
||||
@ -38,12 +44,16 @@ class FollowService < BaseService
|
||||
|
||||
private
|
||||
|
||||
def mark_home_feed_as_partial!
|
||||
redis.set("account:#{@source_account.id}:regeneration", true, nx: true, ex: 1.day.seconds)
|
||||
end
|
||||
|
||||
def following_not_possible?
|
||||
@target_account.nil? || @target_account.id == @source_account.id || @target_account.suspended?
|
||||
end
|
||||
|
||||
def following_not_allowed?
|
||||
@target_account.blocking?(@source_account) || @source_account.blocking?(@target_account) || @target_account.moved? || (!@target_account.local? && @target_account.ostatus?) || @source_account.domain_blocking?(@target_account.domain)
|
||||
domain_not_allowed?(@target_account.domain) || @target_account.blocking?(@source_account) || @source_account.blocking?(@target_account) || @target_account.moved? || (!@target_account.local? && @target_account.ostatus?) || @source_account.domain_blocking?(@target_account.domain)
|
||||
end
|
||||
|
||||
def change_follow_options!
|
||||
|
||||
@ -45,7 +45,7 @@ class ImportService < BaseService
|
||||
items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row['#domain'].strip }
|
||||
|
||||
if @import.overwrite?
|
||||
presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true }
|
||||
presence_hash = items.index_with(true)
|
||||
|
||||
@account.domain_blocks.find_each do |domain_block|
|
||||
if presence_hash[domain_block.domain]
|
||||
@ -96,7 +96,7 @@ class ImportService < BaseService
|
||||
items = @data.take(ROWS_PROCESSING_LIMIT).map { |row| row['#uri'].strip }
|
||||
|
||||
if @import.overwrite?
|
||||
presence_hash = items.each_with_object({}) { |id, mapping| mapping[id] = true }
|
||||
presence_hash = items.index_with(true)
|
||||
|
||||
@account.bookmarks.find_each do |bookmark|
|
||||
if presence_hash[bookmark.status.uri]
|
||||
@ -107,12 +107,12 @@ class ImportService < BaseService
|
||||
end
|
||||
end
|
||||
|
||||
statuses = items.map do |uri|
|
||||
statuses = items.filter_map do |uri|
|
||||
status = ActivityPub::TagManager.instance.uri_to_resource(uri, Status)
|
||||
next if status.nil? && ActivityPub::TagManager.instance.local_uri?(uri)
|
||||
|
||||
status || ActivityPub::FetchRemoteStatusService.new.call(uri)
|
||||
end.compact
|
||||
end
|
||||
|
||||
account_ids = statuses.map(&:account_id)
|
||||
preloaded_relations = relations_map_for_account(@account, account_ids)
|
||||
|
||||
@ -8,11 +8,13 @@ class Keys::ClaimService < BaseService
|
||||
:key, :signature
|
||||
|
||||
def initialize(account, device_id, key_attributes = {})
|
||||
@account = account
|
||||
@device_id = device_id
|
||||
@key_id = key_attributes[:key_id]
|
||||
@key = key_attributes[:key]
|
||||
@signature = key_attributes[:signature]
|
||||
super(
|
||||
account: account,
|
||||
device_id: device_id,
|
||||
key_id: key_attributes[:key_id],
|
||||
key: key_attributes[:key],
|
||||
signature: key_attributes[:signature],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -7,8 +7,10 @@ class Keys::QueryService < BaseService
|
||||
attributes :account, :devices
|
||||
|
||||
def initialize(account, devices)
|
||||
@account = account
|
||||
@devices = devices || []
|
||||
super(
|
||||
account: account,
|
||||
devices: devices || [],
|
||||
)
|
||||
end
|
||||
|
||||
def find(device_id)
|
||||
@ -20,11 +22,13 @@ class Keys::QueryService < BaseService
|
||||
attributes :device_id, :name, :identity_key, :fingerprint_key
|
||||
|
||||
def initialize(attributes = {})
|
||||
@device_id = attributes[:device_id]
|
||||
@name = attributes[:name]
|
||||
@identity_key = attributes[:identity_key]
|
||||
@fingerprint_key = attributes[:fingerprint_key]
|
||||
@claim_url = attributes[:claim_url]
|
||||
super(
|
||||
device_id: attributes[:device_id],
|
||||
name: attributes[:name],
|
||||
identity_key: attributes[:identity_key],
|
||||
fingerprint_key: attributes[:fingerprint_key],
|
||||
)
|
||||
@claim_url = attributes[:claim_url]
|
||||
end
|
||||
|
||||
def valid_claim_url?
|
||||
|
||||
@ -8,8 +8,7 @@ class ProcessHashtagsService < BaseService
|
||||
Tag.find_or_create_by_names(tags) do |tag|
|
||||
status.tags << tag
|
||||
records << tag
|
||||
|
||||
TrendingTags.record_use!(tag, status.account, status.created_at) if status.public_visibility?
|
||||
tag.use!(status.account, status: status, at_time: status.created_at) if status.public_visibility?
|
||||
end
|
||||
|
||||
return unless status.distributable?
|
||||
|
||||
@ -43,7 +43,6 @@ class ProcessMentionsService < BaseService
|
||||
end
|
||||
|
||||
status.save!
|
||||
check_for_spam(status)
|
||||
|
||||
mentions.each { |mention| create_notification(mention) }
|
||||
end
|
||||
@ -72,8 +71,4 @@ class ProcessMentionsService < BaseService
|
||||
def resolve_account_service
|
||||
ResolveAccountService.new
|
||||
end
|
||||
|
||||
def check_for_spam(status)
|
||||
SpamCheck.perform(status)
|
||||
end
|
||||
end
|
||||
|
||||
@ -37,6 +37,7 @@ class ReblogService < BaseService
|
||||
|
||||
create_notification(reblog)
|
||||
bump_potential_friendship(account, reblog)
|
||||
record_use(account, reblog)
|
||||
|
||||
reblog
|
||||
end
|
||||
@ -61,6 +62,16 @@ class ReblogService < BaseService
|
||||
PotentialFriendshipTracker.record(account.id, reblog.reblog.account_id, :reblog)
|
||||
end
|
||||
|
||||
def record_use(account, reblog)
|
||||
return unless reblog.public_visibility?
|
||||
|
||||
original_status = reblog.reblog
|
||||
|
||||
original_status.tags.each do |tag|
|
||||
tag.use!(account)
|
||||
end
|
||||
end
|
||||
|
||||
def build_json(reblog)
|
||||
Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_status(reblog), ActivityPub::ActivitySerializer, signer: reblog.account))
|
||||
end
|
||||
|
||||
@ -16,6 +16,8 @@ class RemoveStatusService < BaseService
|
||||
@account = status.account
|
||||
@options = options
|
||||
|
||||
@status.discard
|
||||
|
||||
RedisLock.acquire(lock_options) do |lock|
|
||||
if lock.acquired?
|
||||
remove_from_self if @account.local?
|
||||
@ -27,10 +29,7 @@ class RemoveStatusService < BaseService
|
||||
# original object being removed implicitly removes reblogs
|
||||
# of it. The Delete activity of the original is forwarded
|
||||
# separately.
|
||||
if @account.local? && !@options[:original_removed]
|
||||
remove_from_remote_followers
|
||||
remove_from_remote_reach
|
||||
end
|
||||
remove_from_remote_reach if @account.local? && !@options[:original_removed]
|
||||
|
||||
# Since reblogs don't mention anyone, don't get reblogged,
|
||||
# favourited and don't contain their own media attachments
|
||||
@ -41,7 +40,6 @@ class RemoveStatusService < BaseService
|
||||
remove_from_hashtags
|
||||
remove_from_public
|
||||
remove_from_media if @status.media_attachments.any?
|
||||
remove_from_spam_check
|
||||
remove_media
|
||||
end
|
||||
|
||||
@ -83,13 +81,10 @@ class RemoveStatusService < BaseService
|
||||
end
|
||||
|
||||
def remove_from_remote_reach
|
||||
return if @status.reblog?
|
||||
|
||||
# People who got mentioned in the status, or who
|
||||
# reblogged it from someone else might not follow
|
||||
# the author and wouldn't normally receive the
|
||||
# delete notification - so here, we explicitly
|
||||
# send it to them
|
||||
# Followers, relays, people who got mentioned in the status,
|
||||
# or who reblogged it from someone else might not follow
|
||||
# the author and wouldn't normally receive the delete
|
||||
# notification - so here, we explicitly send it to them
|
||||
|
||||
status_reach_finder = StatusReachFinder.new(@status)
|
||||
|
||||
@ -98,24 +93,6 @@ class RemoveStatusService < BaseService
|
||||
end
|
||||
end
|
||||
|
||||
def remove_from_remote_followers
|
||||
ActivityPub::DeliveryWorker.push_bulk(@account.followers.inboxes) do |inbox_url|
|
||||
[signed_activity_json, @account.id, inbox_url]
|
||||
end
|
||||
|
||||
relay! if relayable?
|
||||
end
|
||||
|
||||
def relayable?
|
||||
@status.public_visibility?
|
||||
end
|
||||
|
||||
def relay!
|
||||
ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
|
||||
[signed_activity_json, @account.id, inbox_url]
|
||||
end
|
||||
end
|
||||
|
||||
def signed_activity_json
|
||||
@signed_activity_json ||= Oj.dump(serialize_payload(@status, @status.reblog? ? ActivityPub::UndoAnnounceSerializer : ActivityPub::DeleteSerializer, signer: @account))
|
||||
end
|
||||
@ -163,10 +140,6 @@ class RemoveStatusService < BaseService
|
||||
@status.media_attachments.destroy_all
|
||||
end
|
||||
|
||||
def remove_from_spam_check
|
||||
redis.zremrangebyscore("spam_check:#{@status.account_id}", @status.id, @status.id)
|
||||
end
|
||||
|
||||
def lock_options
|
||||
{ redis: Redis.current, key: "distribute:#{@status.id}" }
|
||||
end
|
||||
|
||||
@ -10,6 +10,8 @@ class ReportService < BaseService
|
||||
@comment = options.delete(:comment) || ''
|
||||
@options = options
|
||||
|
||||
raise ActiveRecord::RecordNotFound if @target_account.suspended?
|
||||
|
||||
create_report!
|
||||
notify_staff!
|
||||
forward_to_origin! if !@target_account.local? && ActiveModel::Type::Boolean.new.cast(@options[:forward])
|
||||
|
||||
@ -10,7 +10,7 @@ class ResolveAccountService < BaseService
|
||||
# @param [String, Account] uri URI in the username@domain format or account record
|
||||
# @param [Hash] options
|
||||
# @option options [Boolean] :redirected Do not follow further Webfinger redirects
|
||||
# @option options [Boolean] :skip_webfinger Do not attempt to refresh account data
|
||||
# @option options [Boolean] :skip_webfinger Do not attempt any webfinger query or refreshing account data
|
||||
# @return [Account]
|
||||
def call(uri, options = {})
|
||||
return if uri.blank?
|
||||
@ -120,8 +120,9 @@ class ResolveAccountService < BaseService
|
||||
|
||||
def webfinger_update_due?
|
||||
return false if @options[:check_delivery_availability] && !DeliveryFailureTracker.available?(@domain)
|
||||
return false if @options[:skip_webfinger]
|
||||
|
||||
@account.nil? || ((!@options[:skip_webfinger] || @account.ostatus?) && @account.possibly_stale?)
|
||||
@account.nil? || @account.possibly_stale?
|
||||
end
|
||||
|
||||
def activitypub_ready?
|
||||
|
||||
@ -72,7 +72,7 @@ class SearchService < BaseService
|
||||
end
|
||||
|
||||
def url_query?
|
||||
@resolve && @query =~ /\Ahttps?:\/\//
|
||||
@resolve && /\Ahttps?:\/\//.match?(@query)
|
||||
end
|
||||
|
||||
def url_resource_results
|
||||
|
||||
@ -42,7 +42,13 @@ class SuspendAccountService < BaseService
|
||||
end
|
||||
|
||||
def distribute_update_actor!
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id) if @account.local?
|
||||
return unless @account.local?
|
||||
|
||||
account_reach_finder = AccountReachFinder.new(@account)
|
||||
|
||||
ActivityPub::DeliveryWorker.push_bulk(account_reach_finder.inboxes) do |inbox_url|
|
||||
[signed_activity_json, @account.id, inbox_url]
|
||||
end
|
||||
end
|
||||
|
||||
def unmerge_from_home_timelines!
|
||||
@ -90,4 +96,8 @@ class SuspendAccountService < BaseService
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def signed_activity_json
|
||||
@signed_activity_json ||= Oj.dump(serialize_payload(@account, ActivityPub::UpdateSerializer, signer: @account))
|
||||
end
|
||||
end
|
||||
|
||||
@ -12,6 +12,7 @@ class UnsuspendAccountService < BaseService
|
||||
merge_into_home_timelines!
|
||||
merge_into_list_timelines!
|
||||
publish_media_attachments!
|
||||
distribute_update_actor!
|
||||
end
|
||||
|
||||
private
|
||||
@ -36,6 +37,16 @@ class UnsuspendAccountService < BaseService
|
||||
# @account would now be nil.
|
||||
end
|
||||
|
||||
def distribute_update_actor!
|
||||
return unless @account.local?
|
||||
|
||||
account_reach_finder = AccountReachFinder.new(@account)
|
||||
|
||||
ActivityPub::DeliveryWorker.push_bulk(account_reach_finder.inboxes) do |inbox_url|
|
||||
[signed_activity_json, @account.id, inbox_url]
|
||||
end
|
||||
end
|
||||
|
||||
def merge_into_home_timelines!
|
||||
@account.followers_for_local_distribution.find_each do |follower|
|
||||
FeedManager.instance.merge_into_home(@account, follower)
|
||||
@ -81,4 +92,8 @@ class UnsuspendAccountService < BaseService
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def signed_activity_json
|
||||
@signed_activity_json ||= Oj.dump(serialize_payload(@account, ActivityPub::UpdateSerializer, signer: @account))
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user