renombrar archivos

This commit is contained in:
f 2019-08-08 15:28:23 -03:00
parent ada14b2294
commit f7527e7ee3
No known key found for this signature in database
GPG key ID: 2AE5A13E321F953D
10 changed files with 146 additions and 35 deletions

View file

@ -33,6 +33,7 @@ Metrics/MethodLength:
- 'app/controllers/i18n_controller.rb'
- 'app/controllers/collaborations_controller.rb'
- 'app/controllers/usuaries_controller.rb'
- 'app/models/post.rb'
Metrics/BlockLength:
Exclude:
@ -47,6 +48,7 @@ Metrics/ClassLength:
- 'app/models/site.rb'
- 'app/controllers/posts_controller.rb'
- 'app/controllers/sites_controller.rb'
- 'test/models/post_test.rb'
Lint/HandleExceptions:
Exclude:

View file

@ -0,0 +1,22 @@
# frozen_string_literal: true
module CoreExtensions
module Jekyll
module Document
# Permite cambiar la ubicación del archivo para que podamos leerlo
# sin tener que instanciar uno nuevo.
module Path
def path=(new_path)
@path = new_path
# Dejar que lo recalcule al releer
@cleaned_relative_path =
@extname =
@basename =
@basename_without_ext =
@output_ext =
@relative_path = nil
end
end
end
end
end

View file

@ -0,0 +1,3 @@
class MetadataDate < MetadataTemplate
end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
# Maneja la fecha del document
class MetadataDocumentDate < MetadataTemplate
# La fecha por defecto es ahora!

View file

@ -0,0 +1,35 @@
# Este campo representa el archivo donde se almacenan los datos
class MetadataPath < MetadataTemplate
# :label en este caso es el idioma/colección
def default_value
File.join(site.path, "_#{lang}", "#{date}-#{slug}#{ext}")
end
def value
default_value
end
alias absolute value
alias to_s value
def relative
value.sub(site.path, '').sub(%r{^/}, '')
end
private
def ext
document.extname || '.markdown'
end
def lang
post.lang
end
def slug
post.slug.value
end
def date
post.date.value.strftime('%F')
end
end

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'jekyll/utils'
# El slug es el nombre del archivo sin la fecha ni la extensión y se

View file

@ -4,7 +4,7 @@
#
# TODO: Validar el tipo de valor pasado a value= según el :type
MetadataTemplate = Struct.new(:site, :document, :name, :label, :type,
:value, :help, :required, :errors,
:value, :help, :required, :errors, :post,
:layout, keyword_init: true) do
# El valor por defecto
def default_value

View file

