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
|
||||
|
||||
# Define un campo de imagen
|
||||
# TODO: Validar que sea una imagen
|
||||
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
|
||||
|
||||
class MetadataImage < MetadataFile
|
||||
def validate
|
||||
super
|
||||
|
||||
errors << I18n.t('metadata.image.path_required') if path_missing?
|
||||
errors << I18n.t('metadata.image.not_an_image') unless image?
|
||||
|
||||
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 es una imagen antes de subirla
|
||||
def image?
|
||||
if value['path'].is_a? ActionDispatch::Http::UploadedFile
|
||||
|
@ -44,78 +23,4 @@ class MetadataImage < MetadataTemplate
|
|||
true
|
||||
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
|
||||
|
|
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