Merge commit '15fd712464
' into kb_migration
This commit is contained in:
commit
3a1a6ba39e
289 changed files with 1339 additions and 1337 deletions
|
@ -240,9 +240,9 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
end
|
||||
|
||||
def searchability_from_audience
|
||||
if audience_searchable_by.nil?
|
||||
:private
|
||||
elsif audience_searchable_by.any? { |uri| ActivityPub::TagManager.instance.public_collection?(uri) }
|
||||
return :private if audience_searchable_by.nil?
|
||||
|
||||
if audience_searchable_by.any? { |uri| ActivityPub::TagManager.instance.public_collection?(uri) }
|
||||
:public
|
||||
elsif audience_searchable_by.include?(@account.followers_url)
|
||||
:unlisted # Followers only in kmyblue (generics: private)
|
||||
|
@ -259,7 +259,7 @@ class ActivityPub::ProcessAccountService < BaseService
|
|||
|
||||
def subscribable(note)
|
||||
if subscribable_by.nil?
|
||||
!note.include?('[subscribable:no]')
|
||||
note.exclude?('[subscribable:no]')
|
||||
else
|
||||
subscribable_by.any? { |uri| ActivityPub::TagManager.instance.public_collection?(uri) }
|
||||
end
|
||||
|
|
|
@ -4,12 +4,10 @@ module AccountLimitable
|
|||
def scope_status(status)
|
||||
case status.visibility.to_sym
|
||||
when :public, :unlisted, :public_unlisted
|
||||
#scope_local.merge(scope_list_following_account(status.account))
|
||||
# scope_local.merge(scope_list_following_account(status.account))
|
||||
scope_local
|
||||
when :private
|
||||
scope_account_local_followers(status.account)
|
||||
when :limited
|
||||
scope_status_mentioned(status)
|
||||
else
|
||||
scope_status_mentioned(status)
|
||||
end
|
||||
|
@ -32,7 +30,7 @@ module AccountLimitable
|
|||
account.lists_for_local_distribution.select(:id).reorder(nil)
|
||||
end
|
||||
|
||||
def scope_tag_following_account(status)
|
||||
def scope_tag_following_account(_status)
|
||||
TagFollow.where(tag_id: @status.tags.map(&:id)).select('account_id AS id').reorder(nil)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -122,20 +122,21 @@ class FanOutOnWriteService < BaseService
|
|||
domain = @account.domain || Rails.configuration.x.local_domain
|
||||
|
||||
antennas = Antenna.availables
|
||||
antennas = antennas.left_joins(:antenna_accounts).where(any_accounts: true).or(Antenna.availables.left_joins(:antenna_accounts) .where(antenna_accounts: { exclude: false, account: @account }))
|
||||
antennas = antennas.left_joins(:antenna_domains) .where(any_domains: true) .or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains) .where(antenna_domains: { exclude: false, name: domain }))
|
||||
antennas = antennas.left_joins(:antenna_tags) .where(any_tags: true) .or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains).left_joins(:antenna_tags).where(antenna_tags: { exclude: false, tag: @status.tags }))
|
||||
antennas = antennas.left_joins(:antenna_accounts).where(any_accounts: true).or(Antenna.availables.left_joins(:antenna_accounts).where(antenna_accounts: { exclude: false, account: @account }))
|
||||
antennas = antennas.left_joins(:antenna_domains).where(any_domains: true).or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains).where(antenna_domains: { exclude: false, name: domain }))
|
||||
antennas = antennas.left_joins(:antenna_tags).where(any_tags: true).or(Antenna.availables.left_joins(:antenna_accounts).left_joins(:antenna_domains).left_joins(:antenna_tags).where(antenna_tags: { exclude: false, tag: @status.tags }))
|
||||
antennas = antennas.where(account: @account.followers) if @status.visibility.to_sym == :unlisted
|
||||
antennas = antennas.where(with_media_only: false) if !@status.with_media?
|
||||
antennas = antennas.where(with_media_only: false) unless @status.with_media?
|
||||
antennas = antennas.where.not(account: @account.blocking)
|
||||
antennas.in_batches do |ans|
|
||||
ans.each do |antenna|
|
||||
next if !antenna.enabled?
|
||||
next if antenna.keywords.any? && !antenna.keywords.any? { |keyword| @status.text.include?(keyword) }
|
||||
next unless antenna.enabled?
|
||||
next if antenna.keywords.any? && antenna.keywords.none? { |keyword| @status.text.include?(keyword) }
|
||||
next if antenna.exclude_keywords&.any? { |keyword| @status.text.include?(keyword) }
|
||||
next if antenna.exclude_accounts&.include?(@status.account_id)
|
||||
next if antenna.exclude_domains&.include?(domain)
|
||||
next if antenna.exclude_tags&.any? { |tag_id| tag_ids.include?(tag_id) }
|
||||
|
||||
lists << antenna.list_id
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class GroupReblogService < BaseService
|
|||
return nil if status.account.group?
|
||||
|
||||
visibility = status.visibility.to_sym
|
||||
return nil if !%i(public public_unlisted unlisted private direct).include?(visibility)
|
||||
return nil unless %i(public public_unlisted unlisted private direct).include?(visibility)
|
||||
|
||||
accounts = status.mentions.map(&:account) | status.active_mentions.map(&:account)
|
||||
transcription = %i(private direct).include?(visibility)
|
||||
|
@ -21,49 +21,48 @@ class GroupReblogService < BaseService
|
|||
next if account.id == status.account_id
|
||||
next if transcription && !account.group_allow_private_message
|
||||
|
||||
if status.account.activitypub? && ACTIVITYPUB_CONTINUOUS_SIZE > 0
|
||||
if status.account.activitypub? && ACTIVITYPUB_CONTINUOUS_SIZE.positive?
|
||||
next if account.group_activitypub_count >= ACTIVITYPUB_CONTINUOUS_SIZE
|
||||
|
||||
account.group_activitypub_count = account.group_activitypub_count + 1
|
||||
account.save!
|
||||
else
|
||||
if account.group_activitypub_count > 0
|
||||
account.group_activitypub_count = 0
|
||||
account.save!
|
||||
elsif account.group_activitypub_count.positive?
|
||||
account.group_activitypub_count = 0
|
||||
account.save!
|
||||
end
|
||||
|
||||
ReblogService.new.call(account, status, { visibility: status.visibility }) unless transcription
|
||||
|
||||
next unless transcription
|
||||
|
||||
username = status.account.local? ? status.account.username : "#{status.account.username}@#{status.account.domain}"
|
||||
|
||||
media_attachments = status.media_attachments.map do |media|
|
||||
media.needs_redownload? ? media_proxy_url(media.id, :original) : full_asset_url(media.file.url(:original))
|
||||
MediaAttachment.create(
|
||||
account: account,
|
||||
remote_url: media_url(media),
|
||||
thumbnail_remote_url: media_preview_url(media)
|
||||
).tap do |attachment|
|
||||
attachment.download_file!
|
||||
attachment.save
|
||||
end
|
||||
end
|
||||
|
||||
ReblogService.new.call(account, status, { visibility: status.visibility }) if !transcription
|
||||
text = status.account.local? ? status.text : strip_tags(status.text.gsub(/<br>/, "\n").gsub(%r{<br />}, "\n").gsub(%r{</p>}, "\n\n").strip)
|
||||
|
||||
if transcription
|
||||
username = status.account.local? ? status.account.username : "#{status.account.username}@#{status.account.domain}"
|
||||
|
||||
media_attachments = status.media_attachments.map do |media|
|
||||
url = media.needs_redownload? ? media_proxy_url(media.id, :original) : full_asset_url(media.file.url(:original))
|
||||
MediaAttachment.create(
|
||||
account: account,
|
||||
remote_url: media_url(media),
|
||||
thumbnail_remote_url: media_preview_url(media),
|
||||
).tap do |attachment|
|
||||
attachment.download_file!
|
||||
attachment.save
|
||||
end
|
||||
end
|
||||
|
||||
text = status.account.local? ? status.text : strip_tags(status.text.gsub(/<br>/, "\n").gsub(/<br \/>/, "\n").gsub(/<\/p>/, "\n\n").strip)
|
||||
|
||||
PostStatusService.new.call(
|
||||
account,
|
||||
text: "Private message by @#{username}\n\\-\\-\\-\\-\n#{text}",
|
||||
thread: status.thread,
|
||||
media_ids: media_attachments.map(&:id),
|
||||
sensitive: status.sensitive,
|
||||
spoiler_text: status.spoiler_text,
|
||||
visibility: :private,
|
||||
language: status.language,
|
||||
poll: status.poll,
|
||||
with_rate_limit: true
|
||||
)
|
||||
end
|
||||
PostStatusService.new.call(
|
||||
account,
|
||||
text: "Private message by @#{username}\n\\-\\-\\-\\-\n#{text}",
|
||||
thread: status.thread,
|
||||
media_ids: media_attachments.map(&:id),
|
||||
sensitive: status.sensitive,
|
||||
spoiler_text: status.spoiler_text,
|
||||
visibility: :private,
|
||||
language: status.language,
|
||||
poll: status.poll,
|
||||
with_rate_limit: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ class ImportService < BaseService
|
|||
def parse_import_data!(default_headers)
|
||||
data = CSV.parse(import_data, headers: true)
|
||||
data = CSV.parse(import_data, headers: default_headers) unless data.headers&.first&.strip&.include?(' ')
|
||||
@data = data.reject(&:blank?)
|
||||
@data = data.compact_blank
|
||||
end
|
||||
|
||||
def import_data
|
||||
|
|
|
@ -70,8 +70,8 @@ class PostStatusService < BaseService
|
|||
@visibility = @options[:visibility] || @account.user&.setting_default_privacy
|
||||
@visibility = :unlisted if (@visibility&.to_sym == :public || @visibility&.to_sym == :public_unlisted) && @account.silenced?
|
||||
@visibility = :public_unlisted if @visibility&.to_sym == :public && !@options[:force_visibility] && !@options[:application]&.superapp && @account.user&.setting_public_post_to_unlisted
|
||||
@searchability= searchability
|
||||
@markdown = !!@options[:markdown]
|
||||
@searchability = searchability
|
||||
@markdown = @options[:markdown] || false
|
||||
@scheduled_at = @options[:scheduled_at]&.to_datetime
|
||||
@scheduled_at = nil if scheduled_in_the_past?
|
||||
rescue ArgumentError
|
||||
|
@ -98,7 +98,7 @@ class PostStatusService < BaseService
|
|||
@status = @account.statuses.new(status_attributes)
|
||||
process_mentions_service.call(@status, save_records: false)
|
||||
safeguard_mentions!(@status)
|
||||
|
||||
|
||||
UpdateStatusExpirationService.new.call(@status)
|
||||
|
||||
# The following transaction block is needed to wrap the UPDATEs to
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
class SearchService < BaseService
|
||||
def call(query, account, limit, options = {})
|
||||
@query = query&.strip
|
||||
@query = query&.strip
|
||||
pull_query_commands
|
||||
|
||||
@account = account
|
||||
|
@ -28,7 +28,7 @@ class SearchService < BaseService
|
|||
private
|
||||
|
||||
MIN_SCORE = 0.7
|
||||
MIN_SCORE_RE = /MINSCORE=((([\d]+\.[\d]+)|([\d]+)){1,6})/.freeze
|
||||
MIN_SCORE_RE = /MINSCORE=(((\d+\.\d+)|(\d+)){1,6})/
|
||||
|
||||
def perform_accounts_search!
|
||||
AccountSearchService.new.call(
|
||||
|
@ -71,7 +71,7 @@ class SearchService < BaseService
|
|||
results = definition.limit(@limit).offset(@offset).objects.compact
|
||||
account_ids = results.map(&:account_id)
|
||||
account_domains = results.map(&:account_domain)
|
||||
account_relations = @account.relations_map(account_ids, account_domains) # variable old name: preloaded_relations
|
||||
account_relations = @account.relations_map(account_ids, account_domains) # variable old name: preloaded_relations
|
||||
|
||||
results.reject { |status| StatusFilter.new(status, @account, account_relations).filtered? }
|
||||
rescue Faraday::ConnectionFailed, Parslet::ParseFailed
|
||||
|
@ -137,11 +137,10 @@ class SearchService < BaseService
|
|||
@min_score = MIN_SCORE
|
||||
|
||||
min_score_result = @query.scan(MIN_SCORE_RE).first
|
||||
if (min_score_result)
|
||||
@min_score = min_score_result[1].to_f
|
||||
@query = @query.gsub(MIN_SCORE_RE, '').strip
|
||||
end
|
||||
return unless min_score_result
|
||||
|
||||
@min_score = min_score_result[1].to_f
|
||||
@query = @query.gsub(MIN_SCORE_RE, '').strip
|
||||
end
|
||||
|
||||
def parsed_query
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
class SearchabilityUpdateService < BaseService
|
||||
def call(account)
|
||||
statuses = account.statuses.unset_searchability
|
||||
statuses = account.statuses.unset_searchability
|
||||
|
||||
return unless statuses.exists?
|
||||
|
||||
ids = statuses.pluck(:id)
|
||||
|
||||
# rubocop:disable Rails/SkipsModelValidations
|
||||
if account.public_searchability?
|
||||
statuses.update_all('searchability = CASE visibility WHEN 0 THEN 0 WHEN 10 THEN 0 WHEN 1 THEN 2 WHEN 2 THEN 2 ELSE 3 END, updated_at = CURRENT_TIMESTAMP')
|
||||
elsif account.unlisted_searchability?
|
||||
|
@ -17,6 +18,7 @@ class SearchabilityUpdateService < BaseService
|
|||
else
|
||||
statuses.update_all('searchability = 3, updated_at = CURRENT_TIMESTAMP')
|
||||
end
|
||||
# rubocop:enable Rails/SkipsModelValidations
|
||||
|
||||
return unless Chewy.enabled?
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class UnEmojiReactService < BaseService
|
|||
|
||||
def write_stream(emoji_reaction)
|
||||
emoji_group = @status.emoji_reactions_grouped_by_name
|
||||
.find { |reaction_group| reaction_group['name'] == emoji_reaction.name && (!reaction_group.key?(:domain) || reaction_group['domain'] == emoji_reaction.custom_emoji&.domain) }
|
||||
.find { |reaction_group| reaction_group['name'] == emoji_reaction.name && (!reaction_group.key?(:domain) || reaction_group['domain'] == emoji_reaction.custom_emoji&.domain) }
|
||||
if emoji_group
|
||||
emoji_group['status_id'] = @status.id.to_s
|
||||
else
|
||||
|
|
|
@ -21,7 +21,7 @@ class UpdateAccountService < BaseService
|
|||
|
||||
def authorize_all_follow_requests(account)
|
||||
follow_requests = FollowRequest.where(target_account: account)
|
||||
follow_requests = follow_requests.preload(:account).select { |req| !req.account.silenced? && !reject_straight_follow_domains.include?(req.account.domain) }
|
||||
follow_requests = follow_requests.preload(:account).select { |req| !req.account.silenced? && reject_straight_follow_domains.exclude?(req.account.domain) }
|
||||
AuthorizeFollowWorker.push_bulk(follow_requests, limit: 1_000) do |req|
|
||||
[req.account_id, req.target_account_id]
|
||||
end
|
||||
|
|
|
@ -5,17 +5,24 @@ class UpdateStatusExpirationService < BaseService
|
|||
|
||||
def call(status)
|
||||
existing_expiration = ScheduledExpirationStatus.find_by(status: status)
|
||||
existing_expiration.destroy! if existing_expiration
|
||||
existing_expiration&.destroy!
|
||||
|
||||
expiration = status.text.scan(SCAN_EXPIRATION_RE).first
|
||||
return if !expiration
|
||||
return unless expiration
|
||||
|
||||
expiration_num = expiration[1].to_f
|
||||
expiration_option = expiration[2]
|
||||
base_time = status.created_at || Time.now.utc
|
||||
due = expiration_option == 'd' ? expiration_num.days :
|
||||
expiration_option == 'h' ? expiration_num.hours :
|
||||
expiration_option == 's' ? expiration_num.seconds : expiration_num.minutes
|
||||
|
||||
# rubocop:disable Style/CaseLikeIf
|
||||
due = if expiration_option == 'd'
|
||||
expiration_num.days
|
||||
elsif expiration_option == 'h'
|
||||
expiration_num.hours
|
||||
else
|
||||
expiration_option == 's' ? expiration_num.seconds : expiration_num.minutes
|
||||
end
|
||||
# rubocop:enable Style/CaseLikeIf
|
||||
|
||||
expired_at = base_time + due
|
||||
expired_status = ScheduledExpirationStatus.create!(account: status.account, status: status, scheduled_at: expired_at)
|
||||
|
|
|
@ -113,13 +113,13 @@ class UpdateStatusService < BaseService
|
|||
def update_immediate_attributes!
|
||||
@status.text = @options[:text].presence || @options.delete(:spoiler_text) || '' if @options.key?(:text)
|
||||
@status.spoiler_text = @options[:spoiler_text] || '' if @options.key?(:spoiler_text)
|
||||
@status.markdown = !!@options[:markdown]
|
||||
@status.markdown = @options[:markdown] || false
|
||||
@status.sensitive = @options[:sensitive] || @options[:spoiler_text].present? if @options.key?(:sensitive) || @options.key?(:spoiler_text)
|
||||
@status.language = valid_locale_cascade(@options[:language], @status.language, @status.account.user&.preferred_posting_language, I18n.default_locale)
|
||||
|
||||
# We raise here to rollback the entire transaction
|
||||
raise NoChangesSubmittedError unless significant_changes?
|
||||
|
||||
|
||||
update_expiration!
|
||||
|
||||
@status.edited_at = Time.now.utc
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue