Merge remote-tracking branch 'origin/master' into gs-master
Conflicts: .travis.yml Gemfile.lock README.md app/controllers/settings/follower_domains_controller.rb app/controllers/statuses_controller.rb app/javascript/mastodon/locales/ja.json app/lib/feed_manager.rb app/models/media_attachment.rb app/models/mute.rb app/models/status.rb app/services/mute_service.rb app/views/home/index.html.haml app/views/stream_entries/_simple_status.html.haml config/locales/ca.yml config/locales/en.yml config/locales/es.yml config/locales/fr.yml config/locales/nl.yml config/locales/pl.yml config/locales/pt-BR.yml config/themes.yml
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: accounts
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# username :string default(""), not null
|
||||
# domain :string
|
||||
# secret :string default(""), not null
|
||||
@@ -42,7 +42,7 @@
|
||||
# followers_url :string default(""), not null
|
||||
# protocol :integer default("ostatus"), not null
|
||||
# memorial :boolean default(FALSE), not null
|
||||
# moved_to_account_id :integer
|
||||
# moved_to_account_id :bigint(8)
|
||||
# featured_collection_url :string
|
||||
# fields :jsonb
|
||||
#
|
||||
@@ -120,6 +120,7 @@ class Account < ApplicationRecord
|
||||
scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) }
|
||||
scope :silenced, -> { where(silenced: true) }
|
||||
scope :suspended, -> { where(suspended: true) }
|
||||
scope :without_suspended, -> { where(suspended: false) }
|
||||
scope :recent, -> { reorder(id: :desc) }
|
||||
scope :alphabetic, -> { order(domain: :asc, username: :asc) }
|
||||
scope :by_domain_accounts, -> { group(:domain).select(:domain, 'COUNT(*) AS accounts_count').order('accounts_count desc') }
|
||||
@@ -275,6 +276,10 @@ class Account < ApplicationRecord
|
||||
@value = attr['value']
|
||||
@errors = {}
|
||||
end
|
||||
|
||||
def to_h
|
||||
{ name: @name, value: @value }
|
||||
end
|
||||
end
|
||||
|
||||
class << self
|
||||
@@ -393,7 +398,7 @@ class Account < ApplicationRecord
|
||||
end
|
||||
|
||||
def emojis
|
||||
CustomEmoji.from_text(note, domain)
|
||||
@emojis ||= CustomEmoji.from_text(note, domain)
|
||||
end
|
||||
|
||||
before_create :generate_keys
|
||||
@@ -408,9 +413,9 @@ class Account < ApplicationRecord
|
||||
end
|
||||
|
||||
def generate_keys
|
||||
return unless local?
|
||||
return unless local? && !Rails.env.test?
|
||||
|
||||
keypair = OpenSSL::PKey::RSA.new(Rails.env.test? ? 512 : 2048)
|
||||
keypair = OpenSSL::PKey::RSA.new(2048)
|
||||
self.private_key = keypair.to_pem
|
||||
self.public_key = keypair.public_key.to_pem
|
||||
end
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#
|
||||
# Table name: account_domain_blocks
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# domain :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer
|
||||
# account_id :bigint(8)
|
||||
#
|
||||
|
||||
class AccountDomainBlock < ApplicationRecord
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
#
|
||||
# Table name: account_moderation_notes
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# content :text not null
|
||||
# account_id :integer not null
|
||||
# target_account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
# target_account_id :bigint(8) not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#
|
||||
# Table name: admin_action_logs
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# account_id :integer
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8)
|
||||
# action :string default(""), not null
|
||||
# target_type :string
|
||||
# target_id :integer
|
||||
# target_id :bigint(8)
|
||||
# recorded_changes :text default(""), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#
|
||||
# Table name: backups
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# id :bigint(8) not null, primary key
|
||||
# user_id :bigint(8)
|
||||
# dump_file_name :string
|
||||
# dump_content_type :string
|
||||
# dump_file_size :integer
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#
|
||||
# Table name: blocks
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer not null
|
||||
# target_account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
# target_account_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class Block < ApplicationRecord
|
||||
|
||||
@@ -20,6 +20,10 @@ module AccountInteractions
|
||||
follow_mapping(Block.where(target_account_id: target_account_ids, account_id: account_id), :target_account_id)
|
||||
end
|
||||
|
||||
def blocked_by_map(target_account_ids, account_id)
|
||||
follow_mapping(Block.where(account_id: target_account_ids, target_account_id: account_id), :account_id)
|
||||
end
|
||||
|
||||
def muting_map(target_account_ids, account_id)
|
||||
Mute.where(target_account_id: target_account_ids, account_id: account_id).each_with_object({}) do |mute, mapping|
|
||||
mapping[mute.target_account_id] = {
|
||||
@@ -38,8 +42,12 @@ module AccountInteractions
|
||||
|
||||
def domain_blocking_map(target_account_ids, account_id)
|
||||
accounts_map = Account.where(id: target_account_ids).select('id, domain').map { |a| [a.id, a.domain] }.to_h
|
||||
blocked_domains = AccountDomainBlock.where(account_id: account_id, domain: accounts_map.values).pluck(:domain)
|
||||
accounts_map.map { |id, domain| [id, blocked_domains.include?(domain)] }.to_h
|
||||
blocked_domains = domain_blocking_map_by_domain(accounts_map.values.compact, account_id)
|
||||
accounts_map.map { |id, domain| [id, blocked_domains[domain]] }.to_h
|
||||
end
|
||||
|
||||
def domain_blocking_map_by_domain(target_domains, account_id)
|
||||
follow_mapping(AccountDomainBlock.where(account_id: account_id, domain: target_domains), :domain)
|
||||
end
|
||||
|
||||
private
|
||||
@@ -93,6 +101,7 @@ module AccountInteractions
|
||||
if mute.hide_notifications? != notifications
|
||||
mute.update!(hide_notifications: notifications)
|
||||
end
|
||||
mute
|
||||
end
|
||||
|
||||
def mute_conversation!(conversation)
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'mime/types'
|
||||
|
||||
module Attachmentable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
MAX_MATRIX_LIMIT = 16_777_216 # 4096x4096px or approx. 16MB
|
||||
|
||||
included do
|
||||
before_post_process :set_file_extensions
|
||||
before_post_process :check_image_dimensions
|
||||
end
|
||||
|
||||
private
|
||||
@@ -12,10 +17,31 @@ module Attachmentable
|
||||
def set_file_extensions
|
||||
self.class.attachment_definitions.each_key do |attachment_name|
|
||||
attachment = send(attachment_name)
|
||||
|
||||
next if attachment.blank?
|
||||
extension = Paperclip::Interpolations.content_type_extension(attachment, :original)
|
||||
basename = Paperclip::Interpolations.basename(attachment, :original)
|
||||
attachment.instance_write :file_name, [basename, extension].delete_if(&:blank?).join('.')
|
||||
|
||||
attachment.instance_write :file_name, [Paperclip::Interpolations.basename(attachment, :original), appropriate_extension(attachment)].delete_if(&:blank?).join('.')
|
||||
end
|
||||
end
|
||||
|
||||
def check_image_dimensions
|
||||
self.class.attachment_definitions.each_key do |attachment_name|
|
||||
attachment = send(attachment_name)
|
||||
|
||||
next if attachment.blank? || !attachment.content_type.match?(/image.*/) || attachment.queued_for_write[:original].blank?
|
||||
|
||||
width, height = FastImage.size(attachment.queued_for_write[:original].path)
|
||||
|
||||
raise Mastodon::DimensionsValidationError, "#{width}x#{height} images are not supported" if width.present? && height.present? && (width * height >= MAX_MATRIX_LIMIT)
|
||||
end
|
||||
end
|
||||
|
||||
def appropriate_extension(attachment)
|
||||
mime_type = MIME::Types[attachment.content_type]
|
||||
|
||||
extensions_for_mime_type = mime_type.empty? ? [] : mime_type.first.extensions
|
||||
original_extension = Paperclip::Interpolations.extension(attachment, :original)
|
||||
|
||||
extensions_for_mime_type.include?(original_extension) ? original_extension : extensions_for_mime_type.first
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,14 +3,19 @@
|
||||
module Cacheable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
module ClassMethods
|
||||
@cache_associated = []
|
||||
|
||||
def cache_associated(*associations)
|
||||
@cache_associated = associations
|
||||
end
|
||||
end
|
||||
|
||||
included do
|
||||
scope :with_includes, -> { includes(@cache_associated) }
|
||||
scope :cache_ids, -> { select(:id, :updated_at) }
|
||||
def with_includes
|
||||
includes(@cache_associated)
|
||||
end
|
||||
|
||||
def cache_ids
|
||||
select(:id, :updated_at)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -38,7 +38,7 @@ module Remotable
|
||||
|
||||
self[attribute_name] = url if has_attribute?(attribute_name)
|
||||
end
|
||||
rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError => e
|
||||
rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e
|
||||
Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}"
|
||||
nil
|
||||
end
|
||||
|
||||
@@ -7,8 +7,8 @@ module StatusThreadingConcern
|
||||
find_statuses_from_tree_path(ancestor_ids(limit), account)
|
||||
end
|
||||
|
||||
def descendants(account = nil)
|
||||
find_statuses_from_tree_path(descendant_ids, account)
|
||||
def descendants(limit, account = nil, max_child_id = nil, since_child_id = nil, depth = nil)
|
||||
find_statuses_from_tree_path(descendant_ids(limit, max_child_id, since_child_id, depth), account)
|
||||
end
|
||||
|
||||
private
|
||||
@@ -46,34 +46,46 @@ module StatusThreadingConcern
|
||||
SQL
|
||||
end
|
||||
|
||||
def descendant_ids
|
||||
descendant_statuses.pluck(:id)
|
||||
def descendant_ids(limit, max_child_id, since_child_id, depth)
|
||||
descendant_statuses(limit, max_child_id, since_child_id, depth).pluck(:id)
|
||||
end
|
||||
|
||||
def descendant_statuses
|
||||
Status.find_by_sql([<<-SQL.squish, id: id])
|
||||
def descendant_statuses(limit, max_child_id, since_child_id, depth)
|
||||
Status.find_by_sql([<<-SQL.squish, id: id, limit: limit, max_child_id: max_child_id, since_child_id: since_child_id, depth: depth])
|
||||
WITH RECURSIVE search_tree(id, path)
|
||||
AS (
|
||||
SELECT id, ARRAY[id]
|
||||
FROM statuses
|
||||
WHERE in_reply_to_id = :id
|
||||
WHERE in_reply_to_id = :id AND COALESCE(id < :max_child_id, TRUE) AND COALESCE(id > :since_child_id, TRUE)
|
||||
UNION ALL
|
||||
SELECT statuses.id, path || statuses.id
|
||||
FROM search_tree
|
||||
JOIN statuses ON statuses.in_reply_to_id = search_tree.id
|
||||
WHERE NOT statuses.id = ANY(path)
|
||||
WHERE COALESCE(array_length(path, 1) < :depth, TRUE) AND NOT statuses.id = ANY(path)
|
||||
)
|
||||
SELECT id
|
||||
FROM search_tree
|
||||
ORDER BY path
|
||||
LIMIT :limit
|
||||
SQL
|
||||
end
|
||||
|
||||
def find_statuses_from_tree_path(ids, account)
|
||||
statuses = statuses_with_accounts(ids).to_a
|
||||
statuses = statuses_with_accounts(ids).to_a
|
||||
account_ids = statuses.map(&:account_id).uniq
|
||||
domains = statuses.map(&:account_domain).compact.uniq
|
||||
|
||||
# FIXME: n+1 bonanza
|
||||
statuses.reject! { |status| filter_from_context?(status, account) }
|
||||
relations = if account.present?
|
||||
{
|
||||
blocking: Account.blocking_map(account_ids, account.id),
|
||||
blocked_by: Account.blocked_by_map(account_ids, account.id),
|
||||
muting: Account.muting_map(account_ids, account.id),
|
||||
following: Account.following_map(account_ids, account.id),
|
||||
domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, account.id),
|
||||
}
|
||||
end
|
||||
|
||||
statuses.reject! { |status| filter_from_context?(status, account, relations) }
|
||||
|
||||
# Order ancestors/descendants by tree path
|
||||
statuses.sort_by! { |status| ids.index(status.id) }
|
||||
@@ -83,7 +95,7 @@ module StatusThreadingConcern
|
||||
Status.where(id: ids).includes(:account)
|
||||
end
|
||||
|
||||
def filter_from_context?(status, account)
|
||||
StatusFilter.new(status, account).filtered?
|
||||
def filter_from_context?(status, account, relations)
|
||||
StatusFilter.new(status, account, relations).filtered?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: conversations
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# uri :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
#
|
||||
# Table name: conversation_mutes
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# conversation_id :integer not null
|
||||
# account_id :integer not null
|
||||
# id :bigint(8) not null, primary key
|
||||
# conversation_id :bigint(8) not null
|
||||
# account_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class ConversationMute < ApplicationRecord
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: custom_emojis
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# shortcode :string default(""), not null
|
||||
# domain :string
|
||||
# image_file_name :string
|
||||
@@ -40,6 +40,10 @@ class CustomEmoji < ApplicationRecord
|
||||
|
||||
remotable_attachment :image, LIMIT
|
||||
|
||||
include Attachmentable
|
||||
|
||||
after_commit :remove_entity_cache
|
||||
|
||||
def local?
|
||||
domain.nil?
|
||||
end
|
||||
@@ -56,11 +60,17 @@ class CustomEmoji < ApplicationRecord
|
||||
|
||||
return [] if shortcodes.empty?
|
||||
|
||||
where(shortcode: shortcodes, domain: domain, disabled: false)
|
||||
EntityCache.instance.emoji(shortcodes, domain)
|
||||
end
|
||||
|
||||
def search(shortcode)
|
||||
where('"custom_emojis"."shortcode" ILIKE ?', "%#{shortcode}%")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def remove_entity_cache
|
||||
Rails.cache.delete(EntityCache.instance.to_key(:emoji, shortcode, domain))
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: domain_blocks
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# domain :string default(""), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: email_domain_blocks
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# domain :string default(""), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#
|
||||
# Table name: favourites
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer not null
|
||||
# status_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
# status_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class Favourite < ApplicationRecord
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#
|
||||
# Table name: follows
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer not null
|
||||
# target_account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
# target_account_id :bigint(8) not null
|
||||
# show_reblogs :boolean default(TRUE), not null
|
||||
#
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#
|
||||
# Table name: follow_requests
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer not null
|
||||
# target_account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
# target_account_id :bigint(8) not null
|
||||
# show_reblogs :boolean default(TRUE), not null
|
||||
#
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: imports
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# type :integer not null
|
||||
# approved :boolean default(FALSE), not null
|
||||
# created_at :datetime not null
|
||||
@@ -12,7 +12,7 @@
|
||||
# data_content_type :string
|
||||
# data_file_size :integer
|
||||
# data_updated_at :datetime
|
||||
# account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class Import < ApplicationRecord
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#
|
||||
# Table name: invites
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer not null
|
||||
# id :bigint(8) not null, primary key
|
||||
# user_id :bigint(8) not null
|
||||
# code :string default(""), not null
|
||||
# expires_at :datetime
|
||||
# max_uses :integer
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#
|
||||
# Table name: lists
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# account_id :integer not null
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8) not null
|
||||
# title :string default(""), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
#
|
||||
# Table name: list_accounts
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# list_id :integer not null
|
||||
# account_id :integer not null
|
||||
# follow_id :integer not null
|
||||
# id :bigint(8) not null, primary key
|
||||
# list_id :bigint(8) not null
|
||||
# account_id :bigint(8) not null
|
||||
# follow_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class ListAccount < ApplicationRecord
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
#
|
||||
# Table name: media_attachments
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# status_id :integer
|
||||
# id :bigint(8) not null, primary key
|
||||
# status_id :bigint(8)
|
||||
# file_file_name :string
|
||||
# file_content_type :string
|
||||
# file_file_size :integer
|
||||
@@ -15,12 +15,10 @@
|
||||
# shortcode :string
|
||||
# type :integer default("image"), not null
|
||||
# file_meta :json
|
||||
# account_id :integer
|
||||
# account_id :bigint(8)
|
||||
# description :text
|
||||
#
|
||||
|
||||
require 'mime/types'
|
||||
|
||||
class MediaAttachment < ApplicationRecord
|
||||
self.inheritance_column = nil
|
||||
|
||||
@@ -90,6 +88,8 @@ class MediaAttachment < ApplicationRecord
|
||||
validates_attachment_size :file, less_than: LIMIT
|
||||
remotable_attachment :file, LIMIT
|
||||
|
||||
include Attachmentable
|
||||
|
||||
validates :account, presence: true
|
||||
validates :description, length: { maximum: 420 }, if: :local?
|
||||
|
||||
@@ -247,13 +247,4 @@ class MediaAttachment < ApplicationRecord
|
||||
bitrate: movie.bitrate,
|
||||
}
|
||||
end
|
||||
|
||||
def appropriate_extension
|
||||
mime_type = MIME::Types[file.content_type]
|
||||
|
||||
extensions_for_mime_type = mime_type.empty? ? [] : mime_type.first.extensions
|
||||
original_extension = Paperclip::Interpolations.extension(file, :original)
|
||||
|
||||
extensions_for_mime_type.include?(original_extension) ? original_extension : extensions_for_mime_type.first
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#
|
||||
# Table name: mentions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# status_id :integer
|
||||
# id :bigint(8) not null, primary key
|
||||
# status_id :bigint(8)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer
|
||||
# account_id :bigint(8)
|
||||
#
|
||||
|
||||
class Mention < ApplicationRecord
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
#
|
||||
# Table name: mutes
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# hide_notifications :boolean default(TRUE), not null
|
||||
# account_id :integer not null
|
||||
# target_account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
# target_account_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class Mute < ApplicationRecord
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
#
|
||||
# Table name: notifications
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# activity_id :integer not null
|
||||
# id :bigint(8) not null, primary key
|
||||
# activity_id :bigint(8) not null
|
||||
# activity_type :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer not null
|
||||
# from_account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
# from_account_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class Notification < ApplicationRecord
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: preview_cards
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# url :string default(""), not null
|
||||
# title :string default(""), not null
|
||||
# description :string default(""), not null
|
||||
@@ -34,7 +34,7 @@ class PreviewCard < ApplicationRecord
|
||||
|
||||
has_and_belongs_to_many :statuses
|
||||
|
||||
has_attached_file :image, styles: { original: { geometry: '400x400>', file_geometry_parser: FastGeometryParser } }, convert_options: { all: '-quality 80 -strip' }
|
||||
has_attached_file :image, styles: ->(f) { image_styles(f) }, convert_options: { all: '-quality 80 -strip' }
|
||||
|
||||
include Attachmentable
|
||||
|
||||
@@ -52,6 +52,23 @@ class PreviewCard < ApplicationRecord
|
||||
save!
|
||||
end
|
||||
|
||||
class << self
|
||||
private
|
||||
|
||||
def image_styles(f)
|
||||
styles = {
|
||||
original: {
|
||||
geometry: '400x400>',
|
||||
file_geometry_parser: FastGeometryParser,
|
||||
convert_options: '-coalesce -strip',
|
||||
},
|
||||
}
|
||||
|
||||
styles[:original][:format] = 'jpg' if f.instance.image_content_type == 'image/gif'
|
||||
styles
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def extract_dimensions
|
||||
|
||||
@@ -3,16 +3,16 @@
|
||||
#
|
||||
# Table name: reports
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# status_ids :integer default([]), not null, is an Array
|
||||
# id :bigint(8) not null, primary key
|
||||
# status_ids :bigint(8) default([]), not null, is an Array
|
||||
# comment :text default(""), not null
|
||||
# action_taken :boolean default(FALSE), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# account_id :integer not null
|
||||
# action_taken_by_account_id :integer
|
||||
# target_account_id :integer not null
|
||||
# assigned_account_id :integer
|
||||
# account_id :bigint(8) not null
|
||||
# action_taken_by_account_id :bigint(8)
|
||||
# target_account_id :bigint(8) not null
|
||||
# assigned_account_id :bigint(8)
|
||||
#
|
||||
|
||||
class Report < ApplicationRecord
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
#
|
||||
# Table name: report_notes
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# content :text not null
|
||||
# report_id :integer not null
|
||||
# account_id :integer not null
|
||||
# report_id :bigint(8) not null
|
||||
# account_id :bigint(8) not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
#
|
||||
# Table name: session_activations
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# session_id :string not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# user_agent :string default(""), not null
|
||||
# ip :inet
|
||||
# access_token_id :integer
|
||||
# user_id :integer not null
|
||||
# web_push_subscription_id :integer
|
||||
# access_token_id :bigint(8)
|
||||
# user_id :bigint(8) not null
|
||||
# web_push_subscription_id :bigint(8)
|
||||
#
|
||||
|
||||
class SessionActivation < ApplicationRecord
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
#
|
||||
# Table name: settings
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# var :string not null
|
||||
# value :text
|
||||
# thing_type :string
|
||||
# created_at :datetime
|
||||
# updated_at :datetime
|
||||
# thing_id :integer
|
||||
# thing_id :bigint(8)
|
||||
#
|
||||
|
||||
class Setting < RailsSettings::Base
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: site_uploads
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# var :string default(""), not null
|
||||
# file_file_name :string
|
||||
# file_content_type :string
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
#
|
||||
# Table name: statuses
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# uri :string
|
||||
# text :text default(""), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# in_reply_to_id :integer
|
||||
# reblog_of_id :integer
|
||||
# in_reply_to_id :bigint(8)
|
||||
# reblog_of_id :bigint(8)
|
||||
# url :string
|
||||
# sensitive :boolean default(FALSE), not null
|
||||
# visibility :integer default("public"), not null
|
||||
@@ -18,11 +18,11 @@
|
||||
# favourites_count :integer default(0), not null
|
||||
# reblogs_count :integer default(0), not null
|
||||
# language :string
|
||||
# conversation_id :integer
|
||||
# conversation_id :bigint(8)
|
||||
# local :boolean
|
||||
# account_id :integer not null
|
||||
# application_id :integer
|
||||
# in_reply_to_account_id :integer
|
||||
# account_id :bigint(8) not null
|
||||
# application_id :bigint(8)
|
||||
# in_reply_to_account_id :bigint(8)
|
||||
# local_only :boolean
|
||||
# full_status_text :text default(""), not null
|
||||
#
|
||||
@@ -62,6 +62,7 @@ class Status < ApplicationRecord
|
||||
validates :uri, uniqueness: true, presence: true, unless: :local?
|
||||
validates :text, presence: true, unless: -> { with_media? || reblog? }
|
||||
validates_with StatusLengthValidator
|
||||
validates_with DisallowedHashtagsValidator
|
||||
validates :reblog, uniqueness: { scope: :account }, if: :reblog?
|
||||
|
||||
default_scope { recent }
|
||||
@@ -164,7 +165,7 @@ class Status < ApplicationRecord
|
||||
end
|
||||
|
||||
def emojis
|
||||
CustomEmoji.from_text([spoiler_text, text].join(' '), account.domain)
|
||||
@emojis ||= CustomEmoji.from_text([spoiler_text, text].join(' '), account.domain)
|
||||
end
|
||||
|
||||
after_create_commit :store_uri, if: :local?
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
#
|
||||
# Table name: status_pins
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# account_id :integer not null
|
||||
# status_id :integer not null
|
||||
# id :bigint(8) not null, primary key
|
||||
# account_id :bigint(8) not null
|
||||
# status_id :bigint(8) not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
#
|
||||
# Table name: stream_entries
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# activity_id :integer
|
||||
# id :bigint(8) not null, primary key
|
||||
# activity_id :bigint(8)
|
||||
# activity_type :string
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# hidden :boolean default(FALSE), not null
|
||||
# account_id :integer
|
||||
# account_id :bigint(8)
|
||||
#
|
||||
|
||||
class StreamEntry < ApplicationRecord
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: subscriptions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# callback_url :string default(""), not null
|
||||
# secret :string
|
||||
# expires_at :datetime
|
||||
@@ -12,7 +12,7 @@
|
||||
# updated_at :datetime not null
|
||||
# last_successful_delivery_at :datetime
|
||||
# domain :string
|
||||
# account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class Subscription < ApplicationRecord
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: tags
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# name :string default(""), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: users
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# email :string default(""), not null
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
@@ -30,10 +30,10 @@
|
||||
# last_emailed_at :datetime
|
||||
# otp_backup_codes :string is an Array
|
||||
# filtered_languages :string default([]), not null, is an Array
|
||||
# account_id :integer not null
|
||||
# account_id :bigint(8) not null
|
||||
# disabled :boolean default(FALSE), not null
|
||||
# moderator :boolean default(FALSE), not null
|
||||
# invite_id :integer
|
||||
# invite_id :bigint(8)
|
||||
# remember_token :string
|
||||
#
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Table name: web_push_subscriptions
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# endpoint :string not null
|
||||
# key_p256dh :string not null
|
||||
# key_auth :string not null
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
#
|
||||
# Table name: web_settings
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# id :bigint(8) not null, primary key
|
||||
# data :json
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# user_id :integer not null
|
||||
# user_id :bigint(8) not null
|
||||
#
|
||||
|
||||
class Web::Setting < ApplicationRecord
|
||||
|
||||
Reference in New Issue
Block a user