diff --git a/.rubocop.yml b/.rubocop.yml
index f9765ba7..8df03292 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -44,6 +44,7 @@ Metrics/ClassLength:
Exclude:
- 'app/models/site.rb'
- 'app/controllers/posts_controller.rb'
+ - 'app/controllers/sites_controller.rb'
Lint/HandleExceptions:
Exclude:
diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb
index d13d3030..c5008abd 100644
--- a/app/controllers/sites_controller.rb
+++ b/app/controllers/sites_controller.rb
@@ -23,6 +23,9 @@ class SitesController < ApplicationController
def new
@site = Site.new
authorize @site
+
+ @site.deploys.build type: 'DeployLocal'
+ @site.deploys.build type: 'DeployZip'
end
def create
@@ -137,6 +140,10 @@ class SitesController < ApplicationController
private
def site_params
- params.require(:site).permit(:name, :design_id, :licencia_id)
+ params.require(:site)
+ .permit(:name, :design_id, :licencia_id,
+ deploys_attributes: %i[
+ type id _destroy
+ ])
end
end
diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb
index 8ff40db3..10c21bd3 100644
--- a/app/models/deploy_local.rb
+++ b/app/models/deploy_local.rb
@@ -57,7 +57,7 @@ class DeployLocal < Deploy
end
def fqdn!
- self.fqdn ||= "#{site.name}.#{ENV.fetch('SUTTY', 'sutty.nl')}"
+ self.fqdn ||= "#{site.name}.#{Site.domain}"
end
def destination!
diff --git a/app/models/deploy_zip.rb b/app/models/deploy_zip.rb
index 6804bb28..0ec8afcc 100644
--- a/app/models/deploy_zip.rb
+++ b/app/models/deploy_zip.rb
@@ -30,7 +30,7 @@ class DeployZip < Deploy
# Copiamos de DeployLocal para no cargar todos los métodos de
# compilación...
def fqdn!
- self.fqdn ||= "#{site.name}.#{ENV.fetch('SUTTY', 'sutty.nl')}"
+ self.fqdn ||= "#{site.name}.#{Site.domain}"
end
def destination!
diff --git a/app/models/site.rb b/app/models/site.rb
index bd3f01ed..3235f3a7 100644
--- a/app/models/site.rb
+++ b/app/models/site.rb
@@ -8,6 +8,8 @@ class Site < ApplicationRecord
validates :name, uniqueness: true, hostname: true
validates :design_id, presence: true
+ validate :deploy_local_presence
+
friendly_id :name, use: %i[finders]
belongs_to :design
@@ -33,6 +35,8 @@ class Site < ApplicationRecord
attr_accessor :jekyll, :collections
+ accepts_nested_attributes_for :deploys, allow_destroy: true
+
# El repositorio git para este sitio
def repository
@repository ||= Site::Repository.new path
@@ -370,6 +374,10 @@ class Site < ApplicationRecord
Jekyll::Site.new(config)
end
+ def self.domain
+ ENV.fetch('SUTTY', 'sutty.nl')
+ end
+
private
# Clona el esqueleto de Sutty para crear el sitio nuevo, no pasa nada
@@ -399,4 +407,17 @@ class Site < ApplicationRecord
FileUtils.mv old_path, path
end
+
+ # Valida si el sitio tiene al menos una forma de alojamiento asociada
+ # y es la local
+ #
+ # TODO: Volver opcional el alojamiento local, pero ahora mismo está
+ # atado a la generación del sitio así que no puede faltar
+ def deploy_local_presence
+ # Usamos size porque queremos saber la cantidad de deploys sin
+ # guardar también
+ return if deploys.size.positive? && deploys.map(&:type).include?('DeployLocal')
+
+ errors.add(:deploys, I18n.t('activerecord.errors.models.site.attributes.deploys.deploy_local_presence'))
+ end
end
diff --git a/app/views/deploys/_deploy_local.haml b/app/views/deploys/_deploy_local.haml
new file mode 100644
index 00000000..8c5f34e8
--- /dev/null
+++ b/app/views/deploys/_deploy_local.haml
@@ -0,0 +1,14 @@
+-#
+ Formulario para alojamiento local. Como el alojamiento local no es
+ opcional aun, solo enviamos el tipo con el formulario, no necesitamos
+ nada más.
+
+.row
+ .col
+ %h3= t('.title')
+ - name = site.name || t('.ejemplo')
+ = sanitize_markdown t('.help',
+ fqdn: deploy.object.fqdn || "#{name}.#{Site.domain}"),
+ tags: %w[p strong em a]
+
+ = deploy.hidden_field :type
diff --git a/app/views/deploys/_deploy_zip.haml b/app/views/deploys/_deploy_zip.haml
new file mode 100644
index 00000000..11996b0e
--- /dev/null
+++ b/app/views/deploys/_deploy_zip.haml
@@ -0,0 +1,21 @@
+-# Formulario para "alojar" en un zip
+
+.row
+ .col
+ = deploy.hidden_field :id
+ = deploy.hidden_field :type
+ %h3
+ -#
+ El checkbox invierte la lógica de destrucción porque queremos
+ crear el deploy si está activado y destruirlo si está
+ desactivado.
+ = deploy.check_box :_destroy,
+ { checked: deploy.object.persisted? },
+ '0', '1'
+ = deploy.label :_destroy, t('.title')
+ -# TODO: secar la generación de URLs
+ - name = site.name || t('.ejemplo')
+ = sanitize_markdown t('.help',
+ fqdn: deploy.object.fqdn || "#{name}.#{Site.domain}",
+ file: deploy.object.file || "#{name}.zip"),
+ tags: %w[p strong em a]
diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml
index db9808c5..734e1e2c 100644
--- a/app/views/sites/_form.haml
+++ b/app/views/sites/_form.haml
@@ -46,5 +46,14 @@
%hr/
+ .form-group
+ %h2= t('.deploys.title')
+ %p.lead= t('.help.deploys')
+
+ = f.fields_for :deploys do |deploy|
+ = render "deploys/#{deploy.object.type.underscore}",
+ deploy: deploy, site: site
+ %hr/
+
.form-group
= f.submit submit, class: 'btn btn-success'
diff --git a/config/locales/es.yml b/config/locales/es.yml
index b3a248c2..5878d288 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -11,6 +11,10 @@ es:
name: 'Nombre'
errors:
models:
+ site:
+ attributes:
+ deploys:
+ deploy_local_presence: '¡Necesitamos poder generar el sitio!'
invitadx:
attributes:
email:
@@ -145,6 +149,25 @@ es:
lang: 'Idioma'
logout: 'Salir'
error: 'Hubo un error al iniciar la sesión. ¿Escribiste bien tus credenciales?'
+ deploys:
+ deploy_local:
+ title: 'Alojar en Sutty'
+ help: |
+ El sitio estará disponible en .
+
+ Estamos desarrollando la posibilidad de agregar tus propios
+ dominios, ¡ayudanos!
+ ejemplo: 'ejemplo'
+ deploy_zip:
+ title: 'Generar un archivo ZIP'
+ help: |
+ Los archivos ZIP contienen y comprimen todos los archivos de tu
+ sitio. Con esta opción podrás descargar y compartir tu sitio
+ entero a través de la dirección y
+ guardarla como copia de seguridad o una estrategia de
+ alojamiento solidario, donde muchas personas comparten una copia
+ de tu sitio.
+ ejemplo: 'ejemplo'
sites:
actions: 'Acciones'
posts: 'Ver y editar artículos'
@@ -171,6 +194,11 @@ es:
de autore. Esto significa que nadie puede hacer uso de nuestras
obras sin permiso explícito. Con las licencias establecemos
condiciones bajo las que queremos compartir.'
+ deploys: |
+ Sutty te permite alojar tu sitio en distintos lugares al mismo
+ tiempo. Esta estrategia facilita que el sitio esté disponible
+ aun cuando algunos de los alojamientos no funcionen.
+
design:
title: 'Diseño'
actions: 'Información sobre este diseño'
@@ -179,6 +207,8 @@ es:
licencia:
title: 'Licencia del sitio y todo lo que se publique'
url: 'Leer la licencia'
+ deploys:
+ title: '¿Dónde querés alojar tu sitio?'
fetch:
title: 'Actualizar el sitio'
help:
diff --git a/test/controllers/sites_controller_test.rb b/test/controllers/sites_controller_test.rb
index 5796ea9c..72d3ebc9 100644
--- a/test/controllers/sites_controller_test.rb
+++ b/test/controllers/sites_controller_test.rb
@@ -35,13 +35,40 @@ class SitesControllerTest < ActionDispatch::IntegrationTest
site: {
name: name,
design_id: create(:design).id,
- licencia_id: create(:licencia).id
+ licencia_id: create(:licencia).id,
+ deploys_attributes: {
+ '0' => {
+ type: 'DeployLocal'
+ }
+ }
}
}
- assert_nothing_raised do
- site = Site.find_by_name(name)
- site.destroy
+ site = Site.find_by_name(name)
+
+ assert site
+ assert_equal @usuarie.email, site.roles.first.usuarie.email
+ assert_equal 'usuarie', site.roles.first.rol
+
+ site.destroy
+ end
+
+ test 'no se pueden crear con cualquier deploy' do
+ name = SecureRandom.hex
+
+ assert_raise ActiveRecord::SubclassNotFound do
+ post sites_url, headers: @authorization, params: {
+ site: {
+ name: name,
+ design_id: create(:design).id,
+ licencia_id: create(:licencia).id,
+ deploys_attributes: {
+ '0' => {
+ type: 'DeployNoExiste'
+ }
+ }
+ }
+ }
end
end
end
diff --git a/test/factories/site.rb b/test/factories/site.rb
index 95cce4e8..f59221e3 100644
--- a/test/factories/site.rb
+++ b/test/factories/site.rb
@@ -5,5 +5,13 @@ FactoryBot.define do
name { "test-#{SecureRandom.hex}" }
design
licencia
+
+ after :build do |site|
+ site.deploys << build(:deploy_local, site: site)
+ end
+
+ after :create do |site|
+ site.deploys << create(:deploy_local, site: site)
+ end
end
end