2024-02-21 15:30:01 +00:00
|
|
|
# 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.
|
2024-02-21 15:46:38 +00:00
|
|
|
class ActivityPub
|
|
|
|
class FetchJob < ApplicationJob
|
2024-02-27 19:53:48 +00:00
|
|
|
self.priority = 50
|
|
|
|
|
2024-05-02 19:02:34 +00:00
|
|
|
attr_reader :object, :response
|
2024-03-27 17:06:23 +00:00
|
|
|
|
|
|
|
# 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]
|
2024-03-28 13:13:13 +00:00
|
|
|
discard_on(FastJsonparser::ParseError) do |error|
|
|
|
|
ExceptionNotifier.notify_exception(error, data: { site: site.name, object: object.uri, body: response.body })
|
2024-03-27 17:06:23 +00:00
|
|
|
end
|
|
|
|
|
2024-03-28 13:13:13 +00:00
|
|
|
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
|
|
|
|
|
2024-03-13 19:11:40 +00:00
|
|
|
def perform(site:, object_id:)
|
2024-02-21 15:46:38 +00:00
|
|
|
ActivityPub::Object.transaction do
|
2024-03-27 17:06:23 +00:00
|
|
|
@site = site
|
|
|
|
@object = ::ActivityPub::Object.find(object_id)
|
2024-03-13 19:11:40 +00:00
|
|
|
|
|
|
|
return if object.blank?
|
2024-02-21 20:08:11 +00:00
|
|
|
return if object.activity_pubs.where(aasm_state: 'removed').count.positive?
|
|
|
|
|
2024-03-27 17:06:23 +00:00
|
|
|
@response = site.social_inbox.dereferencer.get(uri: object.uri)
|
2024-02-21 15:30:01 +00:00
|
|
|
|
2024-02-21 15:46:38 +00:00
|
|
|
# @todo Fallar cuando la respuesta no funcione?
|
2024-03-18 19:45:00 +00:00
|
|
|
# @todo Eliminar en 410 Gone
|
2024-03-19 14:20:49 +00:00
|
|
|
return unless response.success?
|
2024-03-18 18:06:41 +00:00
|
|
|
# Ignorar si ya la caché fue revalidada y ya teníamos el
|
|
|
|
# contenido
|
|
|
|
return if response.hit? && object.content.present?
|
2024-02-21 15:32:39 +00:00
|
|
|
|
2024-03-14 15:27:59 +00:00
|
|
|
current_type = object.type
|
2024-02-21 17:07:11 +00:00
|
|
|
content = FastJsonparser.parse(response.body)
|
|
|
|
|
2024-03-19 20:02:19 +00:00
|
|
|
# Modificar atómicamente
|
2024-05-02 19:05:35 +00:00
|
|
|
::ActivityPub::Object.lock.find(object_id).update!(content: content,
|
|
|
|
type: ActivityPub::Object.type_from(content).name)
|
2024-03-14 15:27:59 +00:00
|
|
|
|
2024-03-16 20:53:29 +00:00
|
|
|
object = ::ActivityPub::Object.find(object_id)
|
2024-03-18 18:46:03 +00:00
|
|
|
# Actualiza la mención
|
|
|
|
object.actor&.save! if object.actor_type?
|
2024-03-16 20:53:29 +00:00
|
|
|
|
2024-03-14 15:27:59 +00:00
|
|
|
# Arreglar las relaciones con actividades también
|
2024-03-18 18:46:03 +00:00
|
|
|
ActivityPub.where(object_id: object.id).update_all(object_type: object.type, updated_at: Time.now)
|
2024-02-21 15:46:38 +00:00
|
|
|
end
|
2024-02-21 15:30:01 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|