# frozen_string_literal: true # Relación entre Fediblocks y Sites. # # Cuando se habilita un Fediblock, tenemos que asociar todas sus # instancias con el sitio y bloquearlas. Cuando se deshabilita, la # relación ya está creada y se va actualizando. # # @see ActivityPub::FediblockUpdatedJob class FediblockState < ApplicationRecord include AASM belongs_to :site belongs_to :fediblock, class_name: 'ActivityPub::Fediblock' # El efecto secundario de esta máquina de estados es modificar el # estado de moderación de cada instancia en el sitio. Nos salteamos # los hooks de los eventos individuales. aasm do # Aunque queramos las listas habilitadas por defecto, tenemos que # habilitarlas luego de crearlas para poder generar la lista de # bloqueo en la Social Inbox. state :disabled, initial: true, before_enter: :pause_unique_instances! state :enabled, before_enter: :block_instances! error_on_all_events do |e| ExceptionNotifier.notify_exception(e, data: { site: site.name, fediblock: id }) end event :enable do transitions from: :disabled, to: :enabled end # Al deshabilitar, las listas pasan a modo pausa, a menos que estén # activas en otros listados. # # @todo No cambiar el estado si se habían habilitado manualmente, # pero esto implica que tenemos que encontrar las que sí y quitarlas # de list_names event :disable do transitions from: :enabled, to: :disabled, after: :synchronize! end end private def block_instances! ActivityPub::InstanceModerationJob.perform_later(site: site, hostnames: fediblock.hostnames, perform_remotely: false) end # Pausar todas las moderaciones de las instancias que no estén # bloqueadas por otros fediblocks. def pause_unique_instances! instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids site.instance_moderations.where(instance_id: instance_ids).pause_all_without_callbacks! end def synchronize! ActivityPub::SyncListsJob.perform_later(site: site) end # Devuelve los hostnames únicos a esta instancia. # # @return [Array] def unique_hostnames @unique_hostnames ||= begin other_enabled_fediblock_ids = site.fediblock_states.enabled.where.not(id: id).pluck(:fediblock_id) other_enabled_hostnames = ActivityPub::Fediblock .where(id: other_enabled_fediblock_ids) .pluck(:hostnames) .flatten .uniq fediblock.hostnames - other_enabled_hostnames end end end