mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-13 07:49:29 +00:00
Merge commit '1e71c4e247eb8900a718b04113ffce9c1b8ad2f4' into glitch-soc/merge-upstream
This commit is contained in:
@@ -1,65 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Add support for writing recursive CTEs in ActiveRecord
|
||||
|
||||
# Initially from Lorin Thwaits (https://github.com/lorint) as per comment:
|
||||
# https://github.com/vlado/activerecord-cte/issues/16#issuecomment-1433043310
|
||||
|
||||
# Modified from the above code to change the signature to
|
||||
# `with_recursive(hash)` and extending CTE hash values to also includes arrays
|
||||
# of values that get turned into UNION ALL expressions.
|
||||
|
||||
# This implementation has been merged in Rails: https://github.com/rails/rails/pull/51601
|
||||
|
||||
module ActiveRecord
|
||||
module QueryMethodsExtensions
|
||||
def with_recursive(*args)
|
||||
@with_is_recursive = true
|
||||
check_if_method_has_arguments!(__callee__, args)
|
||||
spawn.with_recursive!(*args)
|
||||
end
|
||||
|
||||
# Like #with_recursive but modifies the relation in place.
|
||||
def with_recursive!(*args) # :nodoc:
|
||||
self.with_values += args
|
||||
@with_is_recursive = true
|
||||
self
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_with(arel)
|
||||
return if with_values.empty?
|
||||
|
||||
with_statements = with_values.map do |with_value|
|
||||
raise ArgumentError, "Unsupported argument type: #{with_value} #{with_value.class}" unless with_value.is_a?(Hash)
|
||||
|
||||
build_with_value_from_hash(with_value)
|
||||
end
|
||||
|
||||
# Was: arel.with(with_statements)
|
||||
@with_is_recursive ? arel.with(:recursive, with_statements) : arel.with(with_statements)
|
||||
end
|
||||
|
||||
def build_with_value_from_hash(hash)
|
||||
hash.map do |name, value|
|
||||
Arel::Nodes::TableAlias.new(build_with_expression_from_value(value), name)
|
||||
end
|
||||
end
|
||||
|
||||
def build_with_expression_from_value(value)
|
||||
case value
|
||||
when Arel::Nodes::SqlLiteral then Arel::Nodes::Grouping.new(value)
|
||||
when ActiveRecord::Relation then value.arel
|
||||
when Arel::SelectManager then value
|
||||
when Array then value.map { |e| build_with_expression_from_value(e) }.reduce { |result, value| Arel::Nodes::UnionAll.new(result, value) }
|
||||
else
|
||||
raise ArgumentError, "Unsupported argument type: `#{value}` #{value.class}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActiveSupport.on_load(:active_record) do
|
||||
ActiveRecord::QueryMethods.prepend(ActiveRecord::QueryMethodsExtensions)
|
||||
end
|
||||
@@ -1,51 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Fix an issue with `LIMIT` ocurring on the left side of a `UNION` causing syntax errors.
|
||||
# See https://github.com/rails/rails/issues/40181
|
||||
|
||||
# The fix has been merged in ActiveRecord: https://github.com/rails/rails/pull/51549
|
||||
# TODO: drop this when available in ActiveRecord
|
||||
|
||||
# rubocop:disable all -- This is a mostly vendored file
|
||||
|
||||
module Arel
|
||||
module Visitors
|
||||
class ToSql
|
||||
private
|
||||
|
||||
def infix_value_with_paren(o, collector, value, suppress_parens = false)
|
||||
collector << "( " unless suppress_parens
|
||||
collector = if o.left.class == o.class
|
||||
infix_value_with_paren(o.left, collector, value, true)
|
||||
else
|
||||
select_parentheses o.left, collector, false # Changed from `visit o.left, collector`
|
||||
end
|
||||
collector << value
|
||||
collector = if o.right.class == o.class
|
||||
infix_value_with_paren(o.right, collector, value, true)
|
||||
else
|
||||
select_parentheses o.right, collector, false # Changed from `visit o.right, collector`
|
||||
end
|
||||
collector << " )" unless suppress_parens
|
||||
collector
|
||||
end
|
||||
|
||||
def select_parentheses(o, collector, always_wrap_selects = true)
|
||||
if o.is_a?(Nodes::SelectStatement) && (always_wrap_selects || require_parentheses?(o))
|
||||
collector << "("
|
||||
visit o, collector
|
||||
collector << ")"
|
||||
collector
|
||||
else
|
||||
visit o, collector
|
||||
end
|
||||
end
|
||||
|
||||
def require_parentheses?(o)
|
||||
!o.orders.empty? || o.limit || o.offset
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:enable all
|
||||
@@ -321,7 +321,9 @@ module Mastodon::CLI
|
||||
|
||||
unless skip_domains.empty?
|
||||
say('The following domains were not available during the check:', :yellow)
|
||||
skip_domains.each { |domain| say(" #{domain}") }
|
||||
shell.indent(2) do
|
||||
skip_domains.each { |domain| say(domain) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ module Mastodon::CLI
|
||||
account.account_stat.tap do |account_stat|
|
||||
account_stat.following_count = account.active_relationships.count
|
||||
account_stat.followers_count = account.passive_relationships.count
|
||||
account_stat.statuses_count = account.statuses.where.not(visibility: :direct).count
|
||||
account_stat.statuses_count = account.statuses.not_direct_visibility.count
|
||||
|
||||
account_stat.save if account_stat.changed?
|
||||
end
|
||||
@@ -60,7 +60,7 @@ module Mastodon::CLI
|
||||
|
||||
def recount_status_stats(status)
|
||||
status.status_stat.tap do |status_stat|
|
||||
status_stat.replies_count = status.replies.where.not(visibility: :direct).count
|
||||
status_stat.replies_count = status.replies.not_direct_visibility.count
|
||||
status_stat.reblogs_count = status.reblogs.count
|
||||
status_stat.favourites_count = status.favourites.count
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@ module Mastodon::CLI
|
||||
class EmailDomainBlocks < Base
|
||||
desc 'list', 'List blocked e-mail domains'
|
||||
def list
|
||||
EmailDomainBlock.where(parent_id: nil).find_each do |entry|
|
||||
say(entry.domain.to_s, :white)
|
||||
EmailDomainBlock.parents.find_each do |parent|
|
||||
say(parent.domain.to_s, :white)
|
||||
|
||||
EmailDomainBlock.where(parent_id: entry.id).find_each do |child|
|
||||
say(" #{child.domain}", :cyan)
|
||||
shell.indent do
|
||||
EmailDomainBlock.where(parent_id: parent.id).find_each do |child|
|
||||
say(child.domain, :cyan)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -62,7 +62,9 @@ module Mastodon::CLI
|
||||
failed += 1
|
||||
say('Failure/Error: ', :red)
|
||||
say(entry.full_name)
|
||||
say(" #{custom_emoji.errors[:image].join(', ')}", :red)
|
||||
shell.indent(2) do
|
||||
say(custom_emoji.errors[:image].join(', '), :red)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -80,9 +80,9 @@ module Mastodon::CLI
|
||||
end
|
||||
|
||||
ip_blocks = if options[:force]
|
||||
IpBlock.where('ip >>= ?', address)
|
||||
IpBlock.containing(address)
|
||||
else
|
||||
IpBlock.where('ip <<= ?', address)
|
||||
IpBlock.contained_by(address)
|
||||
end
|
||||
|
||||
if ip_blocks.empty?
|
||||
|
||||
@@ -6,6 +6,8 @@ module Mastodon::CLI
|
||||
class Media < Base
|
||||
include ActionView::Helpers::NumberHelper
|
||||
|
||||
class UnrecognizedOrphanType < StandardError; end
|
||||
|
||||
VALID_PATH_SEGMENTS_SIZE = [7, 10].freeze
|
||||
|
||||
option :days, type: :numeric, default: 7, aliases: [:d]
|
||||
@@ -120,23 +122,10 @@ module Mastodon::CLI
|
||||
object.acl.put(acl: s3_permissions) if options[:fix_permissions] && !dry_run?
|
||||
|
||||
path_segments = object.key.split('/')
|
||||
path_segments.delete('cache')
|
||||
|
||||
unless VALID_PATH_SEGMENTS_SIZE.include?(path_segments.size)
|
||||
progress.log(pastel.yellow("Unrecognized file found: #{object.key}"))
|
||||
next
|
||||
end
|
||||
|
||||
model_name = path_segments.first.classify
|
||||
attachment_name = path_segments[1].singularize
|
||||
record_id = path_segments[2...-2].join.to_i
|
||||
file_name = path_segments.last
|
||||
record = record_map.dig(model_name, record_id)
|
||||
attachment = record&.public_send(attachment_name)
|
||||
|
||||
progress.increment
|
||||
|
||||
next unless attachment.blank? || !attachment.variant?(file_name)
|
||||
next unless orphaned_file?(path_segments, record_map)
|
||||
|
||||
begin
|
||||
object.delete unless dry_run?
|
||||
@@ -148,6 +137,8 @@ module Mastodon::CLI
|
||||
rescue => e
|
||||
progress.log(pastel.red("Error processing #{object.key}: #{e}"))
|
||||
end
|
||||
rescue UnrecognizedOrphanType
|
||||
progress.log(pastel.yellow("Unrecognized file found: #{object.key}"))
|
||||
end
|
||||
end
|
||||
when :fog
|
||||
@@ -165,26 +156,10 @@ module Mastodon::CLI
|
||||
key = path.gsub("#{root_path}#{File::SEPARATOR}", '')
|
||||
|
||||
path_segments = key.split(File::SEPARATOR)
|
||||
path_segments.delete('cache')
|
||||
|
||||
unless VALID_PATH_SEGMENTS_SIZE.include?(path_segments.size)
|
||||
progress.log(pastel.yellow("Unrecognized file found: #{key}"))
|
||||
next
|
||||
end
|
||||
|
||||
model_name = path_segments.first.classify
|
||||
record_id = path_segments[2...-2].join.to_i
|
||||
attachment_name = path_segments[1].singularize
|
||||
file_name = path_segments.last
|
||||
|
||||
next unless PRELOADED_MODELS.include?(model_name)
|
||||
|
||||
record = model_name.constantize.find_by(id: record_id)
|
||||
attachment = record&.public_send(attachment_name)
|
||||
|
||||
progress.increment
|
||||
|
||||
next unless attachment.blank? || !attachment.variant?(file_name)
|
||||
next unless orphaned_file?(path_segments)
|
||||
|
||||
begin
|
||||
size = File.size(path)
|
||||
@@ -205,6 +180,8 @@ module Mastodon::CLI
|
||||
rescue => e
|
||||
progress.log(pastel.red("Error processing #{key}: #{e}"))
|
||||
end
|
||||
rescue UnrecognizedOrphanType
|
||||
progress.log(pastel.yellow("Unrecognized file found: #{path}"))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -364,5 +341,23 @@ module Mastodon::CLI
|
||||
model_map[model_name] = model_name.constantize.where(id: record_ids).index_by(&:id)
|
||||
end
|
||||
end
|
||||
|
||||
def orphaned_file?(path_segments, record_map = nil)
|
||||
path_segments.delete('cache')
|
||||
|
||||
raise UnrecognizedOrphanType unless VALID_PATH_SEGMENTS_SIZE.include?(path_segments.size)
|
||||
|
||||
model_name = path_segments.first.classify
|
||||
record_id = path_segments[2...-2].join.to_i
|
||||
attachment_name = path_segments[1].singularize
|
||||
file_name = path_segments.last
|
||||
|
||||
raise UnrecognizedOrphanType unless PRELOADED_MODELS.include?(model_name)
|
||||
|
||||
record = record_map.present? ? record_map.dig(model_name, record_id) : model_name.constantize.find_by(id: record_id)
|
||||
attachment = record&.public_send(attachment_name)
|
||||
|
||||
attachment.blank? || !attachment.variant?(file_name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,7 +5,7 @@ dev_null = Logger.new('/dev/null')
|
||||
Rails.logger = dev_null
|
||||
ActiveRecord::Base.logger = dev_null
|
||||
ActiveJob::Base.logger = dev_null
|
||||
HttpLog.configuration.logger = dev_null
|
||||
HttpLog.configuration.logger = dev_null if defined?(HttpLog)
|
||||
Paperclip.options[:log] = false
|
||||
Chewy.logger = dev_null
|
||||
|
||||
|
||||
@@ -596,7 +596,7 @@ def disable_log_stdout!
|
||||
|
||||
Rails.logger = dev_null
|
||||
ActiveRecord::Base.logger = dev_null
|
||||
HttpLog.configuration.logger = dev_null
|
||||
HttpLog.configuration.logger = dev_null if defined?(HttpLog)
|
||||
Paperclip.options[:log] = false
|
||||
end
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace :repo do
|
||||
|
||||
url = "https://api.github.com/repos/#{REPOSITORY_NAME}/contributors?anon=1"
|
||||
|
||||
HttpLog.config.compact_log = true
|
||||
HttpLog.config.compact_log = true if defined?(HttpLog)
|
||||
|
||||
while url.present?
|
||||
response = HTTP.get(url)
|
||||
@@ -43,7 +43,7 @@ namespace :repo do
|
||||
path = Rails.root.join('CHANGELOG.md')
|
||||
tmp = Tempfile.new
|
||||
|
||||
HttpLog.config.compact_log = true
|
||||
HttpLog.config.compact_log = true if defined?(HttpLog)
|
||||
|
||||
begin
|
||||
File.open(path, 'r') do |file|
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace :tests do
|
||||
'3_3_0' => 2020_12_18_054746,
|
||||
}.each do |release, version|
|
||||
ActiveRecord::Tasks::DatabaseTasks
|
||||
.migration_connection
|
||||
.migration_connection_pool
|
||||
.migration_context
|
||||
.migrate(version)
|
||||
Rake::Task["tests:migrations:populate_v#{release}"]
|
||||
|
||||
Reference in New Issue
Block a user