Merge tag 'v3.0.0' into hometown-dev

This commit is contained in:
Darius Kazemi
2019-10-08 13:24:20 -07:00
1012 changed files with 31176 additions and 15165 deletions

View File

@ -24,21 +24,24 @@
# poll_id :bigint(8)
# local_only :boolean
# activity_pub_type :string
# deleted_at :datetime
#
class Status < ApplicationRecord
before_destroy :unlink_from_conversations
include Discard::Model
include Paginable
include Streamable
include Cacheable
include StatusThreadingConcern
self.discard_column = :deleted_at
# If `override_timestamps` is set at creation time, Snowflake ID creation
# will be based on current time instead of `created_at`
attr_accessor :override_timestamps
update_index('statuses#status', :proper) if Chewy.enabled?
update_index('statuses#status', :proper)
enum visibility: [:public, :unlisted, :private, :direct, :limited], _suffix: :visibility
@ -63,7 +66,6 @@ class Status < ApplicationRecord
has_and_belongs_to_many :preview_cards
has_one :notification, as: :activity, dependent: :destroy
has_one :stream_entry, as: :activity, inverse_of: :status
has_one :status_stat, inverse_of: :status
has_one :poll, inverse_of: :status, dependent: :destroy
@ -76,7 +78,7 @@ class Status < ApplicationRecord
accepts_nested_attributes_for :poll
default_scope { recent }
default_scope { recent.kept }
scope :recent, -> { reorder(id: :desc) }
scope :remote, -> { where(local: false).where.not(uri: nil) }
@ -109,13 +111,11 @@ class Status < ApplicationRecord
:status_stat,
:tags,
:preview_cards,
:stream_entry,
:preloadable_poll,
account: :account_stat,
active_mentions: { account: :account_stat },
reblog: [
:application,
:stream_entry,
:tags,
:preview_cards,
:media_attachments,
@ -132,12 +132,14 @@ class Status < ApplicationRecord
REAL_TIME_WINDOW = 6.hours
def searchable_by(preloaded = nil)
ids = [account_id]
ids = []
ids << account_id if local?
if preloaded.nil?
ids += mentions.pluck(:account_id)
ids += favourites.pluck(:account_id)
ids += reblogs.pluck(:account_id)
ids += mentions.where(account: Account.local).pluck(:account_id)
ids += favourites.where(account: Account.local).pluck(:account_id)
ids += reblogs.where(account: Account.local).pluck(:account_id)
else
ids += preloaded.mentions[id] || []
ids += preloaded.favourites[id] || []
@ -204,7 +206,7 @@ class Status < ApplicationRecord
end
def hidden?
private_visibility? || direct_visibility? || limited_visibility?
!distributable?
end
def distributable?
@ -221,6 +223,10 @@ class Status < ApplicationRecord
!sensitive? && with_media?
end
def reported?
@reported ||= Report.where(target_account: account).unresolved.where('? = ANY(status_ids)', id).exists?
end
def emojis
return @emojis if defined?(@emojis)
@ -289,47 +295,6 @@ class Status < ApplicationRecord
where(account: [account] + account.following).where(visibility: [:public, :unlisted, :private])
end
def as_direct_timeline(account, limit = 20, max_id = nil, since_id = nil, cache_ids = false)
# direct timeline is mix of direct message from_me and to_me.
# 2 queries are executed with pagination.
# constant expression using arel_table is required for partial index
# _from_me part does not require any timeline filters
query_from_me = where(account_id: account.id)
.where(Status.arel_table[:visibility].eq(3))
.limit(limit)
.order('statuses.id DESC')
# _to_me part requires mute and block filter.
# FIXME: may we check mutes.hide_notifications?
query_to_me = Status
.joins(:mentions)
.merge(Mention.where(account_id: account.id))
.where(Status.arel_table[:visibility].eq(3))
.limit(limit)
.order('mentions.status_id DESC')
.not_excluded_by_account(account)
if max_id.present?
query_from_me = query_from_me.where('statuses.id < ?', max_id)
query_to_me = query_to_me.where('mentions.status_id < ?', max_id)
end
if since_id.present?
query_from_me = query_from_me.where('statuses.id > ?', since_id)
query_to_me = query_to_me.where('mentions.status_id > ?', since_id)
end
if cache_ids
# returns array of cache_ids object that have id and updated_at
(query_from_me.cache_ids.to_a + query_to_me.cache_ids.to_a).uniq(&:id).sort_by(&:id).reverse.take(limit)
else
# returns ActiveRecord.Relation
items = (query_from_me.select(:id).to_a + query_to_me.select(:id).to_a).uniq(&:id).sort_by(&:id).reverse.take(limit)
Status.where(id: items.map(&:id))
end
end
def as_public_timeline(account = nil, local_only = false)
query = timeline_scope(local_only).without_replies
@ -351,7 +316,7 @@ class Status < ApplicationRecord
end
def reblogs_map(status_ids, account_id)
select('reblog_of_id').where(reblog_of_id: status_ids).where(account_id: account_id).reorder(nil).each_with_object({}) { |s, h| h[s.reblog_of_id] = true }
unscoped.select('reblog_of_id').where(reblog_of_id: status_ids).where(account_id: account_id).each_with_object({}) { |s, h| h[s.reblog_of_id] = true }
end
def mutes_map(conversation_ids, account_id)
@ -442,13 +407,16 @@ class Status < ApplicationRecord
end
end
def status_stat
super || build_status_stat
end
private
def update_status_stat!(attrs)
return if marked_for_destruction? || destroyed?
record = status_stat || build_status_stat
record.update(attrs)
status_stat.update(attrs)
end
def store_uri
@ -504,7 +472,8 @@ class Status < ApplicationRecord
end
def update_statistics
return unless public_visibility? || unlisted_visibility?
return unless distributable?
ActivityTracker.increment('activity:statuses:local')
end
@ -513,7 +482,7 @@ class Status < ApplicationRecord
account&.increment_count!(:statuses_count)
reblog&.increment_count!(:reblogs_count) if reblog?
thread&.increment_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
thread&.increment_count!(:replies_count) if in_reply_to_id.present? && distributable?
end
def decrement_counter_caches
@ -521,7 +490,7 @@ class Status < ApplicationRecord
account&.decrement_count!(:statuses_count)
reblog&.decrement_count!(:reblogs_count) if reblog?
thread&.decrement_count!(:replies_count) if in_reply_to_id.present? && (public_visibility? || unlisted_visibility?)
thread&.decrement_count!(:replies_count) if in_reply_to_id.present? && distributable?
end
def unlink_from_conversations