Refactor how public and tag timelines are queried (#14728)

This commit is contained in:
Eugen Rochko 2020-09-07 11:02:04 +02:00 committed by GitHub
parent a6121a159c
commit e8bc187845
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 429 additions and 378 deletions

View file

@ -85,12 +85,12 @@ class Status < ApplicationRecord
scope :recent, -> { reorder(id: :desc) }
scope :remote, -> { where(local: false).where.not(uri: nil) }
scope :local, -> { where(local: true).or(where(uri: nil)) }
scope :with_accounts, ->(ids) { where(id: ids).includes(:account) }
scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') }
scope :without_reblogs, -> { where('statuses.reblog_of_id IS NULL') }
scope :with_public_visibility, -> { where(visibility: :public) }
scope :tagged_with, ->(tag) { joins(:statuses_tags).where(statuses_tags: { tag_id: tag }) }
scope :in_chosen_languages, ->(account) { where(language: nil).or where(language: account.chosen_languages) }
scope :excluding_silenced_accounts, -> { left_outer_joins(:account).where(accounts: { silenced_at: nil }) }
scope :including_silenced_accounts, -> { left_outer_joins(:account).where.not(accounts: { silenced_at: nil }) }
scope :not_excluded_by_account, ->(account) { where.not(account_id: account.excluded_from_timeline_account_ids) }
@ -277,26 +277,6 @@ class Status < ApplicationRecord
visibilities.keys - %w(direct limited)
end
def in_chosen_languages(account)
where(language: nil).or where(language: account.chosen_languages)
end
def as_public_timeline(account = nil, local_only = false)
query = timeline_scope(local_only).without_replies
apply_timeline_filters(query, account, [:local, true].include?(local_only))
end
def as_tag_timeline(tag, account = nil, local_only = false)
query = timeline_scope(local_only).tagged_with(tag)
apply_timeline_filters(query, account, local_only)
end
def as_outbox_timeline(account)
where(account: account, visibility: :public)
end
def favourites_map(status_ids, account_id)
Favourite.select('status_id').where(status_id: status_ids).where(account_id: account_id).each_with_object({}) { |f, h| h[f.status_id] = true }
end
@ -373,51 +353,6 @@ class Status < ApplicationRecord
status&.distributable? ? status : nil
end.compact
end
private
def timeline_scope(scope = false)
starting_scope = case scope
when :local, true
Status.local
when :remote
Status.remote
else
Status
end
starting_scope
.with_public_visibility
.without_reblogs
end
def apply_timeline_filters(query, account, local_only)
if account.nil?
filter_timeline_default(query)
else
filter_timeline_for_account(query, account, local_only)
end
end
def filter_timeline_for_account(query, account, local_only)
query = query.not_excluded_by_account(account)
query = query.not_domain_blocked_by_account(account) unless local_only
query = query.in_chosen_languages(account) if account.chosen_languages.present?
query.merge(account_silencing_filter(account))
end
def filter_timeline_default(query)
query.excluding_silenced_accounts
end
def account_silencing_filter(account)
if account.silenced?
including_myself = left_outer_joins(:account).where(account_id: account.id).references(:accounts)
excluding_silenced_accounts.or(including_myself)
else
excluding_silenced_accounts
end
end
end
def status_stat