From 8f46d45603b071f5eb84073ac4407ed4d524cc1d Mon Sep 17 00:00:00 2001 From: f Date: Tue, 16 Jun 2020 13:35:08 -0300 Subject: [PATCH] mensajes de mantenimiento con agenda --- Gemfile | 1 + Gemfile.lock | 4 ++ app/jobs/maintenance_job.rb | 30 ++++++++++++ app/mailers/contact_mailer.rb | 2 + app/mailers/maintenance_mailer.rb | 46 +++++++++++++++++++ app/models/maintenance.rb | 8 ++++ app/views/maintenance/were_back.text.haml | 6 +++ app/views/maintenance_mailer/notice.html.haml | 6 +++ app/views/maintenance_mailer/notice.text.haml | 12 +++++ .../maintenance_mailer/were_back.html.haml | 3 ++ .../maintenance_mailer/were_back.text.haml | 6 +++ config/locales/en.yml | 15 ++++++ config/locales/es.yml | 15 ++++++ .../20200616133218_create_maintenance.rb | 14 ++++++ db/schema.rb | 20 +++++++- 15 files changed, 187 insertions(+), 1 deletion(-) create mode 100644 app/jobs/maintenance_job.rb create mode 100644 app/mailers/maintenance_mailer.rb create mode 100644 app/models/maintenance.rb create mode 100644 app/views/maintenance/were_back.text.haml create mode 100644 app/views/maintenance_mailer/notice.html.haml create mode 100644 app/views/maintenance_mailer/notice.text.haml create mode 100644 app/views/maintenance_mailer/were_back.html.haml create mode 100644 app/views/maintenance_mailer/were_back.text.haml create mode 100644 db/migrate/20200616133218_create_maintenance.rb diff --git a/Gemfile b/Gemfile index bc31c84c..4dfcf5d9 100644 --- a/Gemfile +++ b/Gemfile @@ -50,6 +50,7 @@ gem 'friendly_id' gem 'hamlit-rails' gem 'hiredis' gem 'image_processing' +gem 'icalendar' gem 'inline_svg' gem 'jekyll' gem 'jekyll-data', require: 'jekyll-data', diff --git a/Gemfile.lock b/Gemfile.lock index a0f6cf91..c724aebf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -194,6 +194,9 @@ GEM http_parser.rb (0.6.0) i18n (1.8.3) concurrent-ruby (~> 1.0) + icalendar (2.6.1) + ice_cube (~> 0.16) + ice_cube (0.16.3) image_processing (1.11.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) @@ -507,6 +510,7 @@ DEPENDENCIES haml-lint hamlit-rails hiredis + icalendar image_processing inline_svg jbuilder (~> 2.5) diff --git a/app/jobs/maintenance_job.rb b/app/jobs/maintenance_job.rb new file mode 100644 index 00000000..2a335702 --- /dev/null +++ b/app/jobs/maintenance_job.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +# Envía los mensajes de mantenimiento +# +# TODO: Interfaz web desde el panel de gestión. Mientras tanto: +# +# docker exec -it sutty /bin/sh +# su app +# cd +# bundle exec rails c +# m = Maintenance.create message_en: 'reason', message_es: 'razón', +# estimated_from: Time.now, estimated_to: Time.now + 1.hour +# MaintenanceJob.perform_async(maintenance_id: m.id) +# +# Lo mismo para salir de mantenimiento, agregando el atributo +# are_we_back: true al crear el Maintenance. +class MaintenanceJob < ApplicationJob + def perform(maintenance_id:) + maintenance = Maintenance.find(maintenance_id) + # Decidir cuál vamos a enviar según el estado de Maintenance + mailer = maintenance.are_we_back ? :were_back : :notice + + # XXX: Parece que [0] es más rápido que []#first + Usuarie.all.pluck(:email, :lang).each do |u| + MaintenanceMailer.with(maintenance: maintenance, + email: u[0], + lang: u[1]).send(mailer).deliver_now + end + end +end diff --git a/app/mailers/contact_mailer.rb b/app/mailers/contact_mailer.rb index 2b97c63d..a9701811 100644 --- a/app/mailers/contact_mailer.rb +++ b/app/mailers/contact_mailer.rb @@ -20,6 +20,8 @@ class ContactMailer < ApplicationMailer # El CSV es un archivo adjunto con dos filas, una con las etiquetas de # los campos en la cabecera y otra con los valores. + # + # TODO: Si el sitio tiene muches usuaries esto se genera cada vez. def generate_csv csv = ["\xEF\xBB\xBF"] csv << params[:form].keys.map do |field| diff --git a/app/mailers/maintenance_mailer.rb b/app/mailers/maintenance_mailer.rb new file mode 100644 index 00000000..2f2a3d6f --- /dev/null +++ b/app/mailers/maintenance_mailer.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# Envía correos de mantenimiento +class MaintenanceMailer < ApplicationMailer + # Notifica a les usuaries de tareas de mantenimiento + def notice + I18n.with_locale params[:lang] do + attachments['maintenance.ics'] = ics + + mail to: params[:email], + subject: I18n.t('maintenance_mailer.notice.subject') + end + end + + # Notifica que volvimos + def were_back + params[:maintenance] = Maintenance.find(params[:maintenance_id]) + + Usuarie.all.find_each do |usuarie| + I18n.with_locale usuarie.lang do + mail to: usuarie.email, + subject: I18n.t('maintenance_mailer.were_back.subject') + end + end + end + + private + + def cache_key + @cache_key ||= params[:maintenance].cache_key_with_version + '/ics/' + params[:lang] + end + + def ics + Rails.cache.fetch(cache_key, expires_in: 1.hour) do + cal = Icalendar::Calendar.new + cal.event do |e| + e.dtstart = params[:maintenance].estimated_from + e.dtend = params[:maintenance].estimated_to + e.summary = I18n.t('maintenance_mailer.ics.summary') + e.description = params[:maintenance].message + end + + { mimetype: 'text/calendar; charset=utf-8', content: cal.to_ical } + end + end +end diff --git a/app/models/maintenance.rb b/app/models/maintenance.rb new file mode 100644 index 00000000..a40d5cc7 --- /dev/null +++ b/app/models/maintenance.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# En mantenimiento +class Maintenance < ApplicationRecord + extend Mobility + + translates :message, type: :string, locale_accessors: true +end diff --git a/app/views/maintenance/were_back.text.haml b/app/views/maintenance/were_back.text.haml new file mode 100644 index 00000000..156c364c --- /dev/null +++ b/app/views/maintenance/were_back.text.haml @@ -0,0 +1,6 @@ += t('.hi').html_safe +\ += t('.message').html_safe +\ += params[:maintenance].message.html_safe +\ diff --git a/app/views/maintenance_mailer/notice.html.haml b/app/views/maintenance_mailer/notice.html.haml new file mode 100644 index 00000000..667002b2 --- /dev/null +++ b/app/views/maintenance_mailer/notice.html.haml @@ -0,0 +1,6 @@ +%p= t('.hi') +%p= t('.message') +%p= t('.reason') +%blockquote= params[:maintenance].message +%p= t('.estimated_from', from: params[:maintenance].estimated_from) +%p= t('.estimated_to', to: params[:maintenance].estimated_to) diff --git a/app/views/maintenance_mailer/notice.text.haml b/app/views/maintenance_mailer/notice.text.haml new file mode 100644 index 00000000..7e8c5f33 --- /dev/null +++ b/app/views/maintenance_mailer/notice.text.haml @@ -0,0 +1,12 @@ += t('.hi').html_safe +\ += t('.message').html_safe +\ += t('.reason').html_safe +\ += params[:maintenance].message.html_safe +\ += t('.estimated_from', from: params[:maintenance].estimated_from).html_safe +\ += t('.estimated_to', to: params[:maintenance].estimated_to).html_safe +\ diff --git a/app/views/maintenance_mailer/were_back.html.haml b/app/views/maintenance_mailer/were_back.html.haml new file mode 100644 index 00000000..20d0bf20 --- /dev/null +++ b/app/views/maintenance_mailer/were_back.html.haml @@ -0,0 +1,3 @@ +%p= t('.hi') +%p= t('.message') +%blockquote= params[:maintenance].message diff --git a/app/views/maintenance_mailer/were_back.text.haml b/app/views/maintenance_mailer/were_back.text.haml new file mode 100644 index 00000000..5d7d5311 --- /dev/null +++ b/app/views/maintenance_mailer/were_back.text.haml @@ -0,0 +1,6 @@ += t('.hi') +\ += t('.message') +\ += params[:maintenance].message +\ diff --git a/config/locales/en.yml b/config/locales/en.yml index aae7c861..8224fc98 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -69,6 +69,21 @@ en: success: Available for download error: Error help: You can contact us by replying this e-mail + maintenance_mailer: + notice: + subject: 'Maintenance notice' + hi: 'Hi!' + message: "We're getting in contact with you to let you know we'll be doing maintenance work in our servers." + reason: 'The reason is:' + estimated_from: 'The maintenance period starts at %{from}' + estimated_to: 'Up to %{to} (approximately)' + thanks: 'Thanks for your patience' + were_back: + subject: 'Maintenance period ended' + hi: 'Hi!' + message: 'The maintenance period ended at %{created_at}' + ics: + summary: 'Sutty - Maintenance' activerecord: models: usuarie: User diff --git a/config/locales/es.yml b/config/locales/es.yml index 0223ef04..7aa87cdb 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -71,6 +71,21 @@ es: success: Disponible para descargar error: Hubo un error help: Por cualquier duda, responde este correo para contactarte con nosotres. + maintenance_mailer: + notice: + subject: 'Aviso de mantenimiento' + hi: '¡Hola!' + message: 'Nos comunicamos con vos para informarte que estaremos realizando mantenimiento en nuestros servidores' + reason: 'La razón de esta tarea es:' + estimated_from: 'El mantenimiento se realizará a partir de %{from}' + estimated_to: 'Hasta %{to} (aproximadamente)' + thanks: 'Gracias por tu paciencia' + were_back: + subject: 'Fin del mantenimiento' + hi: '¡Hola!' + message: 'El período de mantenimiento terminó en %{created_at}' + ics: + summary: 'Sutty - Mantenimiento' activerecord: models: usuarie: Usuarie diff --git a/db/migrate/20200616133218_create_maintenance.rb b/db/migrate/20200616133218_create_maintenance.rb new file mode 100644 index 00000000..581d9e3d --- /dev/null +++ b/db/migrate/20200616133218_create_maintenance.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Crea una tabla de avisos de mantenimiento +class CreateMaintenance < ActiveRecord::Migration[6.0] + def change + create_table :maintenances do |t| + t.timestamps + t.text :message + t.datetime :estimated_from + t.datetime :estimated_to + t.boolean :are_we_back, default: false + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 5d0d00a8..9cc2bb75 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -12,7 +12,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20_200_206_151_057) do +ActiveRecord::Schema.define(version: 20_200_616_133_218) do # Could not dump table "access_logs" because of following StandardError # Unknown type '' for column 'id' @@ -92,6 +92,23 @@ ActiveRecord::Schema.define(version: 20_200_206_151_057) do t.string 'icons' end + create_table 'log_entries', force: :cascade do |t| + t.datetime 'created_at', precision: 6, null: false + t.datetime 'updated_at', precision: 6, null: false + t.integer 'site_id' + t.text 'text' + t.index ['site_id'], name: 'index_log_entries_on_site_id' + end + + create_table 'maintenances', force: :cascade do |t| + t.datetime 'created_at', precision: 6, null: false + t.datetime 'updated_at', precision: 6, null: false + t.text 'message' + t.datetime 'estimated_from' + t.datetime 'estimated_to' + t.boolean 'are_we_back', default: false + end + create_table 'mobility_string_translations', force: :cascade do |t| t.string 'locale', null: false t.string 'key', null: false @@ -139,6 +156,7 @@ ActiveRecord::Schema.define(version: 20_200_206_151_057) do t.text 'description' t.string 'title' t.boolean 'colaboracion_anonima', default: false + t.boolean 'contact', default: false t.index ['design_id'], name: 'index_sites_on_design_id' t.index ['licencia_id'], name: 'index_sites_on_licencia_id' t.index ['name'], name: 'index_sites_on_name', unique: true