generar el sitio utilizando sidekiq

This commit is contained in:
f 2019-07-25 21:36:33 -03:00
parent 7ed08f8a0d
commit b149374c41
No known key found for this signature in database
GPG key ID: 2AE5A13E321F953D
17 changed files with 273 additions and 48 deletions

View file

@ -3,3 +3,6 @@ IMAP_SERVER=
DEFAULT_FROM= DEFAULT_FROM=
DEVISE_PEPPER= DEVISE_PEPPER=
SKEL_SUTTY=https://0xacab.org/sutty/skel.sutty.nl SKEL_SUTTY=https://0xacab.org/sutty/skel.sutty.nl
SUTTY=sutty.nl
REDIS_SERVER=
REDIS_CLIENT=

View file

@ -47,6 +47,7 @@ gem 'exception_notification'
gem 'font-awesome-rails' gem 'font-awesome-rails'
gem 'friendly_id' gem 'friendly_id'
gem 'hamlit-rails' gem 'hamlit-rails'
gem 'hiredis'
gem 'jekyll' gem 'jekyll'
gem 'jquery-rails' gem 'jquery-rails'
gem 'mini_magick' gem 'mini_magick'
@ -54,8 +55,12 @@ gem 'mobility'
gem 'pundit' gem 'pundit'
gem 'rails-i18n' gem 'rails-i18n'
gem 'rails_warden' gem 'rails_warden'
gem 'redis', require: %w[redis redis/connection/hiredis]
gem 'redis-rails'
gem 'rubyzip' gem 'rubyzip'
gem 'rugged' gem 'rugged'
gem 'sidekiq'
gem 'terminal-table'
gem 'validates_hostname' gem 'validates_hostname'
gem 'whenever', require: false gem 'whenever', require: false

View file

@ -97,6 +97,7 @@ GEM
commonmarker (0.18.2) commonmarker (0.18.2)
ruby-enum (~> 0.5) ruby-enum (~> 0.5)
concurrent-ruby (1.1.5) concurrent-ruby (1.1.5)
connection_pool (2.2.2)
crass (1.0.4) crass (1.0.4)
database_cleaner (1.7.0) database_cleaner (1.7.0)
devise (4.6.2) devise (4.6.2)
@ -161,6 +162,7 @@ GEM
activesupport (>= 4.0.1) activesupport (>= 4.0.1)
hamlit (>= 1.2.0) hamlit (>= 1.2.0)
railties (>= 4.0.1) railties (>= 4.0.1)
hiredis (0.6.3)
http_parser.rb (0.6.0) http_parser.rb (0.6.0)
i18n (0.9.5) i18n (0.9.5)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
@ -242,6 +244,8 @@ GEM
pundit (2.0.1) pundit (2.0.1)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
rack (2.0.6) rack (2.0.6)
rack-protection (2.0.5)
rack
rack-test (1.1.0) rack-test (1.1.0)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
rails (5.2.3) rails (5.2.3)
@ -280,6 +284,23 @@ GEM
ffi (~> 1.0) ffi (~> 1.0)
rbnacl (4.0.2) rbnacl (4.0.2)
ffi ffi
redis (4.1.2)
redis-actionpack (5.0.2)
actionpack (>= 4.0, < 6)
redis-rack (>= 1, < 3)
redis-store (>= 1.1.0, < 2)
redis-activesupport (5.0.7)
activesupport (>= 3, < 6)
redis-store (>= 1.3, < 2)
redis-rack (2.0.5)
rack (>= 1.5, < 3)
redis-store (>= 1.2, < 2)
redis-rails (5.0.2)
redis-actionpack (>= 5.0, < 6)
redis-activesupport (>= 5.0, < 6)
redis-store (>= 1.2, < 2)
redis-store (1.6.0)
redis (>= 2.2, < 5)
request_store (1.4.1) request_store (1.4.1)
rack (>= 1.4) rack (>= 1.4)
responders (3.0.0) responders (3.0.0)
@ -326,6 +347,11 @@ GEM
selenium-webdriver (3.141.0) selenium-webdriver (3.141.0)
childprocess (~> 0.5) childprocess (~> 0.5)
rubyzip (~> 1.2, >= 1.2.2) rubyzip (~> 1.2, >= 1.2.2)
sidekiq (5.2.7)
connection_pool (~> 2.2, >= 2.2.2)
rack (>= 1.5.0)
rack-protection (>= 1.5.0)
redis (>= 3.3.5, < 5)
simpleidn (0.1.1) simpleidn (0.1.1)
unf (~> 0.1.4) unf (~> 0.1.4)
spring (2.0.2) spring (2.0.2)
@ -346,6 +372,8 @@ GEM
net-ssh (>= 2.8.0) net-ssh (>= 2.8.0)
sysexits (1.2.0) sysexits (1.2.0)
temple (0.8.1) temple (0.8.1)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thor (0.20.3) thor (0.20.3)
thread_safe (0.3.6) thread_safe (0.3.6)
tilt (2.0.9) tilt (2.0.9)
@ -408,6 +436,7 @@ DEPENDENCIES
friendly_id friendly_id
haml-lint haml-lint
hamlit-rails hamlit-rails
hiredis
jbuilder (~> 2.5) jbuilder (~> 2.5)
jekyll jekyll
jquery-rails jquery-rails
@ -422,14 +451,18 @@ DEPENDENCIES
rails-i18n rails-i18n
rails_warden rails_warden
rbnacl (< 5.0) rbnacl (< 5.0)
redis
redis-rails
rubocop-rails rubocop-rails
rubyzip rubyzip
rugged rugged
sass-rails (~> 5.0) sass-rails (~> 5.0)
selenium-webdriver selenium-webdriver
sidekiq
spring spring
spring-watcher-listen (~> 2.0.0) spring-watcher-listen (~> 2.0.0)
sqlite3 (~> 1.3.6) sqlite3 (~> 1.3.6)
terminal-table
turbolinks (~> 5) turbolinks (~> 5)
uglifier (>= 1.3.0) uglifier (>= 1.3.0)
validates_hostname validates_hostname

