Merge remote-tracking branch 'parent/main' into upstream-20241126

This commit is contained in:
KMY 2024-11-26 12:56:31 +09:00
commit 8a075ba4c6
303 changed files with 7495 additions and 4498 deletions

View file

@ -0,0 +1,33 @@
# frozen_string_literal: true
class AddAccountsToListService < BaseService
def call(list, accounts)
@list = list
@accounts = accounts
return if @accounts.empty?
update_list!
merge_into_list!
end
private
def update_list!
ApplicationRecord.transaction do
@accounts.each do |account|
@list.accounts << account
end
end
end
def merge_into_list!
MergeWorker.push_bulk(merge_account_ids) do |account_id|
[account_id, @list.id, 'list']
end
end
def merge_account_ids
ListAccount.where(list: @list, account: @accounts).where.not(follow_id: nil).pluck(:account_id)
end
end

View file

@ -64,6 +64,7 @@ class DeleteAccountService < BaseService
scheduled_statuses
scheduled_expiration_statuses
status_pins
tag_follows
)
ASSOCIATIONS_ON_DESTROY = %w(

View file

@ -131,7 +131,7 @@ class FanOutOnWriteService < BaseService
end
def deliver_to_hashtag_followers!
TagFollow.where(tag_id: @status.tags.map(&:id)).select(:id, :account_id).reorder(nil).find_in_batches do |follows|
TagFollow.for_local_distribution.where(tag_id: @status.tags.map(&:id)).select(:id, :account_id).reorder(nil).find_in_batches do |follows|
FeedInsertWorker.push_bulk(follows) do |follow|
[@status.id, follow.account_id, 'tags', { 'update' => update? }]
end

View file

@ -74,7 +74,7 @@ class FetchResourceService < BaseService
def process_html(response)
page = Nokogiri::HTML5(response.body_with_limit)
json_link = page.xpath('//link[@rel="alternate"]').find { |link| ACTIVITY_STREAM_LINK_TYPES.include?(link['type']) }
json_link = page.xpath('//link[nokogiri:link_rel_include(@rel, "alternate")]', NokogiriHandler).find { |link| ACTIVITY_STREAM_LINK_TYPES.include?(link['type']) }
process(json_link['href'], terminal: true) unless json_link.nil?
end

View file

@ -84,7 +84,10 @@ class FollowService < BaseService
follow = @source_account.follow!(@target_account, **follow_options.merge(rate_limit: @options[:with_rate_limit], bypass_limit: @options[:bypass_limit]))
LocalNotificationWorker.perform_async(@target_account.id, follow.id, follow.class.name, 'follow')
MergeWorker.perform_async(@target_account.id, @source_account.id)
MergeWorker.perform_async(@target_account.id, @source_account.id, 'home')
MergeWorker.push_bulk(List.where(account: @source_account).joins(:list_accounts).where(list_accounts: { account_id: @target_account.id }).pluck(:id)) do |list_id|
[@target_account.id, list_id, 'list']
end
follow
end

View file

@ -42,6 +42,8 @@ class PostStatusService < BaseService
@text = @options[:text] || ''
@in_reply_to = @options[:thread]
@antispam = Antispam.new
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
validate_status!
@ -62,6 +64,8 @@ class PostStatusService < BaseService
end
@status
rescue Antispam::SilentlyDrop => e
e.status
end
private
@ -160,6 +164,7 @@ class PostStatusService < BaseService
@status.limited_scope = :personal if @status.limited_visibility? && !@status.reply_limited? && !process_mentions_service.mentions?
UpdateStatusExpirationService.new.call(@status)
@antispam.local_preflight_check!(@status)
# The following transaction block is needed to wrap the UPDATEs to
# the media attachments when the status is created
@ -182,6 +187,7 @@ class PostStatusService < BaseService
def schedule_status!
status_for_validation = @account.statuses.build(status_attributes)
@antispam.local_preflight_check!(status_for_validation)
if status_for_validation.valid?
# Marking the status as destroyed is necessary to prevent the status from being
@ -198,6 +204,8 @@ class PostStatusService < BaseService
else
raise ActiveRecord::RecordInvalid
end
rescue Antispam::SilentlyDrop
@status = @account.scheduled_status.new(scheduled_status_attributes).tap(&:delete)
end
def postprocess_status!

View file

@ -0,0 +1,29 @@
# frozen_string_literal: true
class RemoveAccountsFromListService < BaseService
def call(list, accounts)
@list = list
@accounts = accounts
return if @accounts.empty?
unmerge_from_list!
update_list!
end
private
def update_list!
ListAccount.where(list: @list, account: @accounts).destroy_all
end
def unmerge_from_list!
UnmergeWorker.push_bulk(unmerge_account_ids) do |account_id|
[account_id, @list.id, 'list']
end
end
def unmerge_account_ids
ListAccount.where(list: @list, account: @accounts).where.not(follow_id: nil).pluck(:account_id)
end
end

View file

@ -31,7 +31,13 @@ class UnfollowService < BaseService
create_notification(follow) if !@target_account.local? && @target_account.activitypub?
create_reject_notification(follow) if @target_account.local? && !@source_account.local? && @source_account.activitypub?
UnmergeWorker.perform_async(@target_account.id, @source_account.id) unless @options[:skip_unmerge]
unless @options[:skip_unmerge]
UnmergeWorker.perform_async(@target_account.id, @source_account.id, 'home')
UnmergeWorker.push_bulk(List.where(account: @source_account).joins(:list_accounts).where(list_accounts: { account_id: @target_account.id }).pluck(:list_id)) do |list_id|
[@target_account.id, list_id, 'list']
end
end
follow
end

View file

@ -6,6 +6,12 @@ class UnmuteService < BaseService
account.unmute!(target_account)
MergeWorker.perform_async(target_account.id, account.id) if account.following?(target_account)
if account.following?(target_account)
MergeWorker.perform_async(target_account.id, account.id, 'home')
MergeWorker.push_bulk(List.where(account: account).joins(:list_accounts).where(list_accounts: { account_id: target_account.id }).pluck(:id)) do |list_id|
[target_account.id, list_id, 'list']
end
end
end
end

View file

@ -26,7 +26,7 @@ class VerifyLinkService < BaseService
def link_back_present?
return false if @body.blank?
links = Nokogiri::HTML5(@body).css("a[rel~='me'],link[rel~='me']")
links = Nokogiri::HTML5(@body).xpath('(//a|//link)[@rel][nokogiri:link_rel_include(@rel, "me")]', NokogiriHandler)
if links.any? { |link| link['href']&.downcase == @link_back.downcase }
true