Add emoji_reactions property to status api object
This commit is contained in:
parent
b88e3942cc
commit
dca26cc504
@ -65,6 +65,7 @@ class Status < ApplicationRecord
|
||||
belongs_to :quote, class_name: 'Status', inverse_of: :quoted, optional: true
|
||||
|
||||
has_many :favourites, inverse_of: :status, dependent: :destroy
|
||||
has_many :emoji_reactions, inverse_of: :status, dependent: :destroy
|
||||
has_many :bookmarks, inverse_of: :status, dependent: :destroy
|
||||
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, dependent: :destroy
|
||||
has_many :reblogged_by_accounts, through: :reblogs, class_name: 'Account', source: :account
|
||||
@ -323,6 +324,29 @@ class Status < ApplicationRecord
|
||||
update_status_stat!(key => [public_send(key) - 1, 0].max)
|
||||
end
|
||||
|
||||
def emoji_reactions_grouped_by_name(account = nil)
|
||||
(Oj.load(status_stat&.emoji_reactions || '', mode: :strict) || []).tap do |emoji_reactions|
|
||||
if account.present?
|
||||
emoji_reactions.each do |emoji_reaction|
|
||||
emoji_reaction['me'] = emoji_reaction['account_ids'].include?(account.id.to_s)
|
||||
emoji_reaction['count'] = emoji_reaction['account_ids'].size
|
||||
emoji_reaction['account_ids'] -= account.excluded_from_timeline_account_ids.map(&:to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def generate_emoji_reactions_grouped_by_name
|
||||
records = emoji_reactions.group(:name).order(Arel.sql('MIN(created_at) ASC')).select('name, min(custom_emoji_id) as custom_emoji_id, count(*) as count, array_agg(account_id::text order by created_at) as account_ids')
|
||||
Oj.dump(ActiveModelSerializers::SerializableResource.new(records, each_serializer: REST::EmojiReactionsGroupedByNameSerializer, scope: nil, scope_name: :current_user))
|
||||
end
|
||||
|
||||
def refresh_emoji_reactions_grouped_by_name!
|
||||
generate_emoji_reactions_grouped_by_name.tap do |emoji_reactions|
|
||||
update_status_stat!(emoji_reactions: emoji_reactions)
|
||||
end
|
||||
end
|
||||
|
||||
def trendable?
|
||||
if attributes['trendable'].nil?
|
||||
account.trendable?
|
||||
|
@ -9,6 +9,7 @@
|
||||
# replies_count :bigint(8) default(0), not null
|
||||
# reblogs_count :bigint(8) default(0), not null
|
||||
# favourites_count :bigint(8) default(0), not null
|
||||
# emoji_reactions :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
@ -27,4 +28,14 @@ class StatusStat < ApplicationRecord
|
||||
def favourites_count
|
||||
[attributes['favourites_count'], 0].max
|
||||
end
|
||||
|
||||
def emoji_reactions
|
||||
attributes['emoji_reactions'] || ''
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reset_parent_cache
|
||||
Rails.cache.delete("statuses/#{status_id}")
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# name: string,
|
||||
#count: number,
|
||||
#account_ids: Array<string>,
|
||||
#me: boolean,
|
||||
#url: string,
|
||||
#domain: string
|
||||
|
||||
class REST::EmojiReactionsGroupedByNameSerializer < ActiveModel::Serializer
|
||||
attributes :name, :count
|
||||
|
||||
attribute :me, if: :current_user?
|
||||
attribute :url, if: :custom_emoji?
|
||||
attribute :static_url, if: :custom_emoji?
|
||||
attribute :domain, if: :custom_emoji?
|
||||
attribute :account_ids, if: :has_account_ids?
|
||||
|
||||
def current_user?
|
||||
!current_user.nil?
|
||||
end
|
||||
|
||||
def custom_emoji?
|
||||
object.respond_to?(:custom_emoji)
|
||||
end
|
||||
|
||||
def has_account_ids?
|
||||
object.respond_to?(:account_ids)
|
||||
end
|
||||
end
|
||||
|
@ -6,7 +6,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||
attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id,
|
||||
:sensitive, :spoiler_text, :visibility, :language,
|
||||
:uri, :url, :replies_count, :reblogs_count,
|
||||
:favourites_count, :edited_at
|
||||
:favourites_count, :emoji_reactions, :edited_at
|
||||
|
||||
attribute :favourited, if: :current_user?
|
||||
attribute :reblogged, if: :current_user?
|
||||
@ -103,6 +103,10 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||
end
|
||||
end
|
||||
|
||||
def emoji_reactions
|
||||
object.emoji_reactions_grouped_by_name(current_user&.account)
|
||||
end
|
||||
|
||||
def reblogged
|
||||
if relationships
|
||||
relationships.reblogs_map[object.id] || false
|
||||
|
@ -0,0 +1,5 @@
|
||||
class AddEmojiReactionsToStatusStats < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :status_stats, :emoji_reactions, :string
|
||||
end
|
||||
end
|
@ -965,8 +965,14 @@ ActiveRecord::Schema[7.1].define(version: 2023_12_12_073317) do
|
||||
t.bigint "replies_count", default: 0, null: false
|
||||
t.bigint "reblogs_count", default: 0, null: false
|
||||
t.bigint "favourites_count", default: 0, null: false
|
||||
<<<<<<< HEAD
|
||||
t.datetime "created_at", precision: nil, null: false
|
||||
t.datetime "updated_at", precision: nil, null: false
|
||||
=======
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "emoji_reactions"
|
||||
>>>>>>> 092f9916b0 (Add emoji_reactions property to status api object)
|
||||
t.index ["status_id"], name: "index_status_stats_on_status_id", unique: true
|
||||
end
|
||||
|
||||
|
61
lib/mastodon/cache_cli.rb
Normal file
61
lib/mastodon/cache_cli.rb
Normal file
@ -0,0 +1,61 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../../config/boot'
|
||||
require_relative '../../config/environment'
|
||||
require_relative 'cli_helper'
|
||||
|
||||
module Mastodon
|
||||
class CacheCLI < Thor
|
||||
include CLIHelper
|
||||
|
||||
def self.exit_on_failure?
|
||||
true
|
||||
end
|
||||
|
||||
desc 'clear', 'Clear out the cache storage'
|
||||
def clear
|
||||
Rails.cache.clear
|
||||
say('OK', :green)
|
||||
end
|
||||
|
||||
option :concurrency, type: :numeric, default: 5, aliases: [:c]
|
||||
option :verbose, type: :boolean, aliases: [:v]
|
||||
desc 'recount TYPE', 'Update hard-cached counters'
|
||||
long_desc <<~LONG_DESC
|
||||
Update hard-cached counters of TYPE by counting referenced
|
||||
records from scratch. TYPE can be "accounts" or "statuses".
|
||||
|
||||
It may take a very long time to finish, depending on the
|
||||
size of the database.
|
||||
LONG_DESC
|
||||
def recount(type)
|
||||
case type
|
||||
when 'accounts'
|
||||
processed, = parallelize_with_progress(Account.local.includes(:account_stat)) do |account|
|
||||
account_stat = account.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.save if account_stat.changed?
|
||||
end
|
||||
when 'statuses'
|
||||
processed, = parallelize_with_progress(Status.includes(:status_stat)) do |status|
|
||||
status_stat = status.status_stat
|
||||
status_stat.replies_count = status.replies.where.not(visibility: :direct).count
|
||||
status_stat.reblogs_count = status.reblogs.count
|
||||
status_stat.favourites_count = status.favourites.count
|
||||
status_stat.emoji_reactions = status.generate_emoji_reactions_grouped_by_name
|
||||
|
||||
status_stat.save if status_stat.changed?
|
||||
end
|
||||
else
|
||||
say("Unknown type: #{type}", :red)
|
||||
exit(1)
|
||||
end
|
||||
|
||||
say
|
||||
say("OK, recounted #{processed} records", :green)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user