BIN
app/assets/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2 KiB

View file

@ -1,6 +1,17 @@
# frozen_string_literal: true # frozen_string_literal: true
# Configuración base del correo
class ApplicationMailer < ActionMailer::Base class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com' helper :application
before_action :inline_logo!
default from: ENV.fetch('DEFAULT_FROM', "noreply@#{Site.domain}")
layout 'mailer' layout 'mailer'
private
def inline_logo!
attachments.inline['logo.png'] ||=
File.read('app/assets/images/logo.png')
end
end end

View file

@ -0,0 +1,28 @@
# frozen_string_literal: true
# Notifica a les usuaries cuando un sitio se generó con éxito
#
# XXX: No será mejor enviarles un correo con copia?
# TODO: Agregar headers de desuscripción de notificaciones cuando
# tengamos opciones de usuarie
# TODO: Agregar firma GPG y header Autocrypt
# TODO: Cifrar con GPG si le usuarie nos dio su llave
class DeployMailer < ApplicationMailer
# rubocop:disable Metrics/AbcSize
def deployed(which_ones)
@usuarie = Usuarie.find(params[:usuarie])
@site = @usuarie.sites.find(params[:site])
@deploys = which_ones
@deploy_local = @site.deploys.find_by(type: 'DeployLocal')
# Informamos a cada quien en su idioma y damos una dirección de
# respuesta porque a veces les usuaries nos escriben
I18n.with_locale(@usuarie.lang) do
mail(to: @usuarie.email,
reply_to: "sutty@#{Site.domain}",
subject: I18n.t('mailers.deploy_mailer.deployed.subject',
site: @site.name))
end
end
# rubocop:enable Metrics/AbcSize
end

View file

@ -0,0 +1,17 @@
%h1= t('.hi')
= sanitize_markdown t('.explanation', fqdn: @deploy_local.fqdn),
tags: %w[p a strong em]
%table
%thead
%tr
%th= t('.th.type')
%th= t('.th.status')
%tbody
- @deploys.each do |deploy, value|
%tr
%td= t(".#{deploy}.title")
%td= value ? t(".#{deploy}.success") : t(".#{deploy}.error")
= sanitize_markdown t('.help'), tags: %w[p a strong em]

View file

@ -0,0 +1,12 @@
= "# #{t('.hi')}"
\
= t('.explanation', fqdn: @deploy_local.fqdn)
\
= Terminal::Table.new do |table|
- table << [t('.th.type'), t('.th.status')]
- table.add_separator
- @deploys.each do |deploy, value|
- table << [t(".#{deploy}.title"),
value ? t(".#{deploy}.success") : t(".#{deploy}.error")]
\
= t('.help')

View file

@ -1,8 +0,0 @@
!!!
%html
%head
%meta{:content => "text/html; charset=utf-8", "http-equiv" => "Content-Type"}/
:css
/* Email styles need to be inline */
%body
= yield

