Merge commit 'f877aa9d70d0d600961989b8e97c0e0ce3ac1db6' into glitch-soc/merge-upstream

Conflicts:
- `.github/dependabot.yml`:
  Upstream made changes, but we had removed it.
  Discarded upstream changes.
- `.rubocop_todo.yml`:
  Upstream regenerated the file, we had some glitch-soc-specific ignores.
- `app/models/account_statuses_filter.rb`:
  Minor upstream code style change where glitch-soc had slightly different code
  due to handling of local-only posts.
  Updated to match upstream's code style.
- `app/models/status.rb`:
  Upstream moved ActiveRecord callback definitions, glitch-soc had an extra one.
  Moved the definitions as upstream did.
- `app/services/backup_service.rb`:
  Upstream rewrote a lot of the backup service, glitch-soc had changes because
  of exporting local-only posts.
  Took upstream changes and added back code to deal with local-only posts.
- `config/routes.rb`:
  Upstream split the file into different files, while glitch-soc had a few
  extra routes.
  Extra routes added to `config/routes/settings.rb`, `config/routes/api.rb`
  and `config/routes/admin.rb`
- `db/schema.rb`:
  Upstream has new migrations, while glitch-soc had an extra migration.
  Updated the expected serial number to match upstream's.
- `lib/mastodon/version.rb`:
  Upstream added support to set version tags from environment variables, while
  glitch-soc has an extra `+glitch` tag.
  Changed the code to support upstream's feature but prepending a `+glitch`.
- `spec/lib/activitypub/activity/create_spec.rb`:
  Minor code style change upstream, while glitch-soc has extra tests due to
  `directMessage` handling.
  Applied upstream's changes while keeping glitch-soc's extra tests.
- `spec/models/concerns/account_interactions_spec.rb`:
  Minor code style change upstream, while glitch-soc has extra tests.
  Applied upstream's changes while keeping glitch-soc's extra tests.
This commit is contained in:
Claire
2023-05-08 19:05:55 +02:00
429 changed files with 6138 additions and 3323 deletions

View File

@ -43,7 +43,7 @@ class ActivityTracker
case @type
when :basic
redis.mget(*keys).map(&:to_i).sum
redis.mget(*keys).sum(&:to_i)
when :unique
redis.pfcount(*keys)
end

View File

@ -4,7 +4,7 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
def perform
return reject_payload! if delete_arrived_first?(@json['id']) || !related_to_local_activity?
with_lock("announce:#{value_or_id(@object)}") do
with_redis_lock("announce:#{value_or_id(@object)}") do
original_status = status_from_object
return reject_payload! if original_status.nil? || !announceable?(original_status)

View File

@ -47,7 +47,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
def create_status
return reject_payload! if unsupported_object_type? || non_matching_uri_hosts?(@account.uri, object_uri) || tombstone_exists? || !related_to_local_activity?
with_lock("create:#{object_uri}") do
with_redis_lock("create:#{object_uri}") do
return if delete_arrived_first?(object_uri) || poll_vote?
@status = find_existing_status
@ -313,7 +313,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
poll = replied_to_status.preloadable_poll
already_voted = true
with_lock("vote:#{replied_to_status.poll_id}:#{@account.id}") do
with_redis_lock("vote:#{replied_to_status.poll_id}:#{@account.id}") do
already_voted = poll.votes.where(account: @account).exists?
poll.votes.create!(account: @account, choice: poll.options.index(@object['name']), uri: object_uri)
end

View File

@ -12,7 +12,7 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
private
def delete_person
with_lock("delete_in_progress:#{@account.id}", autorelease: 2.hours, raise_on_failure: false) do
with_redis_lock("delete_in_progress:#{@account.id}", autorelease: 2.hours, raise_on_failure: false) do
DeleteAccountService.new.call(@account, reserve_username: false, skip_activitypub: true)
end
end
@ -20,14 +20,14 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
def delete_note
return if object_uri.nil?
with_lock("delete_status_in_progress:#{object_uri}", raise_on_failure: false) do
with_redis_lock("delete_status_in_progress:#{object_uri}", raise_on_failure: false) do
unless non_matching_uri_hosts?(@account.uri, object_uri)
# This lock ensures a concurrent `ActivityPub::Activity::Create` either
# does not create a status at all, or has finished saving it to the
# database before we try to load it.
# Without the lock, `delete_later!` could be called after `delete_arrived_first?`
# and `Status.find` before `Status.create!`
with_lock("create:#{object_uri}") { delete_later!(object_uri) }
with_redis_lock("create:#{object_uri}") { delete_later!(object_uri) }
Tombstone.find_or_create_by(uri: object_uri, account: @account)
end

View File

@ -13,7 +13,7 @@ module ActivityPub::CaseTransform
when Symbol then camel_lower(value.to_s).to_sym
when String
camel_lower_cache[value] ||= if value.start_with?('_:')
"_:#{value.gsub(/\A_:/, '').underscore.camelize(:lower)}"
"_:#{value.delete_prefix('_:').underscore.camelize(:lower)}"
else
value.underscore.camelize(:lower)
end

