metadata file & url
This commit is contained in:
parent
7ddc4e6150
commit
9c54518c8e
9 changed files with 153 additions and 96 deletions
106
app/models/metadata_file.rb
Normal file
106
app/models/metadata_file.rb
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# 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 && !value['path'].blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Determina si el archivo ya fue subido
|
||||||
|
def uploaded?
|
||||||
|
value['path'].is_a?(String)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Determina si la ruta es opcional pero deja pasar si la ruta se
|
||||||
|
# especifica
|
||||||
|
def path_optional?
|
||||||
|
!required && value['path'].blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Asociar la imagen subida al sitio y obtener la ruta
|
||||||
|
def save
|
||||||
|
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
|
||||||
|
|
||||||
|
def to_param
|
||||||
|
{ name => %i[description path] }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Almacena el archivo en el sitio y lo devuelve
|
||||||
|
#
|
||||||
|
# @return ActiveStorage::Attachment
|
||||||
|
def static_file
|
||||||
|
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 key_from_path
|
||||||
|
# XXX: No podemos usar self#extension porque en este punto todavía
|
||||||
|
# no sabemos el static_file
|
||||||
|
File.basename(value['path'], '.*')
|
||||||
|
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
|
||||||
|
|
||||||
|
def extension
|
||||||
|
static_file.blob.content_type.split('/').last
|
||||||
|
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
|
||||||
|
File.join('public', [static_file.key, extension].join('.'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def destination_path
|
||||||
|
File.join(site.path, relative_destination_path)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,37 +1,16 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Define un campo de imagen
|
# Define un campo de imagen
|
||||||
# TODO: Validar que sea una imagen
|
class MetadataImage < MetadataFile
|
||||||
class MetadataImage < 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
|
def validate
|
||||||
super
|
super
|
||||||
|
|
||||||
errors << I18n.t('metadata.image.path_required') if path_missing?
|
|
||||||
errors << I18n.t('metadata.image.not_an_image') unless image?
|
errors << I18n.t('metadata.image.not_an_image') unless image?
|
||||||
|
|
||||||
errors.compact!
|
errors.compact!
|
||||||
errors.empty?
|
errors.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determina si necesitamos la imagen pero no la tenemos
|
|
||||||
def path_missing?
|
|
||||||
required && !value['path'].blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
# Determina si el archivo ya fue subido
|
|
||||||
def uploaded?
|
|
||||||
value['path'].is_a?(String)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Determina si es una imagen antes de subirla
|
# Determina si es una imagen antes de subirla
|
||||||
def image?
|
def image?
|
||||||
if value['path'].is_a? ActionDispatch::Http::UploadedFile
|
if value['path'].is_a? ActionDispatch::Http::UploadedFile
|
||||||
|
@ -44,78 +23,4 @@ class MetadataImage < MetadataTemplate
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Determina si la ruta es opcional pero deja pasar si la ruta se
|
|
||||||
# especifica
|
|
||||||
def path_optional?
|
|
||||||
!required && value['path'].blank?
|
|
||||||
end
|
|
||||||
|
|
||||||
# Asociar la imagen subida al sitio y obtener la ruta
|
|
||||||
def save
|
|
||||||
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
|
|
||||||
|
|
||||||
def to_param
|
|
||||||
{ name => %i[description path] }
|
|
||||||
end
|
|
||||||
|
|
||||||
# Almacena el archivo en el sitio y lo devuelve
|
|
||||||
#
|
|
||||||
# @return ActiveStorage::Attachment
|
|
||||||
def static_file
|
|
||||||
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 key_from_path
|
|
||||||
# XXX: No podemos usar self#extension porque en este punto todavía
|
|
||||||
# no sabemos el static_file
|
|
||||||
File.basename(value['path'], '.*')
|
|
||||||
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
|
|
||||||
|
|
||||||
def extension
|
|
||||||
static_file.blob.content_type.split('/').last
|
|
||||||
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
|
|
||||||
File.join('public', [static_file.key, extension].join('.'))
|
|
||||||
end
|
|
||||||
|
|
||||||
def destination_path
|
|
||||||
File.join(site.path, relative_destination_path)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
4
app/models/metadata_url.rb
Normal file
4
app/models/metadata_url.rb
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Un campo de URL
|
||||||
|
class MetadataUrl < MetadataString; end
|
7
app/views/posts/attribute_ro/_file.haml
Normal file
7
app/views/posts/attribute_ro/_file.haml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
%tr{ id: attribute }
|
||||||
|
%th= post_label_t(attribute, :path, post: post)
|
||||||
|
%td
|
||||||
|
- if metadata.value['path'].present?
|
||||||
|
%figure
|
||||||
|
= link_to url_for(metadata.static_file)
|
||||||
|
%figcaption= metadata.value['description']
|
3
app/views/posts/attribute_ro/_order.haml
Normal file
3
app/views/posts/attribute_ro/_order.haml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
%tr{ id: attribute }
|
||||||
|
%th= post_label_t(attribute, post: post)
|
||||||
|
%td= metadata.value
|
3
app/views/posts/attribute_ro/_url.haml
Normal file
3
app/views/posts/attribute_ro/_url.haml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
%tr{ id: attribute }
|
||||||
|
%th= post_label_t(attribute, post: post)
|
||||||
|
%td= link_to metadata.value
|
22
app/views/posts/attributes/_file.haml
Normal file
22
app/views/posts/attributes/_file.haml
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
.form-group
|
||||||
|
- if metadata.uploaded?
|
||||||
|
= hidden_field_tag "post[#{attribute}][path]", metadata.value['path']
|
||||||
|
|
||||||
|
.custom-file
|
||||||
|
= file_field(*field_name_for('post', attribute, :path),
|
||||||
|
**field_options(attribute, metadata),
|
||||||
|
class: "custom-file-input #{invalid(post, attribute)}",
|
||||||
|
data: { preview: "#{attribute}-preview" })
|
||||||
|
= label_tag "post_#{attribute}_path",
|
||||||
|
post_label_t(attribute, :path, post: post), class: 'custom-file-label'
|
||||||
|
= render 'posts/attribute_feedback',
|
||||||
|
post: post, attribute: [attribute, :path], metadata: metadata
|
||||||
|
|
||||||
|
.form-group
|
||||||
|
= label_tag "post_#{attribute}_description",
|
||||||
|
post_label_t(attribute, :description, post: post)
|
||||||
|
= text_field(*field_name_for('post', attribute, :description),
|
||||||
|
value: metadata.value['description'],
|
||||||
|
**field_options(attribute, metadata))
|
||||||
|
= render 'posts/attribute_feedback',
|
||||||
|
post: post, attribute: [attribute, :description], metadata: metadata
|
1
app/views/posts/attributes/_order.haml
Normal file
1
app/views/posts/attributes/_order.haml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
-# nada
|
6
app/views/posts/attributes/_url.haml
Normal file
6
app/views/posts/attributes/_url.haml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.form-group
|
||||||
|
= label_tag "post_#{attribute}", post_label_t(attribute, post: post)
|
||||||
|
= url_field 'post', attribute, value: metadata.value,
|
||||||
|
**field_options(attribute, metadata)
|
||||||
|
= render 'posts/attribute_feedback',
|
||||||
|
post: post, attribute: attribute, metadata: metadata
|
Loading…
Reference in a new issue