5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-15 09:01:42 +00:00
panel/app/models/site/static_file_migration.rb

125 lines
4 KiB
Ruby
Raw Normal View History

2019-11-14 17:27:24 +00:00
# frozen_string_literal: true
class Site
MigrationAuthor = Struct.new :email, :name, keyword_init: true
# 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
remove = true
# 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?
path = Pathname.new(metadata.value['path'])
# Si no existe, agregamos una imagen faltante para no
# romper el sitio en Sutty
unless path.exist?
log.write "#{path} no existe\n"
path = Pathname.new(Rails.root.join('app/assets/images/logo.png'))
remove = false
end
# Agregamos el archivo al sitio y se lo asignamos al campo
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
next unless remove
dest = Pathname.new(metadata.send(:relative_destination_path))
# 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
unless doc.save(false)
log.write "#{doc.path.relative} no se pudo guardar\n"
end
modified << doc.path.absolute
end
end
end
log.close
# 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
@author = MigrationAuthor.new email: "sutty@#{Site.domain}",
name: 'Sutty'
end
# Encuentra todos los layouts con campos estáticos
def layouts
@layouts ||= site.layouts.reject do |_, layout|
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