View File

@ -407,10 +407,10 @@ class FeedManager
return true if crutches[:languages][status.account_id].present? && status.language.present? && !crutches[:languages][status.account_id].include?(status.language)
check_for_blocks = crutches[:active_mentions][status.id] || []
check_for_blocks.concat([status.account_id])
check_for_blocks.push(status.account_id)
if status.reblog?
check_for_blocks.concat([status.reblog.account_id])
check_for_blocks.push(status.reblog.account_id)
check_for_blocks.concat(crutches[:active_mentions][status.reblog_of_id] || [])
end
@ -446,7 +446,7 @@ class FeedManager
# the notification has been checked for mute/block. Therefore, it's not
# necessary to check the author of the toot for mute/block again
check_for_blocks = status.active_mentions.pluck(:account_id)
check_for_blocks.concat([status.in_reply_to_account]) if status.reply? && !status.in_reply_to_account_id.nil?
check_for_blocks.push(status.in_reply_to_account) if status.reply? && !status.in_reply_to_account_id.nil?
should_filter = blocks_or_mutes?(receiver_id, check_for_blocks, :mentions) # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted)
should_filter ||= (status.account.silenced? && !Follow.where(account_id: receiver_id, target_account_id: status.account_id).exists?) # of if the account is silenced and I'm not following them
@ -593,10 +593,10 @@ class FeedManager
check_for_blocks = statuses.flat_map do |s|
arr = crutches[:active_mentions][s.id] || []
arr.concat([s.account_id])
arr.push(s.account_id)
if s.reblog?
arr.concat([s.reblog.account_id])
arr.push(s.reblog.account_id)
arr.concat(crutches[:active_mentions][s.reblog_of_id] || [])
end

View File

@ -6,8 +6,8 @@ class Importer::AccountsIndexImporter < Importer::BaseImporter
in_work_unit(tmp) do |accounts|
bulk = Chewy::Index::Import::BulkBuilder.new(index, to_index: accounts).bulk_body
indexed = bulk.select { |entry| entry[:index] }.size
deleted = bulk.select { |entry| entry[:delete] }.size
indexed = bulk.count { |entry| entry[:index] }
deleted = bulk.count { |entry| entry[:delete] }
Chewy::Index::Import::BulkRequest.new(index).perform(bulk)

View File

@ -6,8 +6,8 @@ class Importer::TagsIndexImporter < Importer::BaseImporter
in_work_unit(tmp) do |tags|
bulk = Chewy::Index::Import::BulkBuilder.new(index, to_index: tags).bulk_body
indexed = bulk.select { |entry| entry[:index] }.size
deleted = bulk.select { |entry| entry[:delete] }.size
indexed = bulk.count { |entry| entry[:index] }
deleted = bulk.count { |entry| entry[:delete] }
Chewy::Index::Import::BulkRequest.new(index).perform(bulk)

View File

@ -8,21 +8,51 @@ class PermalinkRedirector
end
def redirect_path
if path_segments[0].present? && path_segments[0].start_with?('@') && path_segments[1] =~ /\d/
find_status_url_by_id(path_segments[1])
elsif path_segments[0].present? && path_segments[0].start_with?('@')
find_account_url_by_name(path_segments[0])
elsif path_segments[0] == 'statuses' && path_segments[1] =~ /\d/
find_status_url_by_id(path_segments[1])
elsif path_segments[0] == 'accounts' && path_segments[1] =~ /\d/
find_account_url_by_id(path_segments[1])
if at_username_status_request? || statuses_status_request?
find_status_url_by_id(second_segment)
elsif at_username_request?
find_account_url_by_name(first_segment)
elsif accounts_request? && record_integer_id_request?
find_account_url_by_id(second_segment)
end
end
private
def at_username_status_request?
at_username_request? && record_integer_id_request?
end
def statuses_status_request?
statuses_request? && record_integer_id_request?
end
def at_username_request?
first_segment.present? && first_segment.start_with?('@')
end
def statuses_request?
first_segment == 'statuses'
end
def accounts_request?
first_segment == 'accounts'
end
def record_integer_id_request?
second_segment =~ /\d/
end
def first_segment
path_segments.first
end
def second_segment
path_segments.second
end
def path_segments
@path_segments ||= @path.gsub(/\A\//, '').split('/')
@path_segments ||= @path.delete_prefix('/').split('/')
end
def find_status_url_by_id(id)

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class Vacuum::ImportsVacuum
def perform
clean_unconfirmed_imports!
clean_old_imports!
end
private
def clean_unconfirmed_imports!
BulkImport.where(state: :unconfirmed).where('created_at <= ?', 10.minutes.ago).reorder(nil).in_batches.delete_all
end
def clean_old_imports!
BulkImport.where('created_at <= ?', 1.week.ago).reorder(nil).in_batches.delete_all
end
end

View File

@ -57,7 +57,7 @@ class WebfingerResource
end
def resource_without_acct_string
resource.gsub(/\Aacct:/, '')
resource.delete_prefix('acct:')
end
def local_username