mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-21 17:36:23 +00:00
crear licencias y gestionar correctamente las colecciones por idioma
habia un monton de inconsistencias que hacian que los posts se guardaran en cualquier lado, que empezaron a saltar apenas introdujimos la gestión de licencias
This commit is contained in:
parent
8f22215621
commit
cad881db1c
18 changed files with 110 additions and 76 deletions
16
app/models/metadata_lang.rb
Normal file
16
app/models/metadata_lang.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Un campo de idioma
|
||||
class MetadataLang < MetadataTemplate
|
||||
def default_value
|
||||
I18n.locale
|
||||
end
|
||||
|
||||
def value
|
||||
self[:value] || document.collection.label.to_sym
|
||||
end
|
||||
|
||||
def values
|
||||
I18n.available_locales
|
||||
end
|
||||
end
|
|
@ -28,7 +28,7 @@ class MetadataPath < MetadataTemplate
|
|||
end
|
||||
|
||||
def lang
|
||||
post.lang
|
||||
post.lang.value
|
||||
end
|
||||
|
||||
def slug
|
||||
|
|
|
@ -12,8 +12,8 @@ class Post < OpenStruct
|
|||
# Atributos por defecto
|
||||
DEFAULT_ATTRIBUTES = %i[site document layout].freeze
|
||||
# Otros atributos que no vienen en los metadatos
|
||||
PRIVATE_ATTRIBUTES = %i[lang path slug attributes errors].freeze
|
||||
PUBLIC_ATTRIBUTES = %i[date].freeze
|
||||
PRIVATE_ATTRIBUTES = %i[path slug attributes errors].freeze
|
||||
PUBLIC_ATTRIBUTES = %i[lang date].freeze
|
||||
|
||||
# Redefinir el inicializador de OpenStruct
|
||||
#
|
||||
|
@ -47,6 +47,7 @@ class Post < OpenStruct
|
|||
required: template['required'])
|
||||
end
|
||||
|
||||
load_lang!
|
||||
load_slug!
|
||||
load_date!
|
||||
load_path!
|
||||
|
@ -142,7 +143,7 @@ class Post < OpenStruct
|
|||
FileUtils.rm_f path.absolute
|
||||
|
||||
# TODO: Devolver self en lugar de todo el array
|
||||
site.posts(lang: lang).reject! do |post|
|
||||
site.posts(lang: lang.value).reject! do |post|
|
||||
post.path.absolute == path.absolute
|
||||
end
|
||||
end
|
||||
|
@ -231,6 +232,7 @@ class Post < OpenStruct
|
|||
|
||||
save
|
||||
end
|
||||
alias update update_attributes
|
||||
|
||||
private
|
||||
|
||||
|
@ -292,6 +294,13 @@ class Post < OpenStruct
|
|||
required: true)
|
||||
end
|
||||
|
||||
def load_lang!
|
||||
self.lang = MetadataLang.new(document: document, site: site,
|
||||
layout: layout, name: :lang,
|
||||
type: :lang, post: self,
|
||||
required: true)
|
||||
end
|
||||
|
||||
# Ejecuta la acción de guardado en cada atributo
|
||||
def save_attributes!
|
||||
attributes.map do |attr|
|
||||
|
|
|
@ -15,8 +15,8 @@ class PostRelation < Array
|
|||
# Genera un artículo nuevo con los parámetros que le pasemos y lo suma
|
||||
# al array
|
||||
def build(**args)
|
||||
args[:document] ||= build_document
|
||||
args[:lang] ||= I18n.locale
|
||||
args[:document] ||= build_document(collection: args[:lang])
|
||||
args[:layout] = build_layout(args[:layout])
|
||||
|
||||
post = Post.new(site: site, **args)
|
||||
|
@ -31,12 +31,22 @@ class PostRelation < Array
|
|||
post
|
||||
end
|
||||
|
||||
alias find_generic find
|
||||
|
||||
def find(id)
|
||||
super() do |p|
|
||||
find_generic do |p|
|
||||
p.id == id
|
||||
end
|
||||
end
|
||||
|
||||
# Encuentra el primer post por el valor de un atributo
|
||||
# XXX: Acepta cualquier atributo
|
||||
def find_by(**args)
|
||||
find_generic do |p|
|
||||
p.public_send(args.first.first).try(:value) == args.first.last
|
||||
end
|
||||
end
|
||||
|
||||
# Intenta guardar todos y devuelve true si pudo
|
||||
def save_all
|
||||
map(&:save).all?
|
||||
|
@ -51,14 +61,14 @@ class PostRelation < Array
|
|||
end
|
||||
|
||||
# Devuelve una colección Jekyll que hace pasar el documento
|
||||
def build_collection
|
||||
Jekyll::Collection.new(site.jekyll, 'posts')
|
||||
def build_collection(label:)
|
||||
Jekyll::Collection.new(site.jekyll, label.to_s)
|
||||
end
|
||||
|
||||
# Un documento borrador con algunas propiedades por defecto
|
||||
def build_document
|
||||
doc = Jekyll::Document.new('', site: site.jekyll,
|
||||
collection: build_collection)
|
||||
def build_document(collection:)
|
||||
col = build_collection(label: collection)
|
||||
doc = Jekyll::Document.new('', site: site.jekyll, collection: col)
|
||||
doc.data['date'] = Date.today.to_time
|
||||
doc
|
||||
end
|
||||
|
|
|
@ -8,11 +8,9 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
|
|||
# @return Post
|
||||
def create
|
||||
# TODO: Implementar layout
|
||||
self.post = site.posts.build
|
||||
# TODO: No podemos pasar los post_params a build aun porque para
|
||||
# saber los parámetros tenemos que haber instanciado el post
|
||||
# primero.
|
||||
post.update_attributes(post_params) && commit(action: :created)
|
||||
self.post = site.posts(lang: params[:post][:lang] || I18n.locale).build
|
||||
|
||||
commit(action: :created) if post.update(post_params)
|
||||
|
||||
# Devolver el post aunque no se haya salvado para poder rescatar los
|
||||
# errores
|
||||
|
@ -20,10 +18,7 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
|
|||
end
|
||||
|
||||
def update
|
||||
# TODO: No podemos pasar los post_params a build aun porque para
|
||||
# saber los parámetros tenemos que haber instanciado el post
|
||||
# primero.
|
||||
post.update_attributes(post_params) && commit(action: :updated)
|
||||
commit(action: :updated) if post.update(post_params)
|
||||
|
||||
# Devolver el post aunque no se haya salvado para poder rescatar los
|
||||
# errores
|
||||
|
@ -31,7 +26,9 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
|
|||
end
|
||||
|
||||
def destroy
|
||||
post.destroy! && commit(action: :destroyed)
|
||||
post.destroy!
|
||||
|
||||
commit(action: :destroyed) if post.destroyed?
|
||||
|
||||
post
|
||||
end
|
||||
|
|
|
@ -17,6 +17,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do
|
|||
commit_config(action: :create)
|
||||
end
|
||||
|
||||
add_licencias
|
||||
|
||||
site
|
||||
end
|
||||
|
||||
|
@ -46,5 +48,27 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do
|
|||
site.roles << Rol.new(site: site, usuarie: usuarie,
|
||||
temporal: temporal, rol: rol)
|
||||
end
|
||||
|
||||
# Crea la licencia del sitio para cada locale disponible
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def add_licencias
|
||||
I18n.available_locales.each do |locale|
|
||||
Mobility.with_locale(locale) do
|
||||
params = ActionController::Parameters.new(
|
||||
post: {
|
||||
lang: locale,
|
||||
title: site.licencia.name,
|
||||
author: %w[Sutty],
|
||||
permalink: "#{I18n.t('activerecord.models.licencia').downcase}/",
|
||||
content: site.licencia.deed
|
||||
}
|
||||
)
|
||||
|
||||
PostService.new(site: site, usuarie: usuarie, params: params)
|
||||
.create
|
||||
end
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
end
|
||||
# rubocop:enable Metrics/BlockLength
|
||||
|
|
3
app/views/posts/attribute_ro/_lang.haml
Normal file
3
app/views/posts/attribute_ro/_lang.haml
Normal file
|
@ -0,0 +1,3 @@
|
|||
%tr{ id: attribute }
|
||||
%th= post_label_t(attribute, post: post)
|
||||
%td= t(".#{metadata.value}")
|
2
app/views/posts/attributes/_lang.haml
Normal file
2
app/views/posts/attributes/_lang.haml
Normal file
|
@ -0,0 +1,2 @@
|
|||
-# TODO: Implementar i18n
|
||||
= hidden_field 'post[lang]', I18n.locale
|
|
@ -59,6 +59,7 @@ en:
|
|||
activerecord:
|
||||
models:
|
||||
usuarie: User
|
||||
licencia: License
|
||||
attributes:
|
||||
usuarie:
|
||||
email: 'E-mail address'
|
||||
|
|
|
@ -61,6 +61,7 @@ es:
|
|||
activerecord:
|
||||
models:
|
||||
usuarie: Usuarie
|
||||
licencia: Licencia
|
||||
attributes:
|
||||
usuarie:
|
||||
email: 'Correo electrónico'
|
||||
|
|
|
@ -5,7 +5,7 @@ designs = YAML.safe_load(File.read('db/seeds/designs.yml'))
|
|||
designs.each do |d|
|
||||
design = Design.find_or_create_by(gem: d['gem'])
|
||||
|
||||
design.update_attributes d
|
||||
design.update d
|
||||
end
|
||||
|
||||
licencias = YAML.safe_load(File.read('db/seeds/licencias.yml'))
|
||||
|
@ -13,7 +13,7 @@ licencias = YAML.safe_load(File.read('db/seeds/licencias.yml'))
|
|||
licencias.each do |l|
|
||||
licencia = Licencia.find_or_create_by(icons: l['icons'])
|
||||
|
||||
licencia.update_attributes l
|
||||
licencia.update l
|
||||
end
|
||||
|
||||
YAML.safe_load(File.read('db/seeds/sites.yml')).each do |site|
|
||||
|
|
|
@ -7,14 +7,6 @@
|
|||
description_en: 'The Peer Production License is a license that allows use for any purpose under the same terms, except for commercial purposes, which are only allowed for collectives, cooperatives and other worker-owned "enterprises". We recommend this license if you are inclined towards non-profit terms, since it allows the development of more ethical economies while fending off capitalistic for-profit uses. If you want to know more about it, we invite you to read [The Telekommunist Manifesto](http://networkcultures.org/blog/publication/no-03-the-telekommunist-manifesto-dmytri-kleiner/)'
|
||||
description_es: 'La licencia de Producción de Pares permite el uso con cualquier propósito bajo la misma licencia, a excepción de los usos comerciales que solo están permitidos a colectivos, cooperativas y otras "empresas" en manos de sus trabajadorxs. Recomendamos esta licencia si te estabas inclinando hacia términos sin fines de lucro, ya que permite el desarrollo de economías más éticas al mismo tiempo que impide la explotación capitalista. Si te interesa saber más, te invitamos a leer [El manifiesto telecomunista](https://endefensadelsl.org/manifiesto_telecomunista.html).'
|
||||
deed_en: |
|
||||
---
|
||||
title: License
|
||||
permalink: license/
|
||||
layout: post
|
||||
---
|
||||
|
||||
# Peer Production License (human-readable version)
|
||||
|
||||
This is a human-readable summary of the [full
|
||||
license](https://wiki.p2pfoundation.net/Peer_Production_License).
|
||||
|
||||
|
@ -54,14 +46,6 @@
|
|||
such as publicity, privacy, or moral rights may limit how you use the
|
||||
material.
|
||||
deed_es: |
|
||||
---
|
||||
title: Licencia
|
||||
permalink: licencia/
|
||||
layout: post
|
||||
---
|
||||
|
||||
# Licencia de producción de pares (versión legible por humanas)
|
||||
|
||||
Esto es un resumen legible por humanas del [texto legal (la licencia
|
||||
completa)](http://endefensadelsl.org/ppl_es.html)
|
||||
|
||||
|
@ -113,7 +97,7 @@
|
|||
hacerlo es enlazar a esta página.
|
||||
|
||||
- icons: "/images/by.png"
|
||||
name_en: 'Attribution 4.0 International (CC BY 4.0)'
|
||||
name_en: 'Creative Commons Attribution 4.0 International (CC BY 4.0)'
|
||||
description_en: "This license gives everyone the freedom to use,
|
||||
adapt, and redistribute the contents of your site by requiring
|
||||
attribution only. We recommend this license if you're publishing
|
||||
|
@ -121,7 +105,7 @@
|
|||
you want to be attributed. Users of the site will have to mention the
|
||||
source and indicate if they made changes to it."
|
||||
url_en: 'https://creativecommons.org/licenses/by/4.0/'
|
||||
name_es: 'Atribución 4.0 Internacional (CC BY 4.0)'
|
||||
name_es: 'Creative Commons Atribución 4.0 Internacional (CC BY 4.0)'
|
||||
description_es: "Esta licencia permite a todes la libertad de usar,
|
||||
adaptar/modificar y redistribuir los contenidos de tu sitio con la
|
||||
única condición de atribuirte la autoría original. Recomendamos esta
|
||||
|
@ -131,12 +115,6 @@
|
|||
indicar si hicieron cambios."
|
||||
url_es: 'https://creativecommons.org/licenses/by/4.0/deed.es'
|
||||
deed_en: |
|
||||
---
|
||||
title: License
|
||||
permalink: license/
|
||||
layout: post
|
||||
---
|
||||
|
||||
This is a human-readable summary of (and not a substitute for) the
|
||||
[license](https://creativecommons.org/licenses/by/4.0/legalcode).
|
||||
|
||||
|
@ -173,12 +151,6 @@
|
|||
such as publicity, privacy, or moral rights may limit how you use the
|
||||
material.
|
||||
deed_es: |
|
||||
---
|
||||
title: Licencia
|
||||
permalink: licencia/
|
||||
layout: post
|
||||
---
|
||||
|
||||
Este es un resumen legible por humanes (y no un sustituto) de la
|
||||
[licencia](https://creativecommons.org/licenses/by/4.0/legalcode).
|
||||
|
||||
|
@ -215,8 +187,8 @@
|
|||
publicidad, privacidad, o derechos morales pueden limitar la forma en que
|
||||
utilice el material.
|
||||
- icons: "/images/sa.png"
|
||||
name_en: "Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)"
|
||||
name_es: "Atribución-CompartirIgual 4.0 Internacional (CC BY-SA 4.0)"
|
||||
name_en: "Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)"
|
||||
name_es: "Creative Commons Atribución-CompartirIgual 4.0 Internacional (CC BY-SA 4.0)"
|
||||
url_en: 'https://creativecommons.org/licenses/by-sa/4.0/'
|
||||
url_es: 'https://creativecommons.org/licenses/by-sa/4.0/deed.es'
|
||||
description_en: "This license is the same as the CC-BY 4.0 but it adds
|
||||
|
@ -232,12 +204,6 @@
|
|||
están permitidos, las mejoras hechas con fines de lucro deben ser
|
||||
compartidas bajo la misma licencia."
|
||||
deed_en: |
|
||||
---
|
||||
title: License
|
||||
permalink: license/
|
||||
layout: post
|
||||
---
|
||||
|
||||
This is a human-readable summary of (and not a substitute for) the
|
||||
[license](https://creativecommons.org/licenses/by-sa/4.0/legalcode).
|
||||
|
||||
|
@ -279,12 +245,6 @@
|
|||
such as publicity, privacy, or moral rights may limit how you use the
|
||||
material.
|
||||
deed_es: |
|
||||
---
|
||||
title: Licencia
|
||||
permalink: licencia/
|
||||
layout: post
|
||||
---
|
||||
|
||||
Este es un resumen legible por humanes (y no un sustituto) de la
|
||||
[licencia](https://creativecommons.org/licenses/by/4.0/legalcode).
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ module Api
|
|||
|
||||
test 'se puede obtener un listado de todos' do
|
||||
get v1_sites_url, headers: @authorization, as: :json
|
||||
assert_equal [@site.name], JSON.parse(response.body)
|
||||
assert_equal Site.all.pluck(:name), JSON.parse(response.body)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ class PostsControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
# TODO: implementar reload?
|
||||
site = Site.find(@site.id)
|
||||
new_post = site.posts.first
|
||||
new_post = site.posts.find_by(title: title)
|
||||
|
||||
assert_equal 302, response.status
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class SitesControllerTest < ActionDispatch::IntegrationTest
|
|||
|
||||
test 'se pueden crear' do
|
||||
name = SecureRandom.hex
|
||||
design = create :design
|
||||
design = Design.all.sample
|
||||
|
||||
post sites_url, headers: @authorization, params: {
|
||||
site: {
|
||||
|
@ -40,7 +40,7 @@ class SitesControllerTest < ActionDispatch::IntegrationTest
|
|||
title: name,
|
||||
description: name * 2,
|
||||
design_id: design.id,
|
||||
licencia_id: create(:licencia).id,
|
||||
licencia_id: Licencia.first.id,
|
||||
deploys_attributes: {
|
||||
'0' => {
|
||||
type: 'DeployLocal'
|
||||
|
@ -62,8 +62,15 @@ class SitesControllerTest < ActionDispatch::IntegrationTest
|
|||
assert_equal design.gem, site.config.theme
|
||||
assert_equal name, site.config.title
|
||||
assert_equal name * 2, site.config.description
|
||||
assert_equal I18n.t('site_service.create', name: name),
|
||||
site.repository.rugged.head.target.message
|
||||
|
||||
# TODO: Esto requiere que podamos buscar hacia atrás en la historia
|
||||
# del repositorio
|
||||
# assert_equal I18n.t('site_service.create', name: name),
|
||||
# site.repository.rugged.head.target.message
|
||||
|
||||
I18n.available_locales.each do |locale|
|
||||
assert_equal 3, site.posts(lang: locale).size
|
||||
end
|
||||
|
||||
site.destroy
|
||||
end
|
||||
|
|
|
@ -42,6 +42,8 @@ class PostTest < ActiveSupport::TestCase
|
|||
|
||||
if metadata.empty?
|
||||
assert_not @post.document.data[attr.to_s].present?
|
||||
elsif metadata.type == :lang
|
||||
assert @post.path.relative.starts_with?("_#{metadata.value}/")
|
||||
elsif @post.document.respond_to? attr
|
||||
assert_equal metadata.value, @post.document.send(attr), attr
|
||||
else
|
||||
|
|
|
@ -60,7 +60,7 @@ class SiteTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test 'se puede leer un sitio' do
|
||||
site = create :site, name: 'sutty.nl'
|
||||
site = create :site
|
||||
|
||||
assert site.valid?
|
||||
assert !site.posts.empty?
|
||||
|
@ -87,10 +87,10 @@ class SiteTest < ActiveSupport::TestCase
|
|||
end
|
||||
|
||||
test 'el sitio tiene artículos en distintos idiomas' do
|
||||
site = create :site, name: 'sutty.nl'
|
||||
@site = create :site
|
||||
|
||||
I18n.available_locales.each do |locale|
|
||||
assert site.posts(lang: locale).size.positive?
|
||||
assert @site.posts(lang: locale).size.positive?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,6 +5,8 @@ require 'rails/test_help'
|
|||
require 'open3'
|
||||
require 'sucker_punch/testing/inline'
|
||||
|
||||
Rails.application.load_seed
|
||||
|
||||
# rubocop:disable Style/ClassAndModuleChildren
|
||||
class ActiveSupport::TestCase
|
||||
include FactoryBot::Syntax::Methods
|
||||
|
|
Loading…
Reference in a new issue