# frozen_string_literal: true # Obtiene o actualiza el contenido de un objeto, usando las credenciales # del sitio. # # XXX: Esto usa las credenciales del sitio para volver el objeto # disponible para todo el CMS. Asumimos que el objeto devuelto es el # mismo para todo el mundo y las credenciales solo son para # autenticación. class ActivityPub class FetchJob < ApplicationJob self.priority = 50 attr_reader :object, :response # Notificar errores de JSON con el contenido, tomar los errores de # validación y conexión como errores temporales y notificar todo lo # demás sin reintentar. # # @param error [Exception] # @return [Bool] discard_on(FastJsonparser::ParseError) do |error| ExceptionNotifier.notify_exception(error, data: { site: site.name, object: object.uri, body: response.body }) end retry_on ActiveRecord::RecordInvalid retry_on SocketError, wait: ApplicationJob.random_wait retry_on SystemCallError, wait: ApplicationJob.random_wait retry_on Net::OpenTimeout, wait: ApplicationJob.random_wait retry_on OpenSSL::OpenSSLError, wait: ApplicationJob.random_wait def perform(site:, object_id:) ActivityPub::Object.transaction do @site = site @object = ::ActivityPub::Object.find(object_id) return if object.blank? return if object.activity_pubs.where(aasm_state: 'removed').count.positive? @response = site.social_inbox.dereferencer.get(uri: object.uri) # @todo Fallar cuando la respuesta no funcione? # @todo Eliminar en 410 Gone return unless response.success? # Ignorar si ya la caché fue revalidada y ya teníamos el # contenido return if response.hit? && object.content.present? current_type = object.type content = FastJsonparser.parse(response.body) # Modificar atómicamente ::ActivityPub::Object.lock.find(object_id).update!(content: content, type: ActivityPub::Object.type_from(content).name) object = ::ActivityPub::Object.find(object_id) # Actualiza la mención object.actor&.save! if object.actor_type? # Arreglar las relaciones con actividades también ActivityPub.where(object_id: object.id).update_all(object_type: object.type, updated_at: Time.now) end end end end