mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-14 23:01:41 +00:00
WIP de subir archivos
This commit is contained in:
parent
c791620f3c
commit
a1fe309e6a
10 changed files with 139 additions and 5 deletions
4
Gemfile
4
Gemfile
|
@ -40,6 +40,10 @@ gem 'jquery-rails'
|
|||
gem 'font-awesome-rails'
|
||||
gem 'exception_notification'
|
||||
gem 'whenever', require: false
|
||||
gem 'carrierwave'
|
||||
gem 'carrierwave-i18n'
|
||||
gem 'mini_magick'
|
||||
gem 'carrierwave-bombshelter'
|
||||
|
||||
group :development, :test do
|
||||
gem 'pry'
|
||||
|
|
18
Gemfile.lock
18
Gemfile.lock
|
@ -75,6 +75,15 @@ GEM
|
|||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (>= 2.0, < 4.0)
|
||||
carrierwave (1.2.3)
|
||||
activemodel (>= 4.0.0)
|
||||
activesupport (>= 4.0.0)
|
||||
mime-types (>= 1.16)
|
||||
carrierwave-bombshelter (0.2.2)
|
||||
activesupport (>= 3.2.0)
|
||||
carrierwave
|
||||
fastimage
|
||||
carrierwave-i18n (0.2.0)
|
||||
childprocess (0.9.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
chronic (0.10.2)
|
||||
|
@ -101,6 +110,7 @@ GEM
|
|||
actionmailer (>= 4.0, < 6)
|
||||
activesupport (>= 4.0, < 6)
|
||||
execjs (2.7.0)
|
||||
fastimage (2.1.3)
|
||||
ffi (1.9.23)
|
||||
font-awesome-rails (4.7.0.4)
|
||||
railties (>= 3.2, < 6.0)
|
||||
|
@ -161,6 +171,10 @@ GEM
|
|||
mini_mime (>= 0.1.1)
|
||||
mercenary (0.3.6)
|
||||
method_source (0.9.0)
|
||||
mime-types (3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mini_magick (4.8.0)
|
||||
mini_mime (1.0.0)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.11.3)
|
||||
|
@ -296,6 +310,9 @@ DEPENDENCIES
|
|||
capistrano-rails
|
||||
capistrano-rbenv
|
||||
capybara (~> 2.13)
|
||||
carrierwave
|
||||
carrierwave-bombshelter
|
||||
carrierwave-i18n
|
||||
commonmarker
|
||||
dotenv-rails
|
||||
email_address
|
||||
|
@ -306,6 +323,7 @@ DEPENDENCIES
|
|||
jekyll
|
||||
jquery-rails
|
||||
listen (>= 3.0.5, < 3.2)
|
||||
mini_magick
|
||||
pry
|
||||
puma (~> 3.7)
|
||||
rails (~> 5.1.4)
|
||||
|
|
|
@ -199,9 +199,23 @@ class Post
|
|||
# HashWithIndifferentAccess
|
||||
attrs = attrs.to_h.map do |k,v|
|
||||
t = template_fields.find { |t| t.key == k }
|
||||
if t && t.nested?
|
||||
v = t.array? ? v.values.map(&:to_h) : v.to_h
|
||||
if t
|
||||
# Subir la imagen!
|
||||
if t.image?
|
||||
begin
|
||||
i = Post::ImageUploader.new(site)
|
||||
i.store! v.tempfile
|
||||
v = i.url
|
||||
rescue CarrierWave::IntegrityError => e
|
||||
v = e.message
|
||||
end
|
||||
end
|
||||
|
||||
if t.nested?
|
||||
v = t.array? ? v.values.map(&:to_h) : v.to_h
|
||||
end
|
||||
end
|
||||
|
||||
{ k => v }
|
||||
end.reduce(Hash.new, :merge).stringify_keys
|
||||
|
||||
|
@ -209,10 +223,20 @@ class Post
|
|||
end
|
||||
|
||||
# Requisitos para que el post sea válido
|
||||
# TODO verificar que el id sea único
|
||||
# TODO validar los parametros de la plantilla
|
||||
def validate
|
||||
add_error validate: I18n.t('posts.errors.date') unless date.is_a? Time
|
||||
add_error validate: I18n.t('posts.errors.title') if title.blank?
|
||||
# TODO verificar que el id sea único
|
||||
# XXX este es un principio de validación de plantillas, aunque no es
|
||||
# recursivo
|
||||
template_fields.each do |tf|
|
||||
# TODO descubrir de mejor forma que el archivo no es del formato
|
||||
# correcto
|
||||
if tf.image? && get_front_matter(tf.key).split('/').to_a.count <= 1
|
||||
add_error validate: get_front_matter(tf.key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def valid?
|
||||
|
|
39
app/models/post/image_uploader.rb
Normal file
39
app/models/post/image_uploader.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Una clase que permite adjuntar imágenes a artículos
|
||||
class Post::ImageUploader < CarrierWave::Uploader::Base
|
||||
|
||||
attr_accessor :site
|
||||
|
||||
# Necesitamos pasar el sitio para poder acceder a los archivos locales
|
||||
def initialize(site)
|
||||
super
|
||||
|
||||
@site = site
|
||||
end
|
||||
|
||||
# Solo aceptamos imágenes
|
||||
def content_type_whitelist
|
||||
/\Aimage\//
|
||||
end
|
||||
|
||||
# Devuelve la ubicación del directorio dentro de Jekyll, para eso,
|
||||
# tenemos que tener acceso al sitio que estamos editando
|
||||
def store_dir
|
||||
File.join site.path, 'public', 'images'
|
||||
end
|
||||
|
||||
# Almacenar en el 'tmp' local
|
||||
def cache_dir
|
||||
File.join Rails.root, 'tmp', 'images'
|
||||
end
|
||||
|
||||
# XXX los nombres de los archivos siempre son únicos, no chequeamos si
|
||||
# están repetidos.
|
||||
def filename
|
||||
[SecureRandom.uuid, '.', file.extension].join
|
||||
end
|
||||
|
||||
# Obtener la URL dentro del proyecto de Jekyll
|
||||
def url
|
||||
CGI.unescape(super).remove site.path
|
||||
end
|
||||
end
|
|
@ -4,7 +4,11 @@ class Post
|
|||
class TemplateField
|
||||
attr_reader :post, :contents, :key
|
||||
|
||||
STRING_VALUES = %w[string text url number email password date year].freeze
|
||||
STRING_VALUES = %w[string text url number email password date year
|
||||
image video audio document].freeze
|
||||
|
||||
# Tipo de valores que son archivos
|
||||
FILE_TYPES = %w[image video audio document].freeze
|
||||
|
||||
def initialize(post, key, contents)
|
||||
@post = post
|
||||
|
@ -32,6 +36,8 @@ class Post
|
|||
return @type if @type
|
||||
|
||||
case
|
||||
when image?
|
||||
@type = 'image'
|
||||
when email?
|
||||
@type = 'email'
|
||||
when url?
|
||||
|
@ -120,6 +126,14 @@ class Post
|
|||
value == 'year'
|
||||
end
|
||||
|
||||
def file?
|
||||
string? && FILE_TYPES.include?(value)
|
||||
end
|
||||
|
||||
def image?
|
||||
value == 'image'
|
||||
end
|
||||
|
||||
# Si la plantilla es simple no está admitiendo Hashes como valores
|
||||
def simple?
|
||||
!complex?
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
- else
|
||||
- url = site_post_path(@site, @post, lang: @lang)
|
||||
- method = :patch
|
||||
= form_tag url, method: method, class: 'form', novalidate: true do
|
||||
= form_tag url, method: method, class: 'form', novalidate: true, multipart: true do
|
||||
= hidden_field_tag 'template', params[:template]
|
||||
.form-group
|
||||
= submit_tag t('posts.save'), class: 'btn btn-success'
|
||||
|
|
3
app/views/posts/template_field/_image.haml
Normal file
3
app/views/posts/template_field/_image.haml
Normal file
|
@ -0,0 +1,3 @@
|
|||
= file_field_tag field_name_for_post_as_string(name),
|
||||
class: 'form-control',
|
||||
required: template.required?
|
|
@ -51,4 +51,10 @@ Rails.application.configure do
|
|||
# Use an evented file watcher to asynchronously detect changes in source code,
|
||||
# routes, locales, etc. This feature depends on the listen gem.
|
||||
config.file_watcher = ActiveSupport::EventedFileUpdateChecker
|
||||
|
||||
CarrierWave.configure do |config|
|
||||
config.ignore_integrity_errors = false
|
||||
config.ignore_processing_errors = false
|
||||
config.ignore_download_errors = false
|
||||
end
|
||||
end
|
||||
|
|
5
config/initializers/carrierwave.rb
Normal file
5
config/initializers/carrierwave.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
CarrierWave.configure do |config|
|
||||
config.permissions = 0640
|
||||
config.directory_permissions = 0750
|
||||
config.storage = :file
|
||||
end
|
21
doc/uploads.md
Normal file
21
doc/uploads.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Subida de archivos
|
||||
|
||||
La subida de archivos se genera a partir de agregar el valor a una
|
||||
plantilla:
|
||||
|
||||
```yaml
|
||||
---
|
||||
cover: image
|
||||
attachment: document
|
||||
video: video
|
||||
audio: audio
|
||||
---
|
||||
```
|
||||
|
||||
Donde `image` solo admite imágenes, `document` cualquier tipo de documento y
|
||||
`video` y `audio` medios.
|
||||
|
||||
Al subir los archivos, se guardan en el directorio `public/` en la raíz
|
||||
del proyecto Jekyll.
|
||||
|
||||
En el frontmatter solo sale la URL del archivo asociado.
|
Loading…
Reference in a new issue