sutty/app/models/metadata_file.rb

132 lines
2.9 KiB
Ruby
Raw Normal View History

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
{ 'path' => nil, 'description' => nil }
end
def empty?
value == default_value
end
def validate
super
errors << I18n.t('metadata.image.path_required') if path_missing?
errors.compact!
errors.empty?
end
# Determina si necesitamos la imagen pero no la tenemos
def path_missing?
required && !path?
2019-11-07 16:08:14 +00:00
end
# Determina si el archivo ya fue subido
def uploaded?
value['path'].is_a?(String) && path?
2019-11-07 16:08:14 +00:00
end
# Determina si la ruta es opcional pero deja pasar si la ruta se
# especifica
def path_optional?
!required && !path?
2019-11-07 16:08:14 +00:00
end
# Asociar la imagen subida al sitio y obtener la ruta
def save
return true unless changed?
value['description'] = sanitize value['description']
value['path'] = nil unless path?
2019-11-07 16:08:14 +00:00
return true if uploaded?
return true if path_optional?
return false unless hardlink.zero?
# Modificar el valor actual
value['path'] = relative_destination_path
true
end
# Almacena el archivo en el sitio y lo devuelve
#
# @return ActiveStorage::Attachment
def static_file
2019-11-14 17:27:24 +00:00
return @static_file if @static_file
return unless path?
2019-11-14 17:27:24 +00:00
2019-11-07 16:08:14 +00:00
ActiveRecord::Base.connection_pool.with_connection do
if uploaded?
blob = ActiveStorage::Blob.find_by(key: key_from_path)
@static_file ||= site.static_files.find_by(blob_id: blob.id)
elsif site.static_files.attach(value['path'])
@static_file ||= site.static_files.last
end
end
end
private
def path?
!value['path'].blank?
end
2020-08-05 15:29:11 +00:00
def filemagic
@filemagic ||= FileMagic.new(FileMagic::MAGIC_MIME)
end
2019-11-14 17:27:24 +00:00
def path
@path ||= Pathname.new value['path']
end
# Obtiene la ruta absoluta del archivo
#
# @return [String|Nil]
2020-08-05 15:29:11 +00:00
def file
return unless path?
2020-08-05 15:29:11 +00:00
if value['path'].is_a? ActionDispatch::Http::UploadedFile
value['path'].tempfile.path
else
File.join site.path, value['path']
2020-08-05 15:29:11 +00:00
end
end
2019-11-07 16:08:14 +00:00
def key_from_path
2019-11-14 17:27:24 +00:00
path.dirname.basename.to_s
2019-11-07 16:08:14 +00:00
end
# Hacemos un link duro para colocar el archivo dentro del repositorio
# y no duplicar el espacio que ocupan. Esto requiere que ambos
# directorios estén dentro del mismo punto de montaje.
def hardlink
FileUtils.mkdir_p File.dirname(destination_path)
FileUtils.ln uploaded_path, destination_path
end
# Obtener la ruta al archivo
# https://stackoverflow.com/a/53908358
def uploaded_relative_path
ActiveStorage::Blob.service.path_for(static_file.key)
end
def uploaded_path
Rails.root.join uploaded_relative_path
end
def relative_destination_path
2019-11-14 17:27:24 +00:00
File.join('public', static_file.key, static_file.filename.to_s)
2019-11-07 16:08:14 +00:00
end
def destination_path
File.join(site.path, relative_destination_path)
end
end