diff options
-rw-r--r-- | app/controllers/admin/custom_emojis_controller.rb | 78 | ||||
-rw-r--r-- | app/controllers/custom_emojis_controller.rb | 97 | ||||
-rw-r--r-- | app/models/concerns/account_associations.rb | 3 | ||||
-rw-r--r-- | app/models/custom_emoji.rb | 8 | ||||
-rw-r--r-- | app/models/custom_emoji_filter.rb | 9 | ||||
-rw-r--r-- | app/models/form/custom_emoji_batch.rb | 39 | ||||
-rw-r--r-- | app/policies/custom_emoji_policy.rb | 36 | ||||
-rw-r--r-- | app/views/custom_emojis/_custom_emoji.html.haml (renamed from app/views/admin/custom_emojis/_custom_emoji.html.haml) | 1 | ||||
-rw-r--r-- | app/views/custom_emojis/index.html.haml (renamed from app/views/admin/custom_emojis/index.html.haml) | 41 | ||||
-rw-r--r-- | app/views/custom_emojis/new.html.haml (renamed from app/views/admin/custom_emojis/new.html.haml) | 2 | ||||
-rw-r--r-- | config/locales/en-MP.yml | 9 | ||||
-rw-r--r-- | config/navigation.rb | 2 | ||||
-rw-r--r-- | config/routes.rb | 12 | ||||
-rw-r--r-- | db/migrate/20200919234917_add_account_to_custom_emoji.rb | 7 | ||||
-rw-r--r-- | db/migrate/20200920084007_backfill_custom_emoji_ownership.rb | 12 | ||||
-rw-r--r-- | db/schema.rb | 5 |
16 files changed, 247 insertions, 114 deletions
diff --git a/app/controllers/admin/custom_emojis_controller.rb b/app/controllers/admin/custom_emojis_controller.rb deleted file mode 100644 index 71efb543e..000000000 --- a/app/controllers/admin/custom_emojis_controller.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -module Admin - class CustomEmojisController < BaseController - def index - authorize :custom_emoji, :index? - - @custom_emojis = filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page]) - @form = Form::CustomEmojiBatch.new - end - - def new - authorize :custom_emoji, :create? - - @custom_emoji = CustomEmoji.new - end - - def create - authorize :custom_emoji, :create? - - @custom_emoji = CustomEmoji.new(resource_params) - - if @custom_emoji.save - log_action :create, @custom_emoji - redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.created_msg') - else - render :new - end - end - - def batch - @form = Form::CustomEmojiBatch.new(form_custom_emoji_batch_params.merge(current_account: current_account, action: action_from_button)) - @form.save - rescue ActionController::ParameterMissing - flash[:alert] = I18n.t('admin.accounts.no_account_selected') - rescue Mastodon::NotPermittedError - flash[:alert] = I18n.t('admin.custom_emojis.not_permitted') - ensure - redirect_to admin_custom_emojis_path(filter_params) - end - - private - - def resource_params - params.require(:custom_emoji).permit(:shortcode, :image, :visible_in_picker) - end - - def filtered_custom_emojis - CustomEmojiFilter.new(filter_params).results - end - - def filter_params - params.slice(:page, *CustomEmojiFilter::KEYS).permit(:page, *CustomEmojiFilter::KEYS) - end - - def action_from_button - if params[:update] - 'update' - elsif params[:list] - 'list' - elsif params[:unlist] - 'unlist' - elsif params[:enable] - 'enable' - elsif params[:disable] - 'disable' - elsif params[:copy] - 'copy' - elsif params[:delete] - 'delete' - end - end - - def form_custom_emoji_batch_params - params.require(:form_custom_emoji_batch).permit(:action, :category_id, :category_name, custom_emoji_ids: []) - end - end -end diff --git a/app/controllers/custom_emojis_controller.rb b/app/controllers/custom_emojis_controller.rb new file mode 100644 index 000000000..0ef8d0a50 --- /dev/null +++ b/app/controllers/custom_emojis_controller.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +class CustomEmojisController < ApplicationController + include Authorization + include AccountableConcern + + layout 'admin' + + before_action :authenticate_user! + before_action :set_pack + before_action :set_body_classes + + def index + authorize :custom_emoji, :index? + + @custom_emojis = filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page]) + @form = Form::CustomEmojiBatch.new + end + + def new + authorize :custom_emoji, :create? + + @custom_emoji = CustomEmoji.new(account: current_account) + end + + def create + authorize :custom_emoji, :create? + + @custom_emoji = CustomEmoji.new(resource_params.merge(account: current_account)) + + if @custom_emoji.save + log_action :create, @custom_emoji + redirect_to custom_emojis_path, notice: I18n.t('admin.custom_emojis.created_msg') + else + render :new + end + end + + def batch + @form = Form::CustomEmojiBatch.new(form_custom_emoji_batch_params.merge(current_account: current_account, action: action_from_button)) + @form.save + rescue ActionController::ParameterMissing + flash[:alert] = I18n.t('admin.accounts.no_account_selected') + rescue Mastodon::NotPermittedError + flash[:alert] = I18n.t('admin.custom_emojis.not_permitted') + ensure + redirect_to custom_emojis_path(filter_params) + end + + private + + def resource_params + params.require(:custom_emoji).permit(:shortcode, :image, :visible_in_picker) + end + + def filtered_custom_emojis + CustomEmojiFilter.new(filter_params, current_account).results + end + + def filter_params + params.slice(:page, *CustomEmojiFilter::KEYS).permit(:page, *CustomEmojiFilter::KEYS) + end + + def action_from_button + if params[:update] + 'update' + elsif params[:list] + 'list' + elsif params[:unlist] + 'unlist' + elsif params[:enable] + 'enable' + elsif params[:disable] + 'disable' + elsif params[:copy] + 'copy' + elsif params[:delete] + 'delete' + elsif params[:claim] + 'claim' + elsif params[:unclaim] + 'unclaim' + end + end + + def form_custom_emoji_batch_params + params.require(:form_custom_emoji_batch).permit(:action, :category_id, :category_name, custom_emoji_ids: []) + end + + def set_pack + use_pack 'settings' + end + + def set_body_classes + @body_classes = 'admin' + end +end diff --git a/app/models/concerns/account_associations.rb b/app/models/concerns/account_associations.rb index a8b024346..71947fc22 100644 --- a/app/models/concerns/account_associations.rb +++ b/app/models/concerns/account_associations.rb @@ -78,5 +78,8 @@ module AccountAssociations # Collection items has_many :collection_items, inverse_of: :account, dependent: :destroy + + # Custom emojis + has_many :custom_emojis, inverse_of: :account, dependent: :nullify end end diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb index 7cb03b819..c819288ba 100644 --- a/app/models/custom_emoji.rb +++ b/app/models/custom_emoji.rb @@ -18,6 +18,7 @@ # visible_in_picker :boolean default(TRUE), not null # category_id :bigint(8) # image_storage_schema_version :integer +# account_id :bigint(8) # class CustomEmoji < ApplicationRecord @@ -32,6 +33,7 @@ class CustomEmoji < ApplicationRecord IMAGE_MIME_TYPES = %w(image/png image/gif).freeze belongs_to :category, class_name: 'CustomEmojiCategory', optional: true + belongs_to :account, inverse_of: :custom_emojis, optional: true has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce -strip' } } @@ -46,6 +48,7 @@ class CustomEmoji < ApplicationRecord scope :alphabetic, -> { order(domain: :asc, shortcode: :asc) } scope :by_domain_and_subdomains, ->(domain) { where(domain: domain).or(where(arel_table[:domain].matches('%.' + domain))) } scope :listed, -> { local.where(disabled: false).where(visible_in_picker: true) } + scope :owned_by, ->(account) { where(account: account) } remotable_attachment :image, LIMIT @@ -61,8 +64,11 @@ class CustomEmoji < ApplicationRecord :emoji end - def copy! + def copy!(current_account = nil) copy = self.class.find_or_initialize_by(domain: nil, shortcode: shortcode) + return copy if copy.account_id.present? && copy.account_id != current_account&.id + + copy.account = current_account copy.image = image copy.tap(&:save!) end diff --git a/app/models/custom_emoji_filter.rb b/app/models/custom_emoji_filter.rb index 414e1fcdd..58c888518 100644 --- a/app/models/custom_emoji_filter.rb +++ b/app/models/custom_emoji_filter.rb @@ -5,13 +5,16 @@ class CustomEmojiFilter local remote by_domain + claimed + unclaimed shortcode ).freeze attr_reader :params - def initialize(params) + def initialize(params, account) @params = params + @account = account end def results @@ -36,6 +39,10 @@ class CustomEmojiFilter CustomEmoji.remote when 'by_domain' CustomEmoji.where(domain: value.strip.downcase) + when 'claimed' + CustomEmoji.where(account: @account) + when 'unclaimed' + CustomEmoji.where(account: nil) when 'shortcode' CustomEmoji.search(value.strip) else diff --git a/app/models/form/custom_emoji_batch.rb b/app/models/form/custom_emoji_batch.rb index f4fa84c10..54a15dc18 100644 --- a/app/models/form/custom_emoji_batch.rb +++ b/app/models/form/custom_emoji_batch.rb @@ -24,13 +24,17 @@ class Form::CustomEmojiBatch copy! when 'delete' delete! + when 'claim' + claim! + when 'unclaim' + unclaim! end end private - def custom_emojis - @custom_emojis ||= CustomEmoji.where(id: custom_emoji_ids) + def custom_emojis(include_all = false) + @custom_emojis ||= (include_all || current_account&.user&.staff? ? CustomEmoji.where(id: custom_emoji_ids) : CustomEmoji.local.where(id: custom_emoji_ids, account: current_account)) end def update! @@ -40,10 +44,12 @@ class Form::CustomEmojiBatch if category_id.present? CustomEmojiCategory.find(category_id) elsif category_name.present? - CustomEmojiCategory.find_or_create_by!(name: category_name) + CustomEmojiCategory.find_or_create_by!(name: current_account&.user&.staff? ? category_name.strip : "(@#{current_account.username}) #{category_name}".rstrip) end end + return if category.name.start_with?('(@') && !category.name.start_with?("(@#{current_account.username}) ") + custom_emojis.each do |custom_emoji| custom_emoji.update(category_id: category&.id) log_action :update, custom_emoji @@ -87,10 +93,10 @@ class Form::CustomEmojiBatch end def copy! - custom_emojis.each { |custom_emoji| authorize(custom_emoji, :copy?) } + custom_emojis(true).each { |custom_emoji| authorize(custom_emoji, :copy?) } custom_emojis.each do |custom_emoji| - copied_custom_emoji = custom_emoji.copy! + copied_custom_emoji = custom_emoji.copy!(current_account) log_action :create, copied_custom_emoji end end @@ -103,4 +109,27 @@ class Form::CustomEmojiBatch log_action :destroy, custom_emoji end end + + def claim! + custom_emojis(true).each { |custom_emoji| authorize(custom_emoji, :claim?) } + + custom_emojis.each do |custom_emoji| + if custom_emoji.local? + custom_emoji.update(account: current_account) + log_action :update, custom_emoji + else + copied_custom_emoji = custom_emoji.copy!(current_account) + log_action :create, copied_custom_emoji + end + end + end + + def unclaim! + custom_emojis.each { |custom_emoji| authorize(custom_emoji, :unclaim?) } + + custom_emojis.each do |custom_emoji| + custom_emoji.update(account: nil) + log_action :update, custom_emoji + end + end end diff --git a/app/policies/custom_emoji_policy.rb b/app/policies/custom_emoji_policy.rb index a8c3cbc73..7e585a3d6 100644 --- a/app/policies/custom_emoji_policy.rb +++ b/app/policies/custom_emoji_policy.rb @@ -2,30 +2,52 @@ class CustomEmojiPolicy < ApplicationPolicy def index? - staff? + user_signed_in? end def create? - admin? + user_signed_in? end def update? - admin? + user_signed_in? && owned? end def copy? - admin? + staff? || (user_signed_in? && new_or_owned?) end def enable? - staff? + user_signed_in? && owned? end def disable? - staff? + user_signed_in? && owned? end def destroy? - admin? + user_signed_in? && owned? + end + + def claim? + staff? || claimable? + end + + def unclaim? + user_signed_in? && owned? + end + + private + + def owned? + staff? || (current_account.present? && record.account_id == current_account.id) + end + + def new_or_owned? + !CustomEmoji.where(domain: nil, shortcode: record.shortcode).where('account_id IS NULL OR account_id != ?', current_account.id).exists? + end + + def claimable? + record.local? ? record.account_id.blank? || record.account_id == current_account.id : new_or_owned? end end diff --git a/app/views/admin/custom_emojis/_custom_emoji.html.haml b/app/views/custom_emojis/_custom_emoji.html.haml index 526c844e9..e124373c6 100644 --- a/app/views/admin/custom_emojis/_custom_emoji.html.haml +++ b/app/views/custom_emojis/_custom_emoji.html.haml @@ -7,6 +7,7 @@ .batch-table__row__content__text %samp= ":#{custom_emoji.shortcode}:" + %p.hint.muted-hint{ title: t('admin.custom_emojis.owner') }= custom_emoji.account_id.present? ? "@#{custom_emoji.account.username}" : t('admin.custom_emojis.unclaimed') if custom_emoji.local? - if custom_emoji.local? %span.account-role.bot= custom_emoji.category&.name || t('admin.custom_emojis.uncategorized') diff --git a/app/views/admin/custom_emojis/index.html.haml b/app/views/custom_emojis/index.html.haml index b6cf7ba64..f81d91d53 100644 --- a/app/views/admin/custom_emojis/index.html.haml +++ b/app/views/custom_emojis/index.html.haml @@ -3,7 +3,9 @@ - if can?(:create, :custom_emoji) - content_for :heading_actions do - = link_to t('admin.custom_emojis.upload'), new_admin_custom_emoji_path, class: 'button' + = link_to t('admin.custom_emojis.upload'), new_custom_emoji_path, class: 'button' + +%p= t('admin.custom_emojis.ownership_warning') .filters .filter-subset @@ -11,17 +13,27 @@ %ul %li= filter_link_to t('admin.accounts.location.all'), local: nil, remote: nil %li - - if selected? local: '1', remote: nil - = filter_link_to t('admin.accounts.location.local'), {local: nil, remote: nil}, {local: '1', remote: nil} + - if selected? local: '1', remote: nil, claimed: nil, unclaimed: nil + = filter_link_to t('admin.accounts.location.local'), {local: nil, remote: nil, claimed: nil, unclaimed: nil}, {local: '1', remote: nil, claimed: nil, unclaimed: nil} + - else + = filter_link_to t('admin.accounts.location.local'), local: '1', remote: nil, claimed: nil, unclaimed: nil + %li + - if selected? remote: '1', local: nil, claimed: nil, unclaimed: nil + = filter_link_to t('admin.accounts.location.remote'), {remote: nil, local: nil, claimed: nil, unclaimed: nil}, {remote: '1', local: nil, claimed: nil, unclaimed: nil} - else - = filter_link_to t('admin.accounts.location.local'), local: '1', remote: nil + = filter_link_to t('admin.accounts.location.remote'), remote: '1', local: nil, claimed: nil, unclained: nil %li - - if selected? remote: '1', local: nil - = filter_link_to t('admin.accounts.location.remote'), {remote: nil, local: nil}, {remote: '1', local: nil} + - if selected? local: '1', remote: nil, claimed: '1', unclaimed: nil + = filter_link_to t('admin.accounts.location.claimed'), {local: '1', remote: nil, claimed: nil, unclaimed: nil}, {local: '1', remote: nil, claimed: '1', unclaimed: nil} - else - = filter_link_to t('admin.accounts.location.remote'), remote: '1', local: nil + = filter_link_to t('admin.accounts.location.claimed'), local: '1', remote: nil, claimed: '1', unclaimed: nil + %li + - if selected? local: '1', remote: nil, claimed: nil, unclaimed: '1' + = filter_link_to t('admin.accounts.location.unclaimed'), {local: '1', remote: nil, claimed: nil, unclaimed: nil}, {local: '1', remote: nil, claimed: nil, unclaimed: '1'} + - else + = filter_link_to t('admin.accounts.location.unclaimed'), local: '1', remote: nil, claimed: nil, unclaimed: '1' -= form_tag admin_custom_emojis_url, method: 'GET', class: 'simple_form' do += form_tag custom_emojis_url, method: 'GET', class: 'simple_form' do .fields-group - CustomEmojiFilter::KEYS.each do |key| = hidden_field_tag key, params[key] if params[key].present? @@ -32,9 +44,9 @@ .actions %button.button= t('admin.accounts.search') - = link_to t('admin.accounts.reset'), admin_custom_emojis_path, class: 'button negative' + = link_to t('admin.accounts.reset'), custom_emojis_path, class: 'button negative' -= form_for(@form, url: batch_admin_custom_emojis_path) do |f| += form_for(@form, url: batch_custom_emojis_path) do |f| = hidden_field_tag :page, params[:page] || 1 - CustomEmojiFilter::KEYS.each do |key| @@ -45,6 +57,10 @@ %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions + = f.button safe_join([fa_icon('lock'), t('admin.custom_emojis.claim')]), name: :claim, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + = f.button safe_join([fa_icon('unlock'), t('admin.custom_emojis.unclaim')]), name: :unclaim, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + - if params[:local] == '1' = f.button safe_join([fa_icon('save'), t('generic.save_changes')]), name: :update, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } @@ -56,10 +72,9 @@ = f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.disable')]), name: :disable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - - if can?(:destroy, :custom_emoji) - = f.button safe_join([fa_icon('times'), t('admin.custom_emojis.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = f.button safe_join([fa_icon('times'), t('admin.custom_emojis.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - - if can?(:copy, :custom_emoji) && params[:local] != '1' + - if params[:local] != '1' = f.button safe_join([fa_icon('copy'), t('admin.custom_emojis.copy')]), name: :copy, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - if params[:local] == '1' diff --git a/app/views/admin/custom_emojis/new.html.haml b/app/views/custom_emojis/new.html.haml index e15a07cb8..fe9d8fc64 100644 --- a/app/views/admin/custom_emojis/new.html.haml +++ b/app/views/custom_emojis/new.html.haml @@ -1,7 +1,7 @@ - content_for :page_title do = t('.title') -= simple_form_for @custom_emoji, url: admin_custom_emojis_path do |f| += simple_form_for @custom_emoji, url: custom_emojis_path do |f| = render 'shared/error_messages', object: @custom_emoji .fields-group diff --git a/config/locales/en-MP.yml b/config/locales/en-MP.yml index d964e5c03..6c4d37c9f 100644 --- a/config/locales/en-MP.yml +++ b/config/locales/en-MP.yml @@ -14,6 +14,9 @@ en-MP: silenced: "Posts from these servers will be hidden in public timelines and no notifications will be generated from their users' interactions, unless you are following them or vise-versa. These are typically set for curation purposes rather than " accounts: endorsements_hint: You can endorse creatures you follow from the web interface, and they will show up here. + location: + claimed: Claimed + unclaimed: Unclaimed people_followed_by: Creatures whom %{name} follows people_who_follow: Creatures who follow %{name} pin_errors: @@ -34,6 +37,12 @@ en-MP: actions: update_status: "%{name} updated roar by %{target}" deleted_status: "(deleted roar)" + custom_emojis: + claim: Claim + owner: Contributor + ownership_warning: "NOTE: You can only make changes to custom emoji that you upload or copy unless you are a moderator." + unclaim: Unclaim + unclaimed: (unclaimed) dashboard: pending_users: creatures waiting for review feature_hcaptcha: hCaptcha diff --git a/config/navigation.rb b/config/navigation.rb index 7f292af3f..364747adb 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -38,6 +38,7 @@ SimpleNavigation::Configuration.run do |navigation| s.item :export, safe_join([fa_icon('cloud-download fw'), t('settings.export')]), settings_export_url end + n.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), custom_emojis_url, highlights_on: %r{/custom_emojis} n.item :invites, safe_join([fa_icon('user-plus fw'), t('invites.title')]), invites_path, if: proc { Setting.min_invite_role == 'user' && current_user.functional? } n.item :development, safe_join([fa_icon('code fw'), t('settings.development')]), settings_applications_url, if: -> { current_user.functional? } @@ -55,7 +56,6 @@ SimpleNavigation::Configuration.run do |navigation| s.item :dashboard, safe_join([fa_icon('tachometer fw'), t('admin.dashboard.title')]), admin_dashboard_url s.item :settings, safe_join([fa_icon('cogs fw'), t('admin.settings.title')]), edit_admin_settings_url, if: -> { current_user.admin? }, highlights_on: %r{/admin/settings} s.item :announcements, safe_join([fa_icon('bullhorn fw'), t('admin.announcements.title')]), admin_announcements_path, highlights_on: %r{/admin/announcements} - s.item :custom_emojis, safe_join([fa_icon('smile-o fw'), t('admin.custom_emojis.title')]), admin_custom_emojis_url, highlights_on: %r{/admin/custom_emojis} s.item :relays, safe_join([fa_icon('exchange fw'), t('admin.relays.title')]), admin_relays_url, if: -> { current_user.admin? && !whitelist_mode? }, highlights_on: %r{/admin/relays} s.item :sidekiq, safe_join([fa_icon('diamond fw'), 'Sidekiq']), sidekiq_url, link_html: { target: 'sidekiq' }, if: -> { current_user.admin? } s.item :pghero, safe_join([fa_icon('database fw'), 'PgHero']), pghero_url, link_html: { target: 'pghero' }, if: -> { current_user.admin? } diff --git a/config/routes.rb b/config/routes.rb index 33343625c..4e36fe074 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -188,6 +188,12 @@ Rails.application.routes.draw do resources :filters, except: [:show] resource :relationships, only: [:show, :update] + resources :custom_emojis, only: [:index, :new, :create] do + collection do + post :batch + end + end + get '/public', to: 'public_timelines#show', as: :public_timeline get '/media_proxy/:id/(*any)', to: 'media_proxy#show', as: :media_proxy @@ -287,12 +293,6 @@ Rails.application.routes.draw do resource :two_factor_authentication, only: [:destroy] end - resources :custom_emojis, only: [:index, :new, :create] do - collection do - post :batch - end - end - resources :account_moderation_notes, only: [:create, :destroy] resources :tags, only: [:index, :show, :update] do diff --git a/db/migrate/20200919234917_add_account_to_custom_emoji.rb b/db/migrate/20200919234917_add_account_to_custom_emoji.rb new file mode 100644 index 000000000..b4466ee30 --- /dev/null +++ b/db/migrate/20200919234917_add_account_to_custom_emoji.rb @@ -0,0 +1,7 @@ +class AddAccountToCustomEmoji < ActiveRecord::Migration[5.2] + def change + safety_assured do + add_reference :custom_emojis, :account, foreign_key: { on_delete: :nullify }, index: true + end + end +end diff --git a/db/migrate/20200920084007_backfill_custom_emoji_ownership.rb b/db/migrate/20200920084007_backfill_custom_emoji_ownership.rb new file mode 100644 index 000000000..1542bdb5e --- /dev/null +++ b/db/migrate/20200920084007_backfill_custom_emoji_ownership.rb @@ -0,0 +1,12 @@ +class BackfillCustomEmojiOwnership < ActiveRecord::Migration[5.2] + disable_ddl_transaction! + + def up + site_contact = Account.site_contact + CustomEmoji.local.in_batches.update_all(account_id: site_contact.id) + end + + def down + nil + end +end diff --git a/db/schema.rb b/db/schema.rb index fbcf8e636..eb0605314 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_09_07_195410) do +ActiveRecord::Schema.define(version: 2020_09_20_084007) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -357,6 +357,8 @@ ActiveRecord::Schema.define(version: 2020_09_07_195410) do t.boolean "visible_in_picker", default: true, null: false t.bigint "category_id" t.integer "image_storage_schema_version" + t.bigint "account_id" + t.index ["account_id"], name: "index_custom_emojis_on_account_id" t.index ["shortcode", "domain"], name: "index_custom_emojis_on_shortcode_and_domain", unique: true end @@ -1069,6 +1071,7 @@ ActiveRecord::Schema.define(version: 2020_09_07_195410) do add_foreign_key "conversation_mutes", "accounts", name: "fk_225b4212bb", on_delete: :cascade add_foreign_key "conversation_mutes", "conversations", on_delete: :cascade add_foreign_key "conversations", "accounts" + add_foreign_key "custom_emojis", "accounts", on_delete: :nullify add_foreign_key "custom_filters", "accounts", on_delete: :cascade add_foreign_key "devices", "accounts", on_delete: :cascade add_foreign_key "devices", "oauth_access_tokens", column: "access_token_id", on_delete: :cascade |