From b149374c41f465d60876f0f0d17afa88f7da1fc0 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 25 Jul 2019 21:36:33 -0300 Subject: [PATCH] generar el sitio utilizando sidekiq --- .env.example | 3 + Gemfile | 5 ++ Gemfile.lock | 33 ++++++++ app/assets/images/logo.png | Bin 0 -> 2001 bytes app/mailers/application_mailer.rb | 13 ++- app/mailers/deploy_mailer.rb | 28 +++++++ app/views/deploy_mailer/deployed.html.haml | 17 ++++ app/views/deploy_mailer/deployed.text.haml | 12 +++ app/views/layouts/mailer.haml | 8 -- app/views/layouts/mailer.html.haml | 9 ++ app/views/layouts/mailer.text.haml | 2 + app/workers/deploy_worker.rb | 39 +++++++++ config/initializers/sidekiq.rb | 13 +++ config/locales/en.yml | 91 ++++++++++++--------- config/locales/es.yml | 24 +++++- test/test_helper.rb | 3 + test/workers/deploy_worker_test.rb | 21 +++++ 17 files changed, 273 insertions(+), 48 deletions(-) create mode 100644 app/assets/images/logo.png create mode 100644 app/mailers/deploy_mailer.rb create mode 100644 app/views/deploy_mailer/deployed.html.haml create mode 100644 app/views/deploy_mailer/deployed.text.haml delete mode 100644 app/views/layouts/mailer.haml create mode 100644 app/workers/deploy_worker.rb create mode 100644 config/initializers/sidekiq.rb create mode 100644 test/workers/deploy_worker_test.rb diff --git a/.env.example b/.env.example index 2661f007..70475f65 100644 --- a/.env.example +++ b/.env.example @@ -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= diff --git a/Gemfile b/Gemfile index 67a8c4d8..25c7a693 100644 --- a/Gemfile +++ b/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 diff --git a/Gemfile.lock b/Gemfile.lock index 4a2c2ff6..b378733e 100644 --- a/Gemfile.lock +++ b/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 diff --git a/app/assets/images/logo.png b/app/assets/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..234d6d248ec5a652ce1b660f2a29448900bfe4de GIT binary patch literal 2001 zcmV;?2QK)DP)LIoe~A}j!cbF5A~>T0-xq~wFTJ@&dpjip)&j-c zSIVvzAWm=_BL=av=%H*WsP|1O`#P^B(VCAC-BF4aa&j0>)Ij4owb0ntDN4O?A~R78 zHHlJ!j*lXl%KVd*qMDSP8-o$atW`MUVo$q+=;$?19U-E)jbqo)!jAKd29X9sGI>ZU zO-+>{0?Tl=}Sp=AI>-fSXlCcc+j5s9fa*%Oe8^OOn<;yTa+<@}9 zLV9WvsY2na>LVadNxPvI%<+l|{p>J&C$FP!TOtyH4B`~KBU0w%<+AJ1CPn`B&T<|} zh*7wd?UITRo?DT_5bNWzN&;&4lkTpPr z=2_@XUd##L#lL8jM*hST+wDxGHbf+fKFQ=piLAk>)V{TU%vlP**HgVsYdk8#;SGB< zkG(4ofH;wf)CPzo#0VtQ0;vdbteXR~m0fX;`xSG4)7O}(7x#=!dKqo=N6ev|$wbO= zBI)ZiRh3V~NOit{0;dvnv}dZ(Ak$Vq`z9vRaUzlsWy;O~OkPr&hqf&WAHNf7Y&$9S zoFt0h-UDWp zLZ44EszVe+FU%!<>CyqPn2FQ|h?GojlP+&d;~&cPiC>j@JwS9oV}7StNB8I%&?-~h zza@Y^om_fl&SfG=$uyuGulU>(drZvqPp9_me*4QoT{^rPIS8C+70E6F6o4w^q!lu7mA3F4ww=-_SDFG ziK{`J#6xziR3y~gWlHGn!T-4X1O34S;qd6pZU?O>- zuQ33|S&Lw7x=aJ}wlI@g7{Y;#c>j$-#>M0NV3$rjzw!qqO*7-sh(FP3GILJOUn1G9LJis47T6VkW0?=< zMZ%trj)Ims{LVFgmsmO}QZx;dd@M8~!9;VGG#Zu1KllPf*9;obD5WRd#ep&W|5bS1 zd6|D&nlsfa?04r}yEJk9Mf7xK!`Asqq-~VvyT*7`wl{(v!Mk2vLBE4U1y(fb^Em0( zsRfgcyv>c!}MQ)k^3g%hVWDPNHA( zkjQ=6niuulD;|()Kfm9=C}ecQB=6p)-=%q@`>kofVCY~zMs!&gyEm9~a1H1Q42BoV za1*^5%paU}HIiMpA7l$L^f1|aOj_-aB@aNKhBMee3{OzKaxs>{j`ke2lt-{`$rfU0 z;T0^jQ}?4&mV^0um@ZOAK|!>G?M+*x%i8ipIWQPH_zUxXvJE!M_ElgGVhb@eAd0$x zA#Gfn0p@JB4?_>vCvH~0Sv%Ak%m!j;!EOkY)$-P{br_mx7$PmqqP&)&A53Eu0_Mi& jK~-W?np7q#vN7DhAAy!sSiN@?00000NkvXXu0mjfBwMrq literal 0 HcmV?d00001 diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index d84cb6e7..94ffc995 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -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 diff --git a/app/mailers/deploy_mailer.rb b/app/mailers/deploy_mailer.rb new file mode 100644 index 00000000..33831044 --- /dev/null +++ b/app/mailers/deploy_mailer.rb @@ -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 diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml new file mode 100644 index 00000000..66cba36b --- /dev/null +++ b/app/views/deploy_mailer/deployed.html.haml @@ -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] diff --git a/app/views/deploy_mailer/deployed.text.haml b/app/views/deploy_mailer/deployed.text.haml new file mode 100644 index 00000000..619d83e1 --- /dev/null +++ b/app/views/deploy_mailer/deployed.text.haml @@ -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') diff --git a/app/views/layouts/mailer.haml b/app/views/layouts/mailer.haml deleted file mode 100644 index cbf6b8e2..00000000 --- a/app/views/layouts/mailer.haml +++ /dev/null @@ -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 diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml index 5ef091a7..9aad3a0e 100644 --- a/app/views/layouts/mailer.html.haml +++ b/app/views/layouts/mailer.html.haml @@ -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') diff --git a/app/views/layouts/mailer.text.haml b/app/views/layouts/mailer.text.haml index 0a90f092..36d87bd3 100644 --- a/app/views/layouts/mailer.text.haml +++ b/app/views/layouts/mailer.text.haml @@ -1 +1,3 @@ = yield + += t('.signature') diff --git a/app/workers/deploy_worker.rb b/app/workers/deploy_worker.rb new file mode 100644 index 00000000..1b4ef9c2 --- /dev/null +++ b/app/workers/deploy_worker.rb @@ -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 diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb new file mode 100644 index 00000000..0ebf8b8c --- /dev/null +++ b/config/initializers/sidekiq.rb @@ -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 diff --git a/config/locales/en.yml b/config/locales/en.yml index 957ac212..157eaf62 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -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 . + + 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 Privacy policy.' - 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 . - - 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 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 . + + 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 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' diff --git a/config/locales/es.yml b/config/locales/es.yml index 4ddd36e0..f2f43591 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -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 . + + 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' diff --git a/test/test_helper.rb b/test/test_helper.rb index 49ac63e7..437b0dab 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -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 diff --git a/test/workers/deploy_worker_test.rb b/test/workers/deploy_worker_test.rb new file mode 100644 index 00000000..53e44d94 --- /dev/null +++ b/test/workers/deploy_worker_test.rb @@ -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