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
|
belongs_to :quote, class_name: 'Status', inverse_of: :quoted, optional: true
|
||||||
|
|
||||||
has_many :favourites, inverse_of: :status, dependent: :destroy
|
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 :bookmarks, inverse_of: :status, dependent: :destroy
|
||||||
has_many :reblogs, foreign_key: 'reblog_of_id', class_name: 'Status', inverse_of: :reblog, 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
|
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)
|
update_status_stat!(key => [public_send(key) - 1, 0].max)
|
||||||
end
|
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?
|
def trendable?
|
||||||
if attributes['trendable'].nil?
|
if attributes['trendable'].nil?
|
||||||
account.trendable?
|
account.trendable?
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
# replies_count :bigint(8) default(0), not null
|
# replies_count :bigint(8) default(0), not null
|
||||||
# reblogs_count :bigint(8) default(0), not null
|
# reblogs_count :bigint(8) default(0), not null
|
||||||
# favourites_count :bigint(8) default(0), not null
|
# favourites_count :bigint(8) default(0), not null
|
||||||
|
# emoji_reactions :string
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
@ -27,4 +28,14 @@ class StatusStat < ApplicationRecord
|
|||||||
def favourites_count
|
def favourites_count
|
||||||
[attributes['favourites_count'], 0].max
|
[attributes['favourites_count'], 0].max
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def emoji_reactions
|
||||||
|
attributes['emoji_reactions'] || ''
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def reset_parent_cache
|
||||||
|
Rails.cache.delete("statuses/#{status_id}")
|
||||||
|
end
|
||||||
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,
|
attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id,
|
||||||
:sensitive, :spoiler_text, :visibility, :language,
|
:sensitive, :spoiler_text, :visibility, :language,
|
||||||
:uri, :url, :replies_count, :reblogs_count,
|
:uri, :url, :replies_count, :reblogs_count,
|
||||||
:favourites_count, :edited_at
|
:favourites_count, :emoji_reactions, :edited_at
|
||||||
|
|
||||||
attribute :favourited, if: :current_user?
|
attribute :favourited, if: :current_user?
|
||||||
attribute :reblogged, if: :current_user?
|
attribute :reblogged, if: :current_user?
|
||||||
@ -103,6 +103,10 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def emoji_reactions
|
||||||
|
object.emoji_reactions_grouped_by_name(current_user&.account)
|
||||||
|
end
|
||||||
|
|
||||||
def reblogged
|
def reblogged
|
||||||
if relationships
|
if relationships
|
||||||
relationships.reblogs_map[object.id] || false
|
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 "replies_count", default: 0, null: false
|
||||||
t.bigint "reblogs_count", default: 0, null: false
|
t.bigint "reblogs_count", default: 0, null: false
|
||||||
t.bigint "favourites_count", default: 0, null: false
|
t.bigint "favourites_count", default: 0, null: false
|
||||||
|
<<<<<<< HEAD
|
||||||
t.datetime "created_at", precision: nil, null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_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
|
t.index ["status_id"], name: "index_status_stats_on_status_id", unique: true
|
||||||
end
|
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