View file

@ -1,3 +1,12 @@
!!!
%html %html
%head
%meta{ content: 'text/html; charset=utf-8',
'http-equiv': 'Content-Type' }/
:css
/* Inline */
%body %body
= yield = yield
= image_tag attachments['logo.png'].url, alt: 'Logo de Sutty'
= t('.signature')

View file

@ -1 +1,3 @@
= yield = yield
= t('.signature')

View file

@ -0,0 +1,39 @@
# frozen_string_literal: true
# Realiza el deploy de un sitio
class DeployWorker
include Sidekiq::Worker
def perform(site)
site = Site.find(site)
# Asegurarse que DeployLocal sea el primero!
deployed = { deploy_local: deploy_local(site) }
# No es opcional
raise unless deployed[:deploy_local]
deploy_others site, deployed
notify_usuaries site, deployed
end
private
def deploy_local(site)
site.deploys.find_by(type: 'DeployLocal').deploy
end
def deploy_others(site, deployed)
site.deploys.where.not(type: 'DeployLocal').find_each do |d|
deployed[d.type.underscore.to_sym] = d.deploy
end
end
def notify_usuaries(site, deployed)
# TODO: existe site.usuaries_ids?
site.usuaries.find_each do |usuarie|
DeployMailer.with(usuarie: usuarie.id, site: site.id)
.deployed(deployed)
.deliver_now
end
end
end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
Sidekiq.configure_server do |config|
config.redis = {
url: ENV.fetch('REDIS_SERVER', 'redis://localhost:6379/1')
}
end
Sidekiq.configure_client do |config|
config.redis = {
url: ENV.fetch('REDIS_CLIENT', 'redis://localhost:6379/1')
}
end

View file

@ -1,5 +1,35 @@
en: en:
deploy_mailer:
deployed:
subject: "[Sutty] The site %{site} has been built"
hi: "Hi!"
explanation: |
This e-mail is to notify you that Sutty has built your site and
it's available at <https://%{fqdn}>.
You'll find details bellow.
th:
type: Type
status: Status
deploy_local:
title: Build the site
success: Success!
error: Error
deploy_zip:
title: Build ZIP file
success: Available for download
error: Error
help: You can contact us by replying this e-mail
activerecord: activerecord:
models:
usuarie: User
attributes:
usuarie:
email: 'E-mail address'
password: 'Password'
password_confirmation: 'Password confirmation'
site:
name: 'Name'
errors: errors:
models: models:
site: site:
@ -22,6 +52,8 @@ en:
disordered: "The posts are disordered, this will prevent you from reordering them!" disordered: "The posts are disordered, this will prevent you from reordering them!"
disordered_button: 'Reorder!' disordered_button: 'Reorder!'
layouts: layouts:
mailer:
signature: 'With love, Sutty'
breadcrumb: breadcrumb:
help: Help help: Help
collaborations: collaborations:
@ -29,19 +61,6 @@ en:
submit: Register submit: Register
password: password:
incorrect: 'Wrong password, please try again.' incorrect: 'Wrong password, please try again.'
invitadxs:
index:
title: 'Guests'
new:
email: 'E-Mail'
password: 'Password'
password_confirmation: 'Repeat password'
submit: 'Register'
acepta_politicas_de_privacidad: 'I accept the <a href="%{privacy_policy}" target="_blank">Privacy policy</a>.'
confirmation:
confirmed: 'Your account is confirmed, please log in to continue'
show:
confirmation_sent: "We've sent a confirmation link to your e-mail address. Please open that link to continue."
info: info:
posts: posts:
reorder: 'The articles have been reordered!' reorder: 'The articles have been reordered!'
@ -79,27 +98,6 @@ en:
sesiones: 'Sessions' sesiones: 'Sessions'
anexo: 'Appendix' anexo: 'Appendix'
simple: 'Simple' simple: 'Simple'
deploys:
deploy_local:
title: 'Host at Sutty'
help: |
The site will be available at <https://%{fqdn}/>.
We're working out the details for allowing your own site
domains, you can help us!
ejemplo: 'example'
deploy_zip:
title: 'Generate a ZIP file'
help: |
ZIP files contain and compress all the files of your site. With
this option you can download and also share your whole site
through the <https://%{fqdn}/%{file}> address, keep it as backup
or have an strategy of solidarity hosting, were many people
shares a copy of your site.
It also helps with site archival for historical purposes :)
ejemplo: 'ejemplo'
sites: sites:
index: 'This is the list of sites you can edit.' index: 'This is the list of sites you can edit.'
edit_translations: "You can edit texts from your site other than edit_translations: "You can edit texts from your site other than
@ -165,6 +163,27 @@ en:
logout: 'Log out' logout: 'Log out'
lang: 'Language' lang: 'Language'
error: 'There was an error during log in. Did you type your credentials correctly?' error: 'There was an error during log in. Did you type your credentials correctly?'
deploys:
deploy_local:
title: 'Host at Sutty'
help: |
The site will be available at <https://%{fqdn}/>.
We're working out the details for allowing your own site
domains, you can help us!
ejemplo: 'example'
deploy_zip:
title: 'Generate a ZIP file'
help: |
ZIP files contain and compress all the files of your site. With
this option you can download and also share your whole site
through the <https://%{fqdn}/%{file}> address, keep it as backup
or have an strategy of solidarity hosting, were many people
shares a copy of your site.
It also helps with site archival for historical purposes :)
ejemplo: 'example'
sites: sites:
actions: 'Actions' actions: 'Actions'
posts: 'View and edit posts' posts: 'View and edit posts'
@ -218,10 +237,6 @@ en:
message: 'Skeleton upgrade' message: 'Skeleton upgrade'
footer: footer:
powered_by: 'is developed by' powered_by: 'is developed by'
templates:
index: 'Templates'
edit: 'Edit'
save: 'Save'
i18n: i18n:
index: 'Translations' index: 'Translations'
edit: 'Edit texts and translations' edit: 'Edit texts and translations'

