mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 22:06:22 +00:00
57b652bbb1
los structs son como hashes con llaves fijas. si llamamos a una que no existe vamos a tener una excepción
124 lines
4 KiB
Ruby
124 lines
4 KiB
Ruby
# 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(validate: 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.to_h.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
|