2019-11-14 17:27:24 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class Site
|
|
|
|
# Obtiene todos los archivos relacionados en artículos del sitio y los
|
|
|
|
# sube a Sutty de forma que los podamos seguir utilizando normalmente
|
|
|
|
# sin casos especiales (ej. soportar archivos locales al repositorio y
|
|
|
|
# remotos, alojados en Sutty)
|
|
|
|
#
|
|
|
|
# TODO: Convertir en reutilizable, por ejemplo correr en cada pull, no
|
|
|
|
# asumir que la migración se hizo una sola vez...
|
|
|
|
class StaticFileMigration
|
|
|
|
# Tipos de metadatos que contienen archivos
|
|
|
|
STATIC_TYPES = %w[file image].freeze
|
|
|
|
|
|
|
|
attr_reader :site
|
|
|
|
|
|
|
|
def initialize(site:)
|
|
|
|
@site = site
|
|
|
|
end
|
|
|
|
|
|
|
|
# Recorre todos los artículos cuyos layouts contengan campos con
|
|
|
|
# archivos estáticos
|
|
|
|
def migrate!
|
|
|
|
log = File.open(File.join(site.path, 'migration.log'), 'w')
|
|
|
|
modified = []
|
|
|
|
|
|
|
|
Dir.chdir site.path do
|
|
|
|
site.locales.each do |locale|
|
|
|
|
# Recorrer todos los documentos de todas las colecciones
|
|
|
|
site.posts(lang: locale).each do |doc|
|
|
|
|
# Ignoramos los documentos cuyo layout no contiene archivos
|
|
|
|
next unless layouts.include? doc.layout.name
|
|
|
|
|
|
|
|
# Buscamos todos los campos con archivos
|
|
|
|
fields.each do |field|
|
|
|
|
next unless doc.attribute? field
|
|
|
|
next unless doc.document.data.key? field.to_s
|
|
|
|
|
|
|
|
# Traemos los metadatos, en este punto, Sutty cree que el
|
|
|
|
# archivo está subido, porque es una string apuntando a un
|
|
|
|
# archivo.
|
|
|
|
metadata = doc.public_send(field)
|
|
|
|
|
|
|
|
next if metadata.value['path'].blank?
|
2021-02-16 21:08:42 +00:00
|
|
|
next if ActiveStorage::Blob.find_by(key: metadata.key_from_path)
|
2019-11-14 17:27:24 +00:00
|
|
|
|
|
|
|
path = Pathname.new(metadata.value['path'])
|
|
|
|
|
2020-11-11 18:31:15 +00:00
|
|
|
# Si no existe vaciamos el campo
|
2019-11-14 17:27:24 +00:00
|
|
|
unless path.exist?
|
2020-11-11 18:31:15 +00:00
|
|
|
metadata.value['path'] = nil
|
|
|
|
log.write "el archivo #{path} de #{doc.path.relative} no existe"
|
|
|
|
next
|
2019-11-14 17:27:24 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Agregamos el archivo al sitio y se lo asignamos al campo
|
2020-11-20 17:09:02 +00:00
|
|
|
# XXX: No usamos ActionDispatch::Http::UploadedFile porque
|
|
|
|
# no tenemos forma de crear un Tempfile o equivalente a
|
|
|
|
# partir de un archivo que exista.
|
2019-11-14 17:27:24 +00:00
|
|
|
metadata.value['path'] = {
|
|
|
|
io: path.open,
|
|
|
|
filename: path.basename
|
|
|
|
}
|
|
|
|
|
|
|
|
# Copiar y analizar el archivo sincrónicamente
|
|
|
|
metadata.static_file.blob.upload path.open
|
|
|
|
metadata.static_file.blob.analyze
|
|
|
|
|
|
|
|
dest = Pathname.new(metadata.send(:relative_destination_path))
|
2020-11-20 17:09:02 +00:00
|
|
|
metadata.value['path'] = dest.to_s
|
2020-11-26 17:35:42 +00:00
|
|
|
metadata.send(:hardlink)
|
2019-11-14 17:27:24 +00:00
|
|
|
|
|
|
|
# Eliminamos el archivo original y lo vinculamos al subido
|
|
|
|
# para mantener la ruta y no romper el sitio
|
|
|
|
FileUtils.rm_f path
|
|
|
|
# XXX: Link simbólico o duro?
|
|
|
|
FileUtils.ln_s dest.relative_path_from(path.dirname), path
|
|
|
|
end
|
|
|
|
|
|
|
|
# Guardamos los cambios
|
2020-06-16 22:10:54 +00:00
|
|
|
log.write "#{doc.path.relative} no se pudo guardar\n" unless doc.save(validate: false)
|
2019-11-14 17:27:24 +00:00
|
|
|
|
|
|
|
modified << doc.path.absolute
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
log.close
|
|
|
|
|
2020-11-11 18:31:15 +00:00
|
|
|
return if modified.empty?
|
|
|
|
|
2019-11-14 17:27:24 +00:00
|
|
|
# TODO: Hacer la migración desde el servicio de creación de sitios?
|
|
|
|
site.repository.commit(file: modified,
|
|
|
|
message: I18n.t('sites.static_file_migration'),
|
|
|
|
usuarie: author)
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def author
|
2020-06-16 22:10:54 +00:00
|
|
|
@author ||= GitAuthor.new email: "sutty@#{Site.domain}",
|
|
|
|
name: 'Sutty'
|
2019-11-14 17:27:24 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Encuentra todos los layouts con campos estáticos
|
|
|
|
def layouts
|
2020-02-13 15:38:53 +00:00
|
|
|
@layouts ||= site.layouts.to_h.reject do |_, layout|
|
2019-11-14 17:27:24 +00:00
|
|
|
layout.metadata.select do |_, desc|
|
|
|
|
STATIC_TYPES.include? desc['type']
|
|
|
|
end.empty?
|
|
|
|
end.keys
|
|
|
|
end
|
|
|
|
|
|
|
|
# Encuentra todos los campos con archivos estáticos
|
|
|
|
def fields
|
|
|
|
@fields ||= layouts.map do |layout|
|
|
|
|
site.layouts[layout].metadata.select do |_, desc|
|
|
|
|
STATIC_TYPES.include? desc['type']
|
|
|
|
end.keys
|
|
|
|
end.flatten.uniq.map(&:to_sym)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|