@ -13,7 +13,7 @@ class Post < OpenStruct
# XXX: Volver document opcional cuando estemos creando
DEFAULT_ATTRIBUTES = %i[site document layout].freeze
# Otros atributos que no vienen en los metadatos
ATTRIBUTES = %i[content lang date slug attributes errors].freeze
ATTRIBUTES = %i[content lang path date slug attributes errors].freeze
# Redefinir el inicializador de OpenStruct
#
@ -22,7 +22,6 @@ class Post < OpenStruct
# @param layout: [Layout] la plantilla
#
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def initialize(**args)
default_attributes_missing(args)
super(args)
@ -45,6 +44,7 @@ class Post < OpenStruct
layout.metadata.each_pair do |name, template|
send "#{name}=".to_sym,
MetadataFactory.build(document: document,
post: self,
site: site,
name: name,
layout: layout,
@ -56,12 +56,12 @@ class Post < OpenStruct
load_slug!
load_date!
load_path!
# Leer el documento
read
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/MethodLength
# Levanta un error si al construir el artículo no pasamos un atributo.
def default_attributes_missing(**args)
@ -127,13 +127,13 @@ class Post < OpenStruct
#
# XXX Commit
def destroy
FileUtils.rm_f path
FileUtils.rm_f path.absolute
site.posts(lang: lang).delete_if do |post|
post.path == path
post.path.absolute == path.absolute
end
!File.exist?(path) && !site.posts(lang: lang).include?(self)
!File.exist?(path.absolute) && !site.posts(lang: lang).include?(self)
end
alias destroy! destroy
# rubocop:enable Metrics/AbcSize
@ -141,10 +141,12 @@ class Post < OpenStruct
# Guarda los cambios
def save
return false unless valid?
# Salir si tenemos que cambiar el nombre del archivo y no pudimos
return false if path_changed? && !update_path!
return false unless write
# Vuelve a leer el post para tomar los cambios
document.read
read
true
end
@ -152,20 +154,15 @@ class Post < OpenStruct
# Lee el documento
def read
Dir.chdir(site.path) do
document.read
end
document.read
end
# Devuelve la ruta del post, si se cambió alguno de los datos,
# generamos una ruta nueva para tener siempre la ruta actualizada.
def path
document.path
end
alias relative_path path
def absolute_path
File.join site.path, path
# Actualizar la ubicación del archivo si cambió de lugar y si no
# existe el destino
def update_path!
!File.exist?(path.absolute) &&
FileUtils.mv(path_was, path.absolute) &&
document.path = path.absolute
end
# Detecta si el artículo es válido para guardar
@ -224,7 +221,7 @@ class Post < OpenStruct
def write
return true if persisted?
Site::Writer.new(site: site, file: path,
Site::Writer.new(site: site, file: path.absolute,
content: full_content, usuarie: usuarie,
message: title.value).save
end
@ -241,25 +238,27 @@ class Post < OpenStruct
# Verifica si hace falta escribir cambios
def persisted?
File.exist?(absolute_path) && full_content == File.read(absolute_path)
File.exist?(path.absolute) && full_content == File.read(path.absolute)
end
private
# rubocop:disable Metrics/AbcSize
def new_attribute_was(method)
attr_was = (attribute_name(method).to_s + '_was').to_sym
return attr_was if singleton_class.method_defined? attr_was
define_singleton_method(attr_was) do
name = attribute_name(attr_was)
name == :content ? document.content : document.data[name.to_s]
if document.respond_to?(name)
document.send(name)
else
document.data[name.to_s]
end
end
attr_was
end
# Pregunta si el atributo cambió
# rubocop:disable Metrics/AbcSize
def new_attribute_changed(method)
attr_changed = (attribute_name(method).to_s + '_changed?').to_sym
@ -284,15 +283,25 @@ class Post < OpenStruct
def load_slug!
self.slug = MetadataSlug.new(document: document, site: site,
layout: layout, name: :slug,
layout: layout, name: :slug, type: :slug,
post: self,
required: true)
end
def load_date!
self.date = MetadataDocumentDate.new(document: document, site: site,
layout: layout, name: :date,
type: :document_date,
post: self,
required: true)
end
def load_path!
self.path = MetadataPath.new(document: document, site: site,
layout: layout, name: :path,
type: :path, post: self,
required: true)
end
end
# rubocop:enable Metrics/ClassLength
# rubocop:enable Style/MethodMissingSuper

View file

@ -1,3 +1,6 @@
# frozen_string_literal: true
require 'jekyll/document'
String.include CoreExtensions::String::StripTags
Jekyll::Document.include CoreExtensions::Jekyll::Document::Path

View file

@ -34,18 +34,18 @@ class PostTest < ActiveSupport::TestCase
test 'se pueden eliminar' do
# TODO: cuando esté con git, solo aplicar git reset
tmp = File.join(Rails.root, 'tmp', 'eliminar.md')
FileUtils.cp @post.path, tmp
FileUtils.cp @post.path.absolute, tmp
assert @post.destroy
assert_not File.exist?(@post.path)
assert_not File.exist?(@post.path.absolute)
assert_not @site.posts.include?(@post)
FileUtils.mv tmp, @post.path
FileUtils.mv tmp, @post.path.absolute
end
test 'se puede ver el contenido completo después de guardar' do
assert @post.save
@post.document.read
@post.read
# Queremos saber si todos los atributos del post terminaron en el
# archivo
@ -56,10 +56,10 @@ class PostTest < ActiveSupport::TestCase
if metadata.empty?
assert_not @post.document.data[attr.to_s].present?
elsif attr == :date
assert_equal metadata.value, @post.document.date
elsif @post.document.respond_to? attr
assert_equal metadata.value, @post.document.send(attr), attr
else
assert_equal metadata.value, @post.document.data[attr.to_s]
assert_equal metadata.value, @post.document.data[attr.to_s], attr
end
end
end
@ -83,7 +83,7 @@ class PostTest < ActiveSupport::TestCase
Dir.chdir(@site.path) do
collection = Jekyll::Collection.new(@site.jekyll, I18n.locale.to_s)
document = Jekyll::Document.new(@post.path,
document = Jekyll::Document.new(@post.path.value,
site: @site.jekyll,
collection: collection)
document.read
@ -128,4 +128,37 @@ class PostTest < ActiveSupport::TestCase
assert @post.date_changed?
assert @post.date.valid?
end
test 'al cambiar slug o fecha cambia el archivo de ubicacion' do
hoy = Date.today.to_time
path_was = @post.path.absolute
@post.slug.value = 'test'
@post.date.value = hoy
assert @post.path_changed?
assert_equal "_es/#{hoy.strftime('%F')}-test.markdown",
@post.path.relative
assert @post.save
assert_equal "_es/#{hoy.strftime('%F')}-test.markdown",
@post.document.relative_path
assert_not File.exist?(path_was)
assert File.exist?(@post.path.absolute)
end
test 'no podemos pisar otros archivos' do
# Elegir un post al azar que no sea el que usamos
# rubocop:disable Lint/Loop
begin
post = @site.posts.sample
end until post != @post
# rubocop:enable Lint/Loop
@post.slug.value = post.slug.value
@post.date.value = post.date.value
assert_not @post.save
assert File.exist?(@post.path.absolute)
assert File.exist?(@post.path_was)
end
end