mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-24 06:26:22 +00:00
generar el sitio utilizando sidekiq
This commit is contained in:
parent
7ed08f8a0d
commit
b149374c41
17 changed files with 273 additions and 48 deletions
|
@ -3,3 +3,6 @@ IMAP_SERVER=
|
|||
DEFAULT_FROM=
|
||||
DEVISE_PEPPER=
|
||||
SKEL_SUTTY=https://0xacab.org/sutty/skel.sutty.nl
|
||||
SUTTY=sutty.nl
|
||||
REDIS_SERVER=
|
||||
REDIS_CLIENT=
|
||||
|
|
5
Gemfile
5
Gemfile
|
@ -47,6 +47,7 @@ gem 'exception_notification'
|
|||
gem 'font-awesome-rails'
|
||||
gem 'friendly_id'
|
||||
gem 'hamlit-rails'
|
||||
gem 'hiredis'
|
||||
gem 'jekyll'
|
||||
gem 'jquery-rails'
|
||||
gem 'mini_magick'
|
||||
|
@ -54,8 +55,12 @@ gem 'mobility'
|
|||
gem 'pundit'
|
||||
gem 'rails-i18n'
|
||||
gem 'rails_warden'
|
||||
gem 'redis', require: %w[redis redis/connection/hiredis]
|
||||
gem 'redis-rails'
|
||||
gem 'rubyzip'
|
||||
gem 'rugged'
|
||||
gem 'sidekiq'
|
||||
gem 'terminal-table'
|
||||
gem 'validates_hostname'
|
||||
gem 'whenever', require: false
|
||||
|
||||
|
|
33
Gemfile.lock
33
Gemfile.lock
|
@ -97,6 +97,7 @@ GEM
|
|||
commonmarker (0.18.2)
|
||||
ruby-enum (~> 0.5)
|
||||
concurrent-ruby (1.1.5)
|
||||
connection_pool (2.2.2)
|
||||
crass (1.0.4)
|
||||
database_cleaner (1.7.0)
|
||||
devise (4.6.2)
|
||||
|
@ -161,6 +162,7 @@ GEM
|
|||
activesupport (>= 4.0.1)
|
||||
hamlit (>= 1.2.0)
|
||||
railties (>= 4.0.1)
|
||||
hiredis (0.6.3)
|
||||
http_parser.rb (0.6.0)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
|
@ -242,6 +244,8 @@ GEM
|
|||
pundit (2.0.1)
|
||||
activesupport (>= 3.0.0)
|
||||
rack (2.0.6)
|
||||
rack-protection (2.0.5)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (5.2.3)
|
||||
|
@ -280,6 +284,23 @@ GEM
|
|||
ffi (~> 1.0)
|
||||
rbnacl (4.0.2)
|
||||
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)
|
||||
rack (>= 1.4)
|
||||
responders (3.0.0)
|
||||
|
@ -326,6 +347,11 @@ GEM
|
|||
selenium-webdriver (3.141.0)
|
||||
childprocess (~> 0.5)
|
||||
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)
|
||||
unf (~> 0.1.4)
|
||||
spring (2.0.2)
|
||||
|
@ -346,6 +372,8 @@ GEM
|
|||
net-ssh (>= 2.8.0)
|
||||
sysexits (1.2.0)
|
||||
temple (0.8.1)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thor (0.20.3)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.9)
|
||||
|
@ -408,6 +436,7 @@ DEPENDENCIES
|
|||
friendly_id
|
||||
haml-lint
|
||||
hamlit-rails
|
||||
hiredis
|
||||
jbuilder (~> 2.5)
|
||||
jekyll
|
||||
jquery-rails
|
||||
|
@ -422,14 +451,18 @@ DEPENDENCIES
|
|||
rails-i18n
|
||||
rails_warden
|
||||
rbnacl (< 5.0)
|
||||
redis
|
||||
redis-rails
|
||||
rubocop-rails
|
||||
rubyzip
|
||||
rugged
|
||||
sass-rails (~> 5.0)
|
||||
selenium-webdriver
|
||||
sidekiq
|
||||
spring
|
||||
spring-watcher-listen (~> 2.0.0)
|
||||
sqlite3 (~> 1.3.6)
|
||||
terminal-table
|
||||
turbolinks (~> 5)
|
||||
uglifier (>= 1.3.0)
|
||||
validates_hostname
|
||||
|
|
BIN
app/assets/images/logo.png
Normal file
BIN
app/assets/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
|
@ -1,6 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Configuración base del correo
|
||||
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'
|
||||
|
||||
private
|
||||
|
||||
def inline_logo!
|
||||
attachments.inline['logo.png'] ||=
|
||||
File.read('app/assets/images/logo.png')
|
||||
end
|
||||
end
|
||||
|
|
28
app/mailers/deploy_mailer.rb
Normal file
28
app/mailers/deploy_mailer.rb
Normal 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
|
17
app/views/deploy_mailer/deployed.html.haml
Normal file
17
app/views/deploy_mailer/deployed.html.haml
Normal 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]
|
12
app/views/deploy_mailer/deployed.text.haml
Normal file
12
app/views/deploy_mailer/deployed.text.haml
Normal 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')
|
|
@ -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
|
|
@ -1,3 +1,12 @@
|
|||
!!!
|
||||
%html
|
||||
%head
|
||||
%meta{ content: 'text/html; charset=utf-8',
|
||||
'http-equiv': 'Content-Type' }/
|
||||
:css
|
||||
/* Inline */
|
||||
%body
|
||||
= yield
|
||||
|
||||
= image_tag attachments['logo.png'].url, alt: 'Logo de Sutty'
|
||||
= t('.signature')
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
= yield
|
||||
|
||||
= t('.signature')
|
||||
|
|
39
app/workers/deploy_worker.rb
Normal file
39
app/workers/deploy_worker.rb
Normal 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
|
13
config/initializers/sidekiq.rb
Normal file
13
config/initializers/sidekiq.rb
Normal 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
|
|
@ -1,5 +1,35 @@
|
|||
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:
|
||||
models:
|
||||
usuarie: User
|
||||
attributes:
|
||||
usuarie:
|
||||
email: 'E-mail address'
|
||||
password: 'Password'
|
||||
password_confirmation: 'Password confirmation'
|
||||
site:
|
||||
name: 'Name'
|
||||
errors:
|
||||
models:
|
||||
site:
|
||||
|
@ -22,6 +52,8 @@ en:
|
|||
disordered: "The posts are disordered, this will prevent you from reordering them!"
|
||||
disordered_button: 'Reorder!'
|
||||
layouts:
|
||||
mailer:
|
||||
signature: 'With love, Sutty'
|
||||
breadcrumb:
|
||||
help: Help
|
||||
collaborations:
|
||||
|
@ -29,19 +61,6 @@ en:
|
|||
submit: Register
|
||||
password:
|
||||
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:
|
||||
posts:
|
||||
reorder: 'The articles have been reordered!'
|
||||
|
@ -79,27 +98,6 @@ en:
|
|||
sesiones: 'Sessions'
|
||||
anexo: 'Appendix'
|
||||
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:
|
||||
index: 'This is the list of sites you can edit.'
|
||||
edit_translations: "You can edit texts from your site other than
|
||||
|
@ -165,6 +163,27 @@ en:
|
|||
logout: 'Log out'
|
||||
lang: 'Language'
|
||||
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:
|
||||
actions: 'Actions'
|
||||
posts: 'View and edit posts'
|
||||
|
@ -218,10 +237,6 @@ en:
|
|||
message: 'Skeleton upgrade'
|
||||
footer:
|
||||
powered_by: 'is developed by'
|
||||
templates:
|
||||
index: 'Templates'
|
||||
edit: 'Edit'
|
||||
save: 'Save'
|
||||
i18n:
|
||||
index: 'Translations'
|
||||
edit: 'Edit texts and translations'
|
||||
|
|
|
@ -1,4 +1,25 @@
|
|||
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:
|
||||
models:
|
||||
usuarie: Usuarie
|
||||
|
@ -31,6 +52,8 @@ es:
|
|||
disordered: 'Los artículos no tienen número de orden, esto impedirá que los puedas reordenar'
|
||||
disordered_button: '¡Reordenar!'
|
||||
layouts:
|
||||
mailer:
|
||||
signature: 'Con cariño, Sutty'
|
||||
breadcrumb:
|
||||
help: Ayuda
|
||||
collaborations:
|
||||
|
@ -200,7 +223,6 @@ es:
|
|||
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'
|
||||
|
|
|
@ -4,6 +4,9 @@ require File.expand_path('../config/environment', __dir__)
|
|||
require 'rails/test_help'
|
||||
require 'open3'
|
||||
|
||||
require 'sidekiq/testing'
|
||||
Sidekiq::Testing.inline!
|
||||
|
||||
# rubocop:disable Style/ClassAndModuleChildren
|
||||
class ActiveSupport::TestCase
|
||||
include FactoryBot::Syntax::Methods
|
||||
|
|
21
test/workers/deploy_worker_test.rb
Normal file
21
test/workers/deploy_worker_test.rb
Normal 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
|
Loading…
Reference in a new issue