View file

@ -1,4 +1,25 @@
es: es:
deploy_mailer:
deployed:
subject: "[Sutty] El sitio %{site} ha sido generado"
hi: "¡Hola!"
explanation: |
Este correo es para notificarte que Sutty ha generado tu sitio y
ya está disponible en la dirección <https://%{fqdn}>.
A continuación encontrarás el detalle de lo que hicimos.
th:
type: Tipo
status: Estado
deploy_local:
title: Generar el sitio
success: ¡Éxito!
error: Hubo un error
deploy_zip:
title: Generar archivo ZIP
success: Disponible para descargar
error: Hubo un error
help: Por cualquier duda, responde este correo para contactarte con nosotres.
activerecord: activerecord:
models: models:
usuarie: Usuarie usuarie: Usuarie
@ -31,6 +52,8 @@ es:
disordered: 'Los artículos no tienen número de orden, esto impedirá que los puedas reordenar' disordered: 'Los artículos no tienen número de orden, esto impedirá que los puedas reordenar'
disordered_button: '¡Reordenar!' disordered_button: '¡Reordenar!'
layouts: layouts:
mailer:
signature: 'Con cariño, Sutty'
breadcrumb: breadcrumb:
help: Ayuda help: Ayuda
collaborations: collaborations:
@ -200,7 +223,6 @@ es:
Sutty te permite alojar tu sitio en distintos lugares al mismo Sutty te permite alojar tu sitio en distintos lugares al mismo
tiempo. Esta estrategia facilita que el sitio esté disponible tiempo. Esta estrategia facilita que el sitio esté disponible
aun cuando algunos de los alojamientos no funcionen. aun cuando algunos de los alojamientos no funcionen.
design: design:
title: 'Diseño' title: 'Diseño'
actions: 'Información sobre este diseño' actions: 'Información sobre este diseño'

View file

@ -4,6 +4,9 @@ require File.expand_path('../config/environment', __dir__)
require 'rails/test_help' require 'rails/test_help'
require 'open3' require 'open3'
require 'sidekiq/testing'
Sidekiq::Testing.inline!
# rubocop:disable Style/ClassAndModuleChildren # rubocop:disable Style/ClassAndModuleChildren
class ActiveSupport::TestCase class ActiveSupport::TestCase
include FactoryBot::Syntax::Methods include FactoryBot::Syntax::Methods

View file

@ -0,0 +1,21 @@
# frozen_string_literal: true
class DeployWorkerTest < ActiveSupport::TestCase
test 'se puede compilar' do
rol = create :rol
site = rol.site
site.deploys << create(:deploy_zip, site: site)
site.save
DeployWorker.perform_async(site.id)
assert_not ActionMailer::Base.deliveries.empty?
site.deploys.each do |d|
assert File.exist?(d.try(:path) || d.try(:destination))
end
site.destroy
end
end