2019-11-07 16:08:14 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2020-08-05 15:29:11 +00:00
|
|
|
require 'filemagic'
|
|
|
|
|
2019-11-07 16:08:14 +00:00
|
|
|
# Define un campo de archivo
|
|
|
|
class MetadataFile < MetadataTemplate
|
|
|
|
# Una ruta vacía a la imagen con una descripción vacía
|
|
|
|
def default_value
|
2020-11-11 18:29:12 +00:00
|
|
|
super || { 'path' => nil, 'description' => nil }
|
2019-11-07 16:08:14 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def empty?
|
|
|
|
value == default_value
|
|
|
|
end
|
|
|
|
|
|
|
|
def validate
|
|
|
|
super
|
|
|
|
|
2021-04-24 22:55:15 +00:00
|
|
|
errors << I18n.t("metadata.#{type}.site_invalid") if site.invalid?
|
2020-11-25 14:59:55 +00:00
|
|
|
errors << I18n.t("metadata.#{type}.path_required") if path_missing?
|
|
|
|
errors << I18n.t("metadata.#{type}.no_file_for_description") if no_file_for_description?
|
2022-03-04 22:09:06 +00:00
|
|
|
errors << I18n.t("metadata.#{type}.attachment_missing") unless static_file
|
2019-11-07 16:08:14 +00:00
|
|
|
|
|
|
|
errors.compact!
|
|
|
|
errors.empty?
|
|
|
|
end
|
|
|
|
|
|
|
|
# Determina si necesitamos la imagen pero no la tenemos
|
|
|
|
def path_missing?
|
2020-09-01 21:33:10 +00:00
|
|
|
required && !path?
|
2019-11-07 16:08:14 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Determina si el archivo ya fue subido
|
|
|
|
def uploaded?
|
2021-02-23 22:00:38 +00:00
|
|
|
value['path'].is_a?(String)
|
2019-11-07 16:08:14 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Asociar la imagen subida al sitio y obtener la ruta
|
2021-02-23 22:00:38 +00:00
|
|
|
#
|
|
|
|
# XXX: Si evitamos guardar cambios con changed? no tenemos forma de
|
|
|
|
# saber que un archivo subido manualmente se convirtió en
|
|
|
|
# un Attachment y cada vez que lo editemos vamos a subir una imagen
|
|
|
|
# repetida.
|
2019-11-07 16:08:14 +00:00
|
|
|
def save
|
2020-09-01 21:33:10 +00:00
|
|
|
value['description'] = sanitize value['description']
|
2020-02-12 21:24:54 +00:00
|
|
|
|
2021-02-24 16:04:46 +00:00
|
|
|
if path?
|
|
|
|
hardlink
|
|
|
|
value['path'] = relative_destination_path
|
|
|
|
else
|
|
|
|
value['path'] = nil
|
|
|
|
end
|
2019-11-07 16:08:14 +00:00
|
|
|
|
|
|
|
true
|
|
|
|
end
|
|
|
|
|
2021-02-23 22:00:38 +00:00
|
|
|
# Almacena el archivo en el sitio y lo devuelve o lo obtiene de la
|
|
|
|
# base de datos.
|
|
|
|
#
|
|
|
|
# Existen tres casos:
|
|
|
|
#
|
|
|
|
# * El archivo fue subido a través de HTTP
|
|
|
|
# * El archivo es una ruta que apunta a un archivo asociado al sitio
|
|
|
|
# * El archivo es una ruta a un archivo dentro del repositorio
|
2019-11-07 16:08:14 +00:00
|
|
|
#
|
2021-02-23 22:00:38 +00:00
|
|
|
# XXX: La última opción provoca archivos duplicados, pero es lo mejor
|
|
|
|
# que tenemos hasta que resolvamos https://0xacab.org/sutty/sutty/-/issues/213
|
|
|
|
#
|
|
|
|
# @return [ActiveStorage::Attachment]
|
2019-11-07 16:08:14 +00:00
|
|
|
def static_file
|
2020-09-01 21:33:10 +00:00
|
|
|
return unless path?
|
2019-11-14 17:27:24 +00:00
|
|
|
|
2021-02-23 22:00:38 +00:00
|
|
|
@static_file ||=
|
|
|
|
case value['path']
|
|
|
|
when ActionDispatch::Http::UploadedFile
|
|
|
|
site.static_files.last if site.static_files.attach(value['path'])
|
|
|
|
when String
|
|
|
|
if (blob = ActiveStorage::Blob.where(key: key_from_path).pluck(:id).first)
|
|
|
|
site.static_files.find_by(blob_id: blob)
|
|
|
|
elsif site.static_files.attach(io: path.open, filename: path.basename)
|
|
|
|
site.static_files.last
|
|
|
|
end
|
2019-11-07 16:08:14 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-03-04 22:19:40 +00:00
|
|
|
# Obtiene la ruta absoluta al archivo
|
|
|
|
#
|
|
|
|
# @return [Pathname]
|
|
|
|
def pathname
|
|
|
|
raise NoMethodError unless uploaded?
|
|
|
|
|
|
|
|
@pathname ||= Pathname.new(File.join(site.path, value['path']))
|
|
|
|
end
|
|
|
|
|
2021-02-16 21:08:42 +00:00
|
|
|
def key_from_path
|
|
|
|
path.dirname.basename.to_s
|
|
|
|
end
|
|
|
|
|
2020-09-01 21:33:10 +00:00
|
|
|
def path?
|
2021-02-16 21:08:42 +00:00
|
|
|
value['path'].present?
|
2020-09-01 21:33:10 +00:00
|
|
|
end
|
|
|
|
|
2022-03-04 22:16:36 +00:00
|
|
|
def description?
|
|
|
|
value['description'].present?
|
|
|
|
end
|
2021-02-23 22:00:38 +00:00
|
|
|
|
2022-03-04 22:16:36 +00:00
|
|
|
private
|
2020-11-25 14:59:55 +00:00
|
|
|
|
|
|
|
# No hay archivo pero se lo describió
|
|
|
|
def no_file_for_description?
|
2022-03-04 22:16:36 +00:00
|
|
|
!path? && description?
|
2020-11-25 14:59:55 +00:00
|
|
|
end
|
2019-11-07 16:08:14 +00:00
|
|
|
end
|