From 8fc705158847a10c5c928c703e3a12d6f5a49c6d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 24 Dec 2021 10:08:09 -0300 Subject: [PATCH 001/109] limpiar gemas al terminar de instalar --- app/models/deploy.rb | 1 + app/models/deploy_local.rb | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 3f034ad5..d08aa239 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -39,6 +39,7 @@ class Deploy < ApplicationRecord site.path end + # XXX: Ver DeployLocal#bundle def gems_dir @gems_dir ||= Rails.root.join('_storage', 'gems', site.name) end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 4fa588f5..a4f60e28 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -92,7 +92,9 @@ class DeployLocal < Deploy def bundle if Rails.env.production? - run %(bundle install --no-cache --path="#{gems_dir}") + # XXX: Desde que ya no compartimos el directorio de gemas, tenemos + # que hacer limpieza después de instalar. + run %(bundle install --no-cache --path="#{gems_dir}" --clean) else run %(bundle install) end From d70ce8efdb8bfe103acf526361199dea22cf83be Mon Sep 17 00:00:00 2001 From: f Date: Fri, 24 Dec 2021 10:19:18 -0300 Subject: [PATCH 002/109] no instalar las gemas de desarrollo --- app/models/deploy_local.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index a4f60e28..6365f602 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -94,7 +94,7 @@ class DeployLocal < Deploy if Rails.env.production? # XXX: Desde que ya no compartimos el directorio de gemas, tenemos # que hacer limpieza después de instalar. - run %(bundle install --no-cache --path="#{gems_dir}" --clean) + run %(bundle install --no-cache --path="#{gems_dir}" --clean --without test development) else run %(bundle install) end From e9c338a8b94271284f04888fd5925521085ffd6b Mon Sep 17 00:00:00 2001 From: f Date: Mon, 27 Dec 2021 11:25:24 -0300 Subject: [PATCH 003/109] no setear un permalink por defecto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit es algo que quisiéramos retomar pero la implementación actual depende de los mecanismos internos de jekyll, que son problemáticos porque espera que se seteen algunos valores antes de poder usarlo. de lo contrario el permalink termina siendo /, haciendo conflicto con la portada del sitio. hasta que lo podamos resolver, lo dejamos vacío. closes #3635 --- app/models/metadata_permalink.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/models/metadata_permalink.rb b/app/models/metadata_permalink.rb index 59b68461..58feb9e5 100644 --- a/app/models/metadata_permalink.rb +++ b/app/models/metadata_permalink.rb @@ -2,12 +2,6 @@ # Este metadato permite generar rutas manuales. class MetadataPermalink < MetadataString - # El valor por defecto una vez creado es la URL que le asigne Jekyll, - # de forma que nunca cambia aunque se cambie el título. - def default_value - document.url.sub(%r{\A/}, '') unless post.new? - end - # Los permalinks nunca pueden ser privados def private? false From a664c2dcd3db20cbb62c42ac4e3154b076772480 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 1 Feb 2022 17:11:00 -0300 Subject: [PATCH 004/109] mapa no geografico --- .../controllers/non_geo_controller.js | 72 +++++++++++++++++++ app/models/metadata_non_geo.rb | 3 + app/views/posts/attribute_ro/_non_geo.haml | 6 ++ app/views/posts/attributes/_non_geo.haml | 24 +++++++ 4 files changed, 105 insertions(+) create mode 100644 app/javascript/controllers/non_geo_controller.js create mode 100644 app/models/metadata_non_geo.rb create mode 100644 app/views/posts/attribute_ro/_non_geo.haml create mode 100644 app/views/posts/attributes/_non_geo.haml diff --git a/app/javascript/controllers/non_geo_controller.js b/app/javascript/controllers/non_geo_controller.js new file mode 100644 index 00000000..072c1b83 --- /dev/null +++ b/app/javascript/controllers/non_geo_controller.js @@ -0,0 +1,72 @@ +import { Controller } from 'stimulus' + +require("leaflet/dist/leaflet.css") +import L from 'leaflet' +delete L.Icon.Default.prototype._getIconUrl + +L.Icon.Default.mergeOptions({ + iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'), + iconUrl: require('leaflet/dist/images/marker-icon.png'), + shadowUrl: require('leaflet/dist/images/marker-shadow.png'), +}) + +export default class extends Controller { + static targets = [ 'lat', 'lng', 'map', 'overlay' ] + + async connect () { + this.marker() + + this.latTarget.addEventListener('change', event => this.marker()) + this.lngTarget.addEventListener('change', event => this.marker()) + window.addEventListener('resize', event => this.map.invalidateSize()) + + const res = await fetch(this.element.dataset.map); + this.overlayTarget.innerHTML = await res.text(); + + this.map.on('click', event => { + this.latTarget.value = event.latlng.lat + this.lngTarget.value = event.latlng.lng + + this.latTarget.dispatchEvent(new Event('change')) + }) + } + + marker () { + if (this._marker) this.map.removeLayer(this._marker) + + this._marker = L.marker(this.coords).addTo(this.map) + + return this._marker + } + + get lat () { + const lat = parseFloat(this.latTarget.value) + + return isNaN(lat) ? 0 : lat + } + + get lng () { + const lng = parseFloat(this.lngTarget.value) + + return isNaN(lng) ? 0 : lng + } + + get coords () { + return [this.lat, this.lng] + } + + get map () { + if (!this._map) { + this._map = L.map(this.mapTarget).setView(this.coords, 13); + + const bounds = [[0,0], [this.mapTarget.clientHeight, this.mapTarget.clientWidth]]; + + L.svgOverlay(this.overlayTarget.querySelector('svg'), bounds).addTo(this._map); + + this._map.fitBounds(bounds); + this._map.setMaxBounds(bounds); + } + + return this._map + } +} diff --git a/app/models/metadata_non_geo.rb b/app/models/metadata_non_geo.rb new file mode 100644 index 00000000..6aec8461 --- /dev/null +++ b/app/models/metadata_non_geo.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +class MetadataNonGeo < MetadataGeo; end diff --git a/app/views/posts/attribute_ro/_non_geo.haml b/app/views/posts/attribute_ro/_non_geo.haml new file mode 100644 index 00000000..75f8d2ef --- /dev/null +++ b/app/views/posts/attribute_ro/_non_geo.haml @@ -0,0 +1,6 @@ +- lat = metadata.value['lat'] +- lng = metadata.value['lng'] +%tr{ id: attribute } + %th= post_label_t(attribute, post: post) + %td + = "#{lat},#{lng}" diff --git a/app/views/posts/attributes/_non_geo.haml b/app/views/posts/attributes/_non_geo.haml new file mode 100644 index 00000000..ad454d96 --- /dev/null +++ b/app/views/posts/attributes/_non_geo.haml @@ -0,0 +1,24 @@ +.row{ data: { controller: 'non-geo', map: "#{site.url}/public/map.svg" } } + .d-none{ hidden: true, data: { target: 'non-geo.overlay' }} + .col + .form-group + = label_tag "#{base}_#{attribute}_lat", + post_label_t(attribute, :lat, post: post) + = text_field(*field_name_for(base, attribute, :lat), + value: metadata.value['lat'], + **field_options(attribute, metadata), + data: { target: 'non-geo.lat' }) + = render 'posts/attribute_feedback', + post: post, attribute: [attribute, :lat], metadata: metadata + .col + .form-group + = label_tag "#{base}_#{attribute}_lng", + post_label_t(attribute, :lng, post: post) + = text_field(*field_name_for(base, attribute, :lng), + value: metadata.value['lng'], + **field_options(attribute, metadata), + data: { target: 'non-geo.lng' }) + = render 'posts/attribute_feedback', + post: post, attribute: [attribute, :lng], metadata: metadata + .col-12.mb-3 + %div{ data: { target: 'non-geo.map' }, style: 'height: 250px' } From c77fb503668c11580f2f920bffa4df9afa5e970f Mon Sep 17 00:00:00 2001 From: f Date: Tue, 1 Feb 2022 17:38:29 -0300 Subject: [PATCH 005/109] obtener el overlay antes que nada --- app/javascript/controllers/non_geo_controller.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/javascript/controllers/non_geo_controller.js b/app/javascript/controllers/non_geo_controller.js index 072c1b83..f8b86643 100644 --- a/app/javascript/controllers/non_geo_controller.js +++ b/app/javascript/controllers/non_geo_controller.js @@ -14,15 +14,15 @@ export default class extends Controller { static targets = [ 'lat', 'lng', 'map', 'overlay' ] async connect () { + const res = await fetch(this.element.dataset.map); + this.overlayTarget.innerHTML = await res.text(); + this.marker() this.latTarget.addEventListener('change', event => this.marker()) this.lngTarget.addEventListener('change', event => this.marker()) window.addEventListener('resize', event => this.map.invalidateSize()) - const res = await fetch(this.element.dataset.map); - this.overlayTarget.innerHTML = await res.text(); - this.map.on('click', event => { this.latTarget.value = event.latlng.lat this.lngTarget.value = event.latlng.lng From 417559399ac7a727e6375ed4ceed1a11d2f5b923 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 1 Feb 2022 17:52:40 -0300 Subject: [PATCH 006/109] traer archivos subidos localmente --- app/views/posts/attributes/_non_geo.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/attributes/_non_geo.haml b/app/views/posts/attributes/_non_geo.haml index ad454d96..84b1cb00 100644 --- a/app/views/posts/attributes/_non_geo.haml +++ b/app/views/posts/attributes/_non_geo.haml @@ -1,4 +1,4 @@ -.row{ data: { controller: 'non-geo', map: "#{site.url}/public/map.svg" } } +.row{ data: { controller: 'non-geo', map: url_for(site.static_files.blobs.find_by_filename('map.svg').attachments.first) } } .d-none{ hidden: true, data: { target: 'non-geo.overlay' }} .col .form-group From cf5341eec4bba6b42c45bc01d921300b28ad30f3 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 1 Feb 2022 18:20:19 -0300 Subject: [PATCH 007/109] =?UTF-8?q?usar=20el=20tama=C3=B1o=20del=20svg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/non_geo_controller.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/app/javascript/controllers/non_geo_controller.js b/app/javascript/controllers/non_geo_controller.js index f8b86643..1a7775f2 100644 --- a/app/javascript/controllers/non_geo_controller.js +++ b/app/javascript/controllers/non_geo_controller.js @@ -55,13 +55,25 @@ export default class extends Controller { return [this.lat, this.lng] } + get svgOverlay () { + return this.overlayTarget.querySelector('svg'); + } + + get bounds () { + return [ + [0, 0], + [ + this.svgOverlay.viewBox.baseVal.height, + this.svgOverlay.viewBox.baseVal.width, + ] + ]; + } + get map () { if (!this._map) { this._map = L.map(this.mapTarget).setView(this.coords, 13); - const bounds = [[0,0], [this.mapTarget.clientHeight, this.mapTarget.clientWidth]]; - - L.svgOverlay(this.overlayTarget.querySelector('svg'), bounds).addTo(this._map); + L.svgOverlay(this.svgOverlay, this.bounds).addTo(this._map); this._map.fitBounds(bounds); this._map.setMaxBounds(bounds); From c68508f89af6d566ad4063869f7d84615672e2c2 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 1 Feb 2022 18:21:32 -0300 Subject: [PATCH 008/109] usar el sistema de coordenadas simplificado --- app/javascript/controllers/non_geo_controller.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/controllers/non_geo_controller.js b/app/javascript/controllers/non_geo_controller.js index 1a7775f2..1da5511a 100644 --- a/app/javascript/controllers/non_geo_controller.js +++ b/app/javascript/controllers/non_geo_controller.js @@ -71,7 +71,10 @@ export default class extends Controller { get map () { if (!this._map) { - this._map = L.map(this.mapTarget).setView(this.coords, 13); + this._map = L.map(this.mapTarget, { + crs: L.CRS.Simple, + zoomSnap: 0.1 + }).setView(this.coords, 13); L.svgOverlay(this.svgOverlay, this.bounds).addTo(this._map); From c5c96c8f3cee253e7e327714bd0785d37f509313 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 1 Feb 2022 18:28:27 -0300 Subject: [PATCH 009/109] ajustar al contenido --- app/javascript/controllers/non_geo_controller.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/controllers/non_geo_controller.js b/app/javascript/controllers/non_geo_controller.js index 1da5511a..419e3c6a 100644 --- a/app/javascript/controllers/non_geo_controller.js +++ b/app/javascript/controllers/non_geo_controller.js @@ -72,11 +72,14 @@ export default class extends Controller { get map () { if (!this._map) { this._map = L.map(this.mapTarget, { + minZoom: -5, crs: L.CRS.Simple, zoomSnap: 0.1 }).setView(this.coords, 13); - L.svgOverlay(this.svgOverlay, this.bounds).addTo(this._map); + const bounds = this.bounds; + + L.svgOverlay(this.svgOverlay, bounds).addTo(this._map); this._map.fitBounds(bounds); this._map.setMaxBounds(bounds); From aa3cbc209ee30ad3efc3db9e477d57c19d60e2a0 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 10 Feb 2022 15:18:49 -0300 Subject: [PATCH 010/109] =?UTF-8?q?vincular=20a=20un=20idioma=20seg=C3=BAn?= =?UTF-8?q?=20el=20dominio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #4545 --- app/models/deploy_localized_domain.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 app/models/deploy_localized_domain.rb diff --git a/app/models/deploy_localized_domain.rb b/app/models/deploy_localized_domain.rb new file mode 100644 index 00000000..6e89c794 --- /dev/null +++ b/app/models/deploy_localized_domain.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Soportar dominios localizados +class DeployLocalizedDomain < DeployAlternativeDomain + store :values, accessors: %i[hostname locale], coder: JSON + + # Generar un link simbólico del sitio principal al alternativo + def deploy + File.symlink?(destination) || + File.symlink(File.join(site.hostname, locale), destination).zero? + end +end From 958306ce06213b852e7b6bf2e917eeb7b63d588c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 10 Feb 2022 15:26:20 -0300 Subject: [PATCH 011/109] expedir certificados para los dominios localizados --- app/controllers/api/v1/sites_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/sites_controller.rb b/app/controllers/api/v1/sites_controller.rb index 6abff704..0de21669 100644 --- a/app/controllers/api/v1/sites_controller.rb +++ b/app/controllers/api/v1/sites_controller.rb @@ -46,7 +46,7 @@ module Api # Dominios alternativos def alternative_names - DeployAlternativeDomain.all.map(&:hostname) + DeployAlternativeDomain.all.map(&:hostname) + DeployLocalizedDomain.all.map(&:hostname) end # Obtener todos los sitios con API habilitada, es decir formulario From 05fba76ab81a03e4b4cad0b2c152181c048a4f5c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 10 Feb 2022 19:00:25 -0300 Subject: [PATCH 012/109] usar mosaicos en lugar de svg --- .../controllers/non_geo_controller.js | 22 +++++++------------ app/views/posts/attributes/_non_geo.haml | 2 +- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/app/javascript/controllers/non_geo_controller.js b/app/javascript/controllers/non_geo_controller.js index 419e3c6a..965c561e 100644 --- a/app/javascript/controllers/non_geo_controller.js +++ b/app/javascript/controllers/non_geo_controller.js @@ -55,10 +55,6 @@ export default class extends Controller { return [this.lat, this.lng] } - get svgOverlay () { - return this.overlayTarget.querySelector('svg'); - } - get bounds () { return [ [0, 0], @@ -72,17 +68,15 @@ export default class extends Controller { get map () { if (!this._map) { this._map = L.map(this.mapTarget, { - minZoom: -5, - crs: L.CRS.Simple, - zoomSnap: 0.1 - }).setView(this.coords, 13); + minZoom: 0, + maxZoom: 5 + }).setView(this.coords, 0); - const bounds = this.bounds; - - L.svgOverlay(this.svgOverlay, bounds).addTo(this._map); - - this._map.fitBounds(bounds); - this._map.setMaxBounds(bounds); + this._layer = L.tileLayer(`${this.element.dataset.site}public/map/{z}/{y}/{x}.png`, { + minNativeZoom: 0, + maxNativeZoom: 5, + noWrap: true + }).addTo(this._map); } return this._map diff --git a/app/views/posts/attributes/_non_geo.haml b/app/views/posts/attributes/_non_geo.haml index 84b1cb00..fd4e85ea 100644 --- a/app/views/posts/attributes/_non_geo.haml +++ b/app/views/posts/attributes/_non_geo.haml @@ -1,4 +1,4 @@ -.row{ data: { controller: 'non-geo', map: url_for(site.static_files.blobs.find_by_filename('map.svg').attachments.first) } } +.row{ data: { controller: 'non-geo', site: site.url } } .d-none{ hidden: true, data: { target: 'non-geo.overlay' }} .col .form-group From 53ce970bb0892f74faa0acb7878c7c34646289f4 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 11 Feb 2022 13:57:53 -0300 Subject: [PATCH 013/109] no intentar descargar el mapa --- app/javascript/controllers/non_geo_controller.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/javascript/controllers/non_geo_controller.js b/app/javascript/controllers/non_geo_controller.js index 965c561e..1c618fcb 100644 --- a/app/javascript/controllers/non_geo_controller.js +++ b/app/javascript/controllers/non_geo_controller.js @@ -14,9 +14,6 @@ export default class extends Controller { static targets = [ 'lat', 'lng', 'map', 'overlay' ] async connect () { - const res = await fetch(this.element.dataset.map); - this.overlayTarget.innerHTML = await res.text(); - this.marker() this.latTarget.addEventListener('change', event => this.marker()) From b54a8280a56ca554753f4627673c9dfc73041aee Mon Sep 17 00:00:00 2001 From: f Date: Wed, 2 Mar 2022 13:56:19 -0300 Subject: [PATCH 014/109] =?UTF-8?q?soportar=20m=C3=A1s=20idiomas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 2aa0056f..e52405d6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -57,7 +57,7 @@ Rails.application.routes.draw do # Gestionar artículos según idioma nested do - scope '/(:locale)', constraint: /[a-z]{2}/ do + scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do post :'posts/reorder', to: 'posts#reorder' resources :posts do get 'p/:page', action: :index, on: :collection From 38c34f7b4ffb4dc70188413a2c7b3f1bec4e0c26 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 2 Mar 2022 14:01:17 -0300 Subject: [PATCH 015/109] =?UTF-8?q?usar=20la=20direcci=C3=B3n=20desde=20el?= =?UTF-8?q?=20sitio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/posts/index.haml | 2 +- app/views/posts/show.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 90d65670..b636a891 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -86,7 +86,7 @@ %div %tbody - - dir = t("locales.#{@locale}.dir") + - dir = @site.data.dig(params[:locale], 'dir') - size = @posts.size - @posts.each_with_index do |post, i| -# diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index da6ac9db..d6ad724c 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -1,4 +1,4 @@ -- dir = t("locales.#{@locale}.dir") +- dir = @site.data.dig(params[:locale], 'dir') .row.justify-content-center .col-md-8 %article.content.table-responsive-md From d7f9f0c9b1f1c3d43632cc92872805d5608687cc Mon Sep 17 00:00:00 2001 From: f Date: Tue, 8 Mar 2022 15:09:31 -0300 Subject: [PATCH 016/109] devolver todos los dominios --- app/controllers/api/v1/sites_controller.rb | 28 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/sites_controller.rb b/app/controllers/api/v1/sites_controller.rb index 6abff704..32fdae1d 100644 --- a/app/controllers/api/v1/sites_controller.rb +++ b/app/controllers/api/v1/sites_controller.rb @@ -9,7 +9,7 @@ module Api # Lista de nombres de dominios a emitir certificados def index - render json: sites_names + alternative_names + api_names + render json: sites_names + alternative_names + api_names + www_names end # Sitios con hidden service de Tor @@ -28,7 +28,7 @@ module Api site = Site.find_by(name: params[:name]) if site - usuarie = GitAuthor.new email: 'tor@' + Site.domain, name: 'Tor' + usuarie = GitAuthor.new email: "tor@#{Site.domain}", name: 'Tor' service = SiteService.new site: site, usuarie: usuarie, params: params service.add_onion @@ -39,14 +39,22 @@ module Api private + def canonicalize(name) + name.end_with?('.') ? name[0..-2] : "#{name}.#{Site.domain}" + end + # Nombres de los sitios def sites_names - Site.all.order(:name).pluck(:name) + Site.all.order(:name).pluck(:name).map do |name| + canonicalize name + end end # Dominios alternativos def alternative_names - DeployAlternativeDomain.all.map(&:hostname) + (DeployAlternativeDomain.all.map(&:hostname) + DeployLocalizedDomain.all.map(&:hostname)).map do |name| + canonicalize name + end end # Obtener todos los sitios con API habilitada, es decir formulario @@ -56,7 +64,17 @@ module Api def api_names Site.where(contact: true) .or(Site.where(colaboracion_anonima: true)) - .select("'api.' || name as name").map(&:name) + .select("'api.' || name as name").map(&:name).map do |name| + canonicalize name + end + end + + def www_names + Site.where(contact: true) + .or(Site.where(colaboracion_anonima: true)) + .select("'www.' || name as name").map(&:name).map do |name| + canonicalize name + end end end end From 437d5ff230f69f4b6b498cb02f041357098fbf03 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 8 Mar 2022 21:54:25 -0300 Subject: [PATCH 017/109] etiquetas --- app/views/posts/attributes/_geo.haml | 4 ++++ app/views/posts/attributes/_non_geo.haml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/app/views/posts/attributes/_geo.haml b/app/views/posts/attributes/_geo.haml index d048565e..4ed7a395 100644 --- a/app/views/posts/attributes/_geo.haml +++ b/app/views/posts/attributes/_geo.haml @@ -1,4 +1,8 @@ .row{ data: { controller: 'geo' } } + .col-12 + %p= post_label_t(attribute, post: post) + = render 'posts/attribute_feedback', + post: post, attribute: attribute, metadata: metadata .col .form-group = label_tag "#{base}_#{attribute}_lat", diff --git a/app/views/posts/attributes/_non_geo.haml b/app/views/posts/attributes/_non_geo.haml index fd4e85ea..a5a7ea12 100644 --- a/app/views/posts/attributes/_non_geo.haml +++ b/app/views/posts/attributes/_non_geo.haml @@ -1,5 +1,9 @@ .row{ data: { controller: 'non-geo', site: site.url } } .d-none{ hidden: true, data: { target: 'non-geo.overlay' }} + .col-12 + %p= post_label_t(attribute, post: post) + = render 'posts/attribute_feedback', + post: post, attribute: attribute, metadata: metadata .col .form-group = label_tag "#{base}_#{attribute}_lat", From 6801d5655bf36d9e84025ff37f5f8f52f63752c0 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 8 Mar 2022 21:56:41 -0300 Subject: [PATCH 018/109] mejorar estilo --- app/views/posts/attributes/_geo.haml | 4 ++-- app/views/posts/attributes/_non_geo.haml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/views/posts/attributes/_geo.haml b/app/views/posts/attributes/_geo.haml index 4ed7a395..dee4707e 100644 --- a/app/views/posts/attributes/_geo.haml +++ b/app/views/posts/attributes/_geo.haml @@ -1,6 +1,6 @@ .row{ data: { controller: 'geo' } } - .col-12 - %p= post_label_t(attribute, post: post) + .col-12.mb-3 + %p.mb-0= post_label_t(attribute, post: post) = render 'posts/attribute_feedback', post: post, attribute: attribute, metadata: metadata .col diff --git a/app/views/posts/attributes/_non_geo.haml b/app/views/posts/attributes/_non_geo.haml index a5a7ea12..3f6a75a6 100644 --- a/app/views/posts/attributes/_non_geo.haml +++ b/app/views/posts/attributes/_non_geo.haml @@ -1,6 +1,7 @@ .row{ data: { controller: 'non-geo', site: site.url } } .d-none{ hidden: true, data: { target: 'non-geo.overlay' }} - .col-12 + .col-12.mb-3 + %p.mb-0= post_label_t(attribute, post: post) %p= post_label_t(attribute, post: post) = render 'posts/attribute_feedback', post: post, attribute: attribute, metadata: metadata From ef00ce4d128093a46be68a86006b2e9390db6257 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 14 Mar 2022 13:39:54 -0300 Subject: [PATCH 019/109] poder ver la salida opcionalmente --- app/models/deploy.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 3f034ad5..0a11f1b8 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -48,7 +48,7 @@ class Deploy < ApplicationRecord # # @param [String] # @return [Boolean] - def run(cmd) + def run(cmd, output: false) r = nil lines = [] @@ -61,6 +61,7 @@ class Deploy < ApplicationRecord # TODO: Enviar a un websocket para ver el proceso en vivo? o.each do |line| lines << line + puts line if output end end end From 8e89643bdb03a73ba3d65cd698575e5139ea3987 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 14 Mar 2022 13:40:17 -0300 Subject: [PATCH 020/109] leer la salida por separado para no bloquear el programa --- app/models/deploy.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 0a11f1b8..427e7091 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -55,14 +55,15 @@ class Deploy < ApplicationRecord time_start Dir.chdir(site.path) do Open3.popen2e(env, cmd, unsetenv_others: true) do |_, o, t| - r = t.value - # XXX: Tenemos que leer línea por línea porque en salidas largas - # se cuelga la IO # TODO: Enviar a un websocket para ver el proceso en vivo? - o.each do |line| - lines << line - puts line if output + Thread.new do + o.each do |line| + lines << line + + puts line if output + end end + r = t.value end end time_stop From f3c3da81e0fe35ddc971333fd49658e8784846e8 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 15 Mar 2022 16:03:16 -0300 Subject: [PATCH 021/109] poder ver la salida si lo ejecutamos desde la terminal --- app/jobs/deploy_job.rb | 10 ++++++---- app/models/deploy_local.rb | 26 +++++++++++++------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 70997ce1..4146abad 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -5,7 +5,9 @@ class DeployJob < ApplicationJob class DeployException < StandardError; end # rubocop:disable Metrics/MethodLength - def perform(site, notify = true, time = Time.now) + def perform(site, notify: true, time: Time.now, output: false) + @output = output + ActiveRecord::Base.connection_pool.with_connection do @site = Site.find(site) @@ -21,7 +23,7 @@ class DeployJob < ApplicationJob "#{@site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" end - DeployJob.perform_in(60, site, notify, time) + DeployJob.perform_in(60, site, notify: notify, time: time, output: output) return end @@ -55,12 +57,12 @@ class DeployJob < ApplicationJob end def deploy_locally - deploy_local.deploy + deploy_local.deploy(output: @output) end def deploy_others @site.deploys.where.not(type: 'DeployLocal').find_each do |d| - @deployed[d.type.underscore.to_sym] = d.deploy + @deployed[d.type.underscore.to_sym] = d.deploy(output: @output) end end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 4fa588f5..4f9318d8 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -12,12 +12,12 @@ class DeployLocal < Deploy # # Pasamos variables de entorno mínimas para no filtrar secretos de # Sutty - def deploy + def deploy(output: false) return false unless mkdir - return false unless yarn - return false unless bundle + return false unless yarn(output: output) + return false unless bundle(output: output) - jekyll_build + jekyll_build(output: output) end # Sólo permitimos un deploy local @@ -79,27 +79,27 @@ class DeployLocal < Deploy File.exist? yarn_lock end - def gem - run %(gem install bundler --no-document) + def gem(output: false) + run %(gem install bundler --no-document), output: output end # Corre yarn dentro del repositorio - def yarn + def yarn(output: false) return true unless yarn_lock? - run 'yarn install --production' + run 'yarn install --production', output: output end - def bundle + def bundle(output: false) if Rails.env.production? - run %(bundle install --no-cache --path="#{gems_dir}") + run %(bundle install --no-cache --path="#{gems_dir}"), output: output else - run %(bundle install) + run %(bundle install), output: output end end - def jekyll_build - run %(bundle exec jekyll build --trace --profile --destination "#{escaped_destination}") + def jekyll_build(output: false) + run %(bundle exec jekyll build --trace --profile --destination "#{escaped_destination}"), output: output end # no debería haber espacios ni caracteres especiales, pero por si From 3160b30dec8a8661e7bebac92e011f3acef19059 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Mar 2022 17:49:28 -0300 Subject: [PATCH 022/109] eliminar atributo style del editor --- app/models/metadata_content.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 9d3a1040..9516b907 100644 --- a/app/models/metadata_content.rb +++ b/app/models/metadata_content.rb @@ -72,6 +72,17 @@ class MetadataContent < MetadataTemplate resource['controls'] = true end + # Elimina los estilos salvo los que asigne el editor + html.css('*').each do |element| + next if elements_with_style.include? element.name.downcase + + element.remove_attribute('style') + end + html.to_s.html_safe end + + def elements_with_style + @elements_with_style ||= %w[div mark].freeze + end end From 1071eba2005c3d3857101bd264c188897a9efe22 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 16 Mar 2022 18:19:04 -0300 Subject: [PATCH 023/109] implementar la misma api en todos los deploys --- app/models/deploy.rb | 2 +- app/models/deploy_alternative_domain.rb | 2 +- app/models/deploy_hidden_service.rb | 2 +- app/models/deploy_localized_domain.rb | 12 ++++++++++++ app/models/deploy_private.rb | 4 ++-- app/models/deploy_www.rb | 2 +- app/models/deploy_zip.rb | 2 +- 7 files changed, 19 insertions(+), 7 deletions(-) create mode 100644 app/models/deploy_localized_domain.rb diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 427e7091..0cc92ff1 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -11,7 +11,7 @@ class Deploy < ApplicationRecord belongs_to :site has_many :build_stats, dependent: :destroy - def deploy + def deploy(**) raise NotImplementedError end diff --git a/app/models/deploy_alternative_domain.rb b/app/models/deploy_alternative_domain.rb index e4960e65..ae0ff300 100644 --- a/app/models/deploy_alternative_domain.rb +++ b/app/models/deploy_alternative_domain.rb @@ -5,7 +5,7 @@ class DeployAlternativeDomain < Deploy store :values, accessors: %i[hostname], coder: JSON # Generar un link simbólico del sitio principal al alternativo - def deploy + def deploy(**) File.symlink?(destination) || File.symlink(site.hostname, destination).zero? end diff --git a/app/models/deploy_hidden_service.rb b/app/models/deploy_hidden_service.rb index d4d2b822..dcac712e 100644 --- a/app/models/deploy_hidden_service.rb +++ b/app/models/deploy_hidden_service.rb @@ -2,7 +2,7 @@ # Genera una versión onion class DeployHiddenService < DeployWww - def deploy + def deploy(**) return true if fqdn.blank? super diff --git a/app/models/deploy_localized_domain.rb b/app/models/deploy_localized_domain.rb new file mode 100644 index 00000000..59e17dcd --- /dev/null +++ b/app/models/deploy_localized_domain.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Soportar dominios localizados +class DeployLocalizedDomain < DeployAlternativeDomain + store :values, accessors: %i[hostname locale], coder: JSON + + # Generar un link simbólico del sitio principal al alternativo + def deploy(**) + File.symlink?(destination) || + File.symlink(File.join(site.hostname, locale), destination).zero? + end +end diff --git a/app/models/deploy_private.rb b/app/models/deploy_private.rb index 3a6595f9..134c5876 100644 --- a/app/models/deploy_private.rb +++ b/app/models/deploy_private.rb @@ -7,8 +7,8 @@ # jekyll-private-data class DeployPrivate < DeployLocal # No es necesario volver a instalar dependencias - def deploy - jekyll_build + def deploy(output: false) + jekyll_build(output: output) end # Hacer el deploy a un directorio privado diff --git a/app/models/deploy_www.rb b/app/models/deploy_www.rb index 5602b0fc..db552bf2 100644 --- a/app/models/deploy_www.rb +++ b/app/models/deploy_www.rb @@ -6,7 +6,7 @@ class DeployWww < Deploy before_destroy :remove_destination! - def deploy + def deploy(**) File.symlink?(destination) || File.symlink(site.hostname, destination).zero? end diff --git a/app/models/deploy_zip.rb b/app/models/deploy_zip.rb index ec8973d1..f1726e6e 100644 --- a/app/models/deploy_zip.rb +++ b/app/models/deploy_zip.rb @@ -12,7 +12,7 @@ class DeployZip < Deploy # y generar un zip accesible públicamente. # # rubocop:disable Metrics/MethodLength - def deploy + def deploy(**) FileUtils.rm_f path time_start From 6ce0cb2c415a4d78c0e1e085046b8b9ebb46716b Mon Sep 17 00:00:00 2001 From: f Date: Tue, 5 Apr 2022 16:25:47 -0300 Subject: [PATCH 024/109] descartar el deploy si el sitio no existe --- app/jobs/deploy_job.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 70997ce1..6dd4b8eb 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -4,6 +4,8 @@ class DeployJob < ApplicationJob class DeployException < StandardError; end + discard_on ActiveRecord::RecordNotFound + # rubocop:disable Metrics/MethodLength def perform(site, notify = true, time = Time.now) ActiveRecord::Base.connection_pool.with_connection do From 87cdba9bec0a45ab48802c409830478ca045ff6e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Apr 2022 20:07:14 -0300 Subject: [PATCH 025/109] =?UTF-8?q?enviar=20m=C3=A1s=20informaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/deploy_job.rb | 14 ++++++++++++-- app/models/deploy.rb | 4 ++++ app/models/deploy_alternative_domain.rb | 6 +++++- app/models/deploy_hidden_service.rb | 2 +- app/models/deploy_local.rb | 4 ++++ app/models/deploy_private.rb | 4 ++++ app/models/deploy_www.rb | 4 ++++ app/models/deploy_zip.rb | 4 ++++ app/views/deploy_mailer/deployed.html.haml | 9 +++++++-- app/views/deploy_mailer/deployed.text.haml | 7 +++---- config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 12 files changed, 52 insertions(+), 10 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 70997ce1..db91672b 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -27,7 +27,13 @@ class DeployJob < ApplicationJob @site.update status: 'building' # Asegurarse que DeployLocal sea el primero! - @deployed = { deploy_local: deploy_locally } + @deployed = { + deploy_local: { + status: deploy_locally, + seconds: deploy_local.build_stats.last.seconds, + url: site.url + } + } # No es opcional unless @deployed[:deploy_local] @@ -60,7 +66,11 @@ class DeployJob < ApplicationJob def deploy_others @site.deploys.where.not(type: 'DeployLocal').find_each do |d| - @deployed[d.type.underscore.to_sym] = d.deploy + @deployed[d.type.underscore.to_sym] = { + status: d.deploy, + seconds: d.build_stats.last.seconds, + url: d.url + } end end diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 3f034ad5..1aefe126 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -15,6 +15,10 @@ class Deploy < ApplicationRecord raise NotImplementedError end + def url + raise NotImplementedError + end + def limit raise NotImplementedError end diff --git a/app/models/deploy_alternative_domain.rb b/app/models/deploy_alternative_domain.rb index e4960e65..d245ac21 100644 --- a/app/models/deploy_alternative_domain.rb +++ b/app/models/deploy_alternative_domain.rb @@ -18,6 +18,10 @@ class DeployAlternativeDomain < Deploy end def destination - File.join(Rails.root, '_deploy', hostname.gsub(/\.\z/, '')) + @destination ||= File.join(Rails.root, '_deploy', hostname.gsub(/\.\z/, '')) + end + + def url + "https://#{File.basename destination}" end end diff --git a/app/models/deploy_hidden_service.rb b/app/models/deploy_hidden_service.rb index d4d2b822..8df46c2e 100644 --- a/app/models/deploy_hidden_service.rb +++ b/app/models/deploy_hidden_service.rb @@ -13,6 +13,6 @@ class DeployHiddenService < DeployWww end def url - 'http://' + fqdn + "http://#{fqdn}" end end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 4fa588f5..b6fa407f 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -25,6 +25,10 @@ class DeployLocal < Deploy 1 end + def url + site.url + end + # Obtener el tamaño de todos los archivos y directorios (los # directorios son archivos :) def size diff --git a/app/models/deploy_private.rb b/app/models/deploy_private.rb index 3a6595f9..0d79811d 100644 --- a/app/models/deploy_private.rb +++ b/app/models/deploy_private.rb @@ -16,6 +16,10 @@ class DeployPrivate < DeployLocal File.join(Rails.root, '_private', site.name) end + def url + "#{ENV['PANEL_URL']}/sites/private/#{site.name}" + end + # No usar recursos en compresión y habilitar los datos privados def env @env ||= super.merge({ diff --git a/app/models/deploy_www.rb b/app/models/deploy_www.rb index 5602b0fc..3c9feb3b 100644 --- a/app/models/deploy_www.rb +++ b/app/models/deploy_www.rb @@ -27,6 +27,10 @@ class DeployWww < Deploy "www.#{site.hostname}" end + def url + "https://www.#{site.hostname}/" + end + private def remove_destination! diff --git a/app/models/deploy_zip.rb b/app/models/deploy_zip.rb index ec8973d1..0a66b602 100644 --- a/app/models/deploy_zip.rb +++ b/app/models/deploy_zip.rb @@ -49,6 +49,10 @@ class DeployZip < Deploy "#{site.hostname}.zip" end + def url + "#{site.url}#{file}" + end + def path File.join(destination, file) end diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml index e8b2e7af..23e99469 100644 --- a/app/views/deploy_mailer/deployed.html.haml +++ b/app/views/deploy_mailer/deployed.html.haml @@ -8,10 +8,15 @@ %tr %th= t('.th.type') %th= t('.th.status') + %th= t('.th.url') + %th= t('.th.seconds') %tbody - - @deploys.each do |deploy, value| + - @deploys.each_pair do |deploy, value| %tr %td= t(".#{deploy}.title") - %td= value ? t(".#{deploy}.success") : t(".#{deploy}.error") + %td= value[:status] ? t(".#{deploy}.success") : t(".#{deploy}.error") + %td= link_to value[:url], value[:url] + %td + %time{ datetime: "PT#{value[:seconds]}S" }= distance_of_time_in_words value[:seconds].seconds = 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 index 53a9b008..a3073a61 100644 --- a/app/views/deploy_mailer/deployed.text.haml +++ b/app/views/deploy_mailer/deployed.text.haml @@ -3,10 +3,9 @@ = t('.explanation', fqdn: @deploy_local.site.hostname) \ = Terminal::Table.new do |table| - - table << [t('.th.type'), t('.th.status')] + - table << [t('.th.type'), t('.th.status'), t('.th.url'), t('.th.seconds')] - table.add_separator - - @deploys.each do |deploy, value| - - table << [t(".#{deploy}.title"), - value ? t(".#{deploy}.success") : t(".#{deploy}.error")] + - @deploys.each_pair do |deploy, value| + - table << [ t(".#{deploy}.title"), value[:status] ? t(".#{deploy}.success") : t(".#{deploy}.error"), value[:url], distance_of_time_in_words(value[:seconds].seconds) ] \ = t('.help') diff --git a/config/locales/en.yml b/config/locales/en.yml index b814796d..c8df9150 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -76,6 +76,8 @@ en: th: type: Type status: Status + seconds: Duration + url: Address deploy_local: title: Build the site success: Success! diff --git a/config/locales/es.yml b/config/locales/es.yml index a6fbd407..e94f623a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -76,6 +76,8 @@ es: th: type: Tipo status: Estado + seconds: Duración + url: Dirección deploy_local: title: Generar el sitio success: ¡Éxito! From c47b4f179cfa07b492edd3834c162508e2c198dc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Apr 2022 20:16:31 -0300 Subject: [PATCH 026/109] =?UTF-8?q?fixup!=20enviar=20m=C3=A1s=20informaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/deploy_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index db91672b..79cfa134 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -31,7 +31,7 @@ class DeployJob < ApplicationJob deploy_local: { status: deploy_locally, seconds: deploy_local.build_stats.last.seconds, - url: site.url + url: deploy_local.url } } From 92866704249f0fa8d8156557e5e8e8365bab5b79 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Apr 2022 20:42:40 -0300 Subject: [PATCH 027/109] mostrar espacio utilizado --- app/jobs/deploy_job.rb | 2 ++ app/views/deploy_mailer/deployed.html.haml | 2 ++ app/views/deploy_mailer/deployed.text.haml | 2 +- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 5 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 79cfa134..38bb0429 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -31,6 +31,7 @@ class DeployJob < ApplicationJob deploy_local: { status: deploy_locally, seconds: deploy_local.build_stats.last.seconds, + size: deploy_local.build_stats.last.size, url: deploy_local.url } } @@ -69,6 +70,7 @@ class DeployJob < ApplicationJob @deployed[d.type.underscore.to_sym] = { status: d.deploy, seconds: d.build_stats.last.seconds, + size: d.build_stats.last.size, url: d.url } end diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml index 23e99469..0053accf 100644 --- a/app/views/deploy_mailer/deployed.html.haml +++ b/app/views/deploy_mailer/deployed.html.haml @@ -10,6 +10,7 @@ %th= t('.th.status') %th= t('.th.url') %th= t('.th.seconds') + %th= t('.th.size') %tbody - @deploys.each_pair do |deploy, value| %tr @@ -18,5 +19,6 @@ %td= link_to value[:url], value[:url] %td %time{ datetime: "PT#{value[:seconds]}S" }= distance_of_time_in_words value[:seconds].seconds + %td= number_to_human_size value[:size], precision: 2 = 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 index a3073a61..0188c303 100644 --- a/app/views/deploy_mailer/deployed.text.haml +++ b/app/views/deploy_mailer/deployed.text.haml @@ -6,6 +6,6 @@ - table << [t('.th.type'), t('.th.status'), t('.th.url'), t('.th.seconds')] - table.add_separator - @deploys.each_pair do |deploy, value| - - table << [ t(".#{deploy}.title"), value[:status] ? t(".#{deploy}.success") : t(".#{deploy}.error"), value[:url], distance_of_time_in_words(value[:seconds].seconds) ] + - table << [t(".#{deploy}.title"), value[:status] ? t(".#{deploy}.success") : t(".#{deploy}.error"), value[:url], distance_of_time_in_words(value[:seconds].seconds), number_to_human_size(value[:size], precision: 2)] \ = t('.help') diff --git a/config/locales/en.yml b/config/locales/en.yml index c8df9150..75fbcc94 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -77,6 +77,7 @@ en: type: Type status: Status seconds: Duration + size: Space used url: Address deploy_local: title: Build the site diff --git a/config/locales/es.yml b/config/locales/es.yml index e94f623a..73467149 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -77,6 +77,7 @@ es: type: Tipo status: Estado seconds: Duración + size: Espacio ocupado url: Dirección deploy_local: title: Generar el sitio From 9024a13490288013f852a57e2a546161d9e47420 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Apr 2022 20:48:14 -0300 Subject: [PATCH 028/109] algunos deploys no generan build_stats --- app/jobs/deploy_job.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 38bb0429..97438650 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -67,10 +67,13 @@ class DeployJob < ApplicationJob def deploy_others @site.deploys.where.not(type: 'DeployLocal').find_each do |d| + status = d.deploy + build_stat = d.build_stats.last + @deployed[d.type.underscore.to_sym] = { - status: d.deploy, - seconds: d.build_stats.last.seconds, - size: d.build_stats.last.size, + status: status, + seconds: build_stat.try(:seconds) || 0, + size: build_stat.try(:size) || 0, url: d.url } end From ef2589a4f162552d7903f98005cb43303fbdcf65 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 6 Apr 2022 20:51:45 -0300 Subject: [PATCH 029/109] =?UTF-8?q?no=20es=20necesario=20traer=20el=20tama?= =?UTF-8?q?=C3=B1o=20de=20los=20build=5Fstats?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/deploy_job.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 97438650..ae6cb279 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -31,7 +31,7 @@ class DeployJob < ApplicationJob deploy_local: { status: deploy_locally, seconds: deploy_local.build_stats.last.seconds, - size: deploy_local.build_stats.last.size, + size: deploy_local.size, url: deploy_local.url } } @@ -73,7 +73,7 @@ class DeployJob < ApplicationJob @deployed[d.type.underscore.to_sym] = { status: status, seconds: build_stat.try(:seconds) || 0, - size: build_stat.try(:size) || 0, + size: d.size, url: d.url } end From 106029b48f4bba2576e92928dfb9cba857d99de3 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 7 Apr 2022 13:34:12 -0300 Subject: [PATCH 030/109] header --- app/views/deploy_mailer/deployed.text.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/deploy_mailer/deployed.text.haml b/app/views/deploy_mailer/deployed.text.haml index 0188c303..48e8000c 100644 --- a/app/views/deploy_mailer/deployed.text.haml +++ b/app/views/deploy_mailer/deployed.text.haml @@ -3,7 +3,7 @@ = t('.explanation', fqdn: @deploy_local.site.hostname) \ = Terminal::Table.new do |table| - - table << [t('.th.type'), t('.th.status'), t('.th.url'), t('.th.seconds')] + - table << [t('.th.type'), t('.th.status'), t('.th.url'), t('.th.seconds'), t('.th.size')] - table.add_separator - @deploys.each_pair do |deploy, value| - table << [t(".#{deploy}.title"), value[:status] ? t(".#{deploy}.success") : t(".#{deploy}.error"), value[:url], distance_of_time_in_words(value[:seconds].seconds), number_to_human_size(value[:size], precision: 2)] From 026b3879e3fff88a5ca5f997875fc74f9423fa6f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 11 Apr 2022 13:29:42 -0300 Subject: [PATCH 031/109] resolver la ruta real MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit para que en el contenedor los sitios y deploys estén en el mismo sistema de archivos los colocamos en el mismo volumen `data` y los vinculamos a la raíz del proyecto. esto es configurable para los sitios pero no para los deploys. algunas verificaciones de seguridad de jekyll resuelven las rutas reales (`realpath`) de los archivos y fallan porque convierte en el symlink en la ruta real. esto rompe cosas como la previsualización de artículos. closes #5140 closes #5122 closes #5121 closes #5086 closes #4958 --- app/models/site.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 5b78d625..38953543 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -413,7 +413,7 @@ class Site < ApplicationRecord # El directorio donde se almacenan los sitios def self.site_path - @site_path ||= ENV.fetch('SITE_PATH', Rails.root.join('_sites')) + @site_path ||= File.realpath(ENV.fetch('SITE_PATH', Rails.root.join('_sites'))) end def self.default From f9e0ad698b5facc7802e726c3d6354b741b6a8b1 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 11 Apr 2022 14:56:58 -0300 Subject: [PATCH 032/109] reemplazar todos los elementos que traen archivos de public/ --- app/models/post.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/models/post.rb b/app/models/post.rb index cab7665f..9bc51c51 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -93,13 +93,14 @@ class Post # Renderizar lo estrictamente necesario y convertir a HTML para # poder reemplazar valores. html = Nokogiri::HTML document.renderer.render_document - # Las imágenes se cargan directamente desde el repositorio, porque + # Los archivos se cargan directamente desde el repositorio, porque # no son públicas hasta que se publica el artículo. - html.css('img').each do |img| - next if %r{\Ahttps?://} =~ img.attributes['src'] + html.css('img,audio,video,iframe').each do |element| + src = element.attributes['src'] - img.attributes['src'].value = Rails.application.routes.url_helpers.site_static_file_url(site, - file: img.attributes['src'].value) + next unless src&.value&.start_with? 'public/' + + src.value = Rails.application.routes.url_helpers.site_static_file_url(site, file: src.value) end # Notificar a les usuaries que están viendo una previsualización From 02d72f4227a1ce3913bb1b608889e7abded966af Mon Sep 17 00:00:00 2001 From: f Date: Mon, 11 Apr 2022 14:57:28 -0300 Subject: [PATCH 033/109] rubocop --- app/models/post.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/post.rb b/app/models/post.rb index 9bc51c51..9c1fea25 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -29,7 +29,7 @@ class Post # TODO: Reemplazar cuando leamos el contenido del Document # a demanda? def find_layout(path) - IO.foreach(path).lazy.grep(/^layout: /).take(1).first&.split(' ')&.last&.tr('\'', '')&.tr('"', '')&.to_sym + File.foreach(path).lazy.grep(/^layout: /).take(1).first&.split(' ')&.last&.tr('\'', '')&.tr('"', '')&.to_sym end end @@ -114,7 +114,7 @@ class Post # Devuelve una llave para poder guardar el post en una cache def cache_key - 'posts/' + uuid.value + "posts/#{uuid.value}" end def cache_version @@ -124,7 +124,7 @@ class Post # Agregar el timestamp para saber si cambió, siguiendo el módulo # ActiveRecord::Integration def cache_key_with_version - cache_key + '-' + cache_version + "#{cache_key}-#{cache_version}" end # TODO: Convertir a UUID? From c021cf0e0e114665da834388d8cc3589e6cdb3e4 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 11 Apr 2022 15:25:07 -0300 Subject: [PATCH 034/109] actualizar jekyll-images produce una excepcion --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8df2d77e..65f950ce 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -289,7 +289,7 @@ GEM jekyll (~> 4) jekyll-ignore-layouts (0.1.2) jekyll (~> 4) - jekyll-images (0.3.0) + jekyll-images (0.3.2) jekyll (~> 4) ruby-filemagic (~> 0.7) ruby-vips (~> 2) From 78c0bdcc3930c5d6035682ecc2982498f88cd0d6 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Apr 2022 10:39:44 -0300 Subject: [PATCH 035/109] cada deploy puede ejecutar tareas de limpieza MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pero la mayoría no lo va a necesitar --- app/models/deploy.rb | 3 +++ app/models/deploy_local.rb | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 3f034ad5..42bfd345 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -23,6 +23,9 @@ class Deploy < ApplicationRecord raise NotImplementedError end + # Realizar tareas de limpieza. + def cleanup!; end + def time_start @start = Time.now end diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index 4fa588f5..66412df2 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -43,6 +43,17 @@ class DeployLocal < Deploy File.join(Rails.root, '_deploy', site.hostname) end + # Libera espacio eliminando archivos temporales + # + # @return [nil] + def cleanup! + FileUtils.rm_rf(gems_dir) + FileUtils.rm_rf(yarn_cache_dir) + FileUtils.rm_rf(File.join(site.path, 'node_modules')) + FileUtils.rm_rf(File.join(site.path, '.sass-cache')) + FileUtils.rm_rf(File.join(site.path, '.jekyll-cache')) + end + private def mkdir From 1e0fb95825b7aed00d7a5c77512e7cb6c1efa770 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Apr 2022 10:40:18 -0300 Subject: [PATCH 036/109] =?UTF-8?q?correr=20la=20recolecci=C3=B3n=20de=20b?= =?UTF-8?q?asura=20de=20git?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/site/repository.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index 74db2549..f63288d4 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -147,6 +147,23 @@ class Site rugged.index.remove(relativize(file)) end + # Garbage collection + # + # @return [Boolean] + def gc + env = { 'PATH' => '/usr/bin', 'LANG' => ENV['LANG'], 'HOME' => path } + cmd = 'git gc' + + r = nil + Dir.chdir(path) do + Open3.popen2e(env, cmd, unsetenv_others: true) do |_, _, t| + r = t.value + end + end + + r&.success? + end + private # Si Sutty tiene una llave privada de tipo ED25519, devuelve las From 9fefc0f554e7142de3c70efac2a3e66d53b61782 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Apr 2022 10:41:22 -0300 Subject: [PATCH 037/109] abl --- app/services/cleanup_service.rb | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 app/services/cleanup_service.rb diff --git a/app/services/cleanup_service.rb b/app/services/cleanup_service.rb new file mode 100644 index 00000000..ad87cf9a --- /dev/null +++ b/app/services/cleanup_service.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# Realiza tareas de limpieza en todos los sitios, para optimizar y +# liberar espacio. +class CleanupService + # Días de antigüedad de los sitios + attr_reader :before + + # @param :before [ActiveSupport::TimeWithZone] Cuánto tiempo lleva sin usarse un sitio. + def initialize(before: 30.days.ago) + @before = before + end + + # Limpieza general + # + # @return [nil] + def cleanup_everything! + cleanup_older_sites! + cleanup_newer_sites! + end + + # Encuentra todos los sitios sin actualizar y realiza limpieza. + # + # @return [nil] + def cleanup_older_sites! + Site.where('updated_at < ?', before).find_each do |site| + next unless File.directory? site.path + + site.deploys.find_each(&:cleanup!) + + site.repository.gc + site.touch + end + end + + # Tareas para los sitios en uso + # + # @return [nil] + def cleanup_newer_sites! + Site.where('updated_at >= ?', before).find_each do |site| + next unless File.directory? site.path + + site.repository.gc + site.touch + end + end +end From 170cbeb69eeddde6e6176a7dcd8f5dbdb13fe7d2 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Apr 2022 10:41:53 -0300 Subject: [PATCH 038/109] poder hacer limpieza desde la terminal --- lib/tasks/cleanup.rake | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 lib/tasks/cleanup.rake diff --git a/lib/tasks/cleanup.rake b/lib/tasks/cleanup.rake new file mode 100644 index 00000000..e14693bc --- /dev/null +++ b/lib/tasks/cleanup.rake @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +namespace :cleanup do + desc 'Cleanup sites' + task everything: :environment do + before = ENV.fetch('BEFORE', '30').to_i.days.ago + service = CleanupService.new(before: before) + + service.cleanup_everything! + end +end From 3b616198eaf64f122e1a2684ed0e2d345ed38d1e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Apr 2022 10:57:51 -0300 Subject: [PATCH 039/109] realizar la limpieza mensualmente --- .dockerignore | 1 + Dockerfile | 2 ++ Procfile | 8 +------- monit.conf | 30 ++++-------------------------- 4 files changed, 8 insertions(+), 33 deletions(-) diff --git a/.dockerignore b/.dockerignore index afe4e8d7..7b84d429 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,3 +2,4 @@ * # Solo agregar lo que usamos en COPY # !./archivo +!./monit.conf diff --git a/Dockerfile b/Dockerfile index ecf43cbc..342c2750 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,8 @@ RUN apk add --no-cache libxslt libxml2 postgresql-libs libssh2 \ RUN gem install --no-document --no-user-install foreman RUN wget https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-linux-amd64.tar.gz -O - | tar --strip-components 1 -xvzf - pandoc-${PANDOC_VERSION}/bin/pandoc && mv /bin/pandoc /usr/bin/pandoc +COPY ./monit.conf /etc/monit.d/sutty.conf + VOLUME "/srv" EXPOSE 3000 diff --git a/Procfile b/Procfile index b308ffd5..48931e8d 100644 --- a/Procfile +++ b/Procfile @@ -1,7 +1 @@ -migrate: bundle exec rake db:prepare db:seed -sutty: bundle exec puma config.ru -blazer_5m: bundle exec rake blazer:run_checks SCHEDULE="5 minutes" -blazer_1h: bundle exec rake blazer:run_checks SCHEDULE="1 hour" -blazer_1d: bundle exec rake blazer:run_checks SCHEDULE="1 day" -blazer: bundle exec rake blazer:send_failing_checks -prometheus: bundle exec prometheus_exporter -b 0.0.0.0 --prefix "sutty_" +cleanup: rake cleanup:everything diff --git a/monit.conf b/monit.conf index 96c08d8a..07cd1c1e 100644 --- a/monit.conf +++ b/monit.conf @@ -1,27 +1,5 @@ -check process sutty with pidfile /srv/tmp/puma.pid - start program = "/usr/local/bin/sutty start" - stop program = "/usr/local/bin/sutty stop" - -check process prometheus with pidfile /tmp/prometheus.pid - start program = "/usr/local/bin/sutty prometheus start" - stop program = "/usr/local/bin/sutty prometheus start" - -check program blazer_5m - with path "/usr/local/bin/sutty blazer 5m" - every 5 cycles - if status != 0 then alert - -check program blazer_1h - with path "/usr/local/bin/sutty blazer 1h" - every 60 cycles - if status != 0 then alert - -check program blazer_1d - with path "/usr/local/bin/sutty blazer 1d" - every 1440 cycles - if status != 0 then alert - -check program blazer - with path "/usr/local/bin/sutty blazer" - every 61 cycles +# Limpiar mensualmente +check program cleanup + with path "/usr/bin/foreman run -f /srv/Procfile -d /srv " as uid "rails" gid "http-data" + every "0 3 1 * *" if status != 0 then alert From f2eea5fbcbf746bb061fcbfb363f06bf8e68d85f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 18 Apr 2022 17:27:43 -0300 Subject: [PATCH 040/109] no fallar al cerrarse la salida --- app/models/deploy.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 0cc92ff1..b45fa350 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -62,7 +62,10 @@ class Deploy < ApplicationRecord puts line if output end + rescue IOError => e + ExceptionNotifier.notify(e, data: { site: site.name }) end + r = t.value end end From bfeb513b6b5c52265b3a2820165188dbf15662cd Mon Sep 17 00:00:00 2001 From: f Date: Thu, 28 Apr 2022 10:56:47 -0300 Subject: [PATCH 041/109] =?UTF-8?q?agregar=20modo=20de=20slugificaci=C3=B3?= =?UTF-8?q?n=20en=20el=20sitio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_slug.rb | 2 +- db/migrate/20220428135113_add_slugify_mode_to_sites.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20220428135113_add_slugify_mode_to_sites.rb diff --git a/app/models/metadata_slug.rb b/app/models/metadata_slug.rb index 09da23f9..a37451d9 100644 --- a/app/models/metadata_slug.rb +++ b/app/models/metadata_slug.rb @@ -25,7 +25,7 @@ require 'jekyll/utils' class MetadataSlug < MetadataTemplate # Trae el slug desde el título si existe o una string al azar def default_value - title ? Jekyll::Utils.slugify(title) : SecureRandom.uuid + title ? Jekyll::Utils.slugify(title, mode: site.slugify_mode) : SecureRandom.uuid end def value diff --git a/db/migrate/20220428135113_add_slugify_mode_to_sites.rb b/db/migrate/20220428135113_add_slugify_mode_to_sites.rb new file mode 100644 index 00000000..fd887886 --- /dev/null +++ b/db/migrate/20220428135113_add_slugify_mode_to_sites.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Permite a los sitios elegir el método de slugificación +class AddSlugifyModeToSites < ActiveRecord::Migration[6.1] + def change + add_column :sites, :slugify_mode, :string, default: 'default' + end +end From cadb3ad6a6fb00547df734a10271d0a4069d7a1c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 28 Apr 2022 10:57:28 -0300 Subject: [PATCH 042/109] normalizar unicode en la string --- app/models/metadata_slug.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_slug.rb b/app/models/metadata_slug.rb index a37451d9..b0fe8cec 100644 --- a/app/models/metadata_slug.rb +++ b/app/models/metadata_slug.rb @@ -39,6 +39,6 @@ class MetadataSlug < MetadataTemplate return if post.title&.private? return if post.title&.value&.blank? - post.title&.value&.to_s + post.title&.value&.to_s&.unicode_normalize end end From 87c09323dc60f1f21856edec9330efcc673fa0ef Mon Sep 17 00:00:00 2001 From: f Date: Thu, 5 May 2022 19:37:14 -0300 Subject: [PATCH 043/109] ignorar posts sin layout pero notificar closes #5828 closes #3251 --- app/models/site.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/site.rb b/app/models/site.rb index 7d4875e5..141baf22 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -230,6 +230,8 @@ class Site < ApplicationRecord layout = layouts[Post.find_layout(doc.path)] @posts[lang].build(document: doc, layout: layout, lang: lang) + rescue TypeError => e + ExceptionNotifier.notify_exception(e, data: { site: name, site_id: id, path: doc.path }) end @posts[lang] From a0441a858e960360997d412ce44192f4393e49a3 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 11 Jun 2022 19:51:11 -0300 Subject: [PATCH 044/109] comandos correctos --- Procfile | 2 +- monit.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Procfile b/Procfile index 48931e8d..112b6042 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -cleanup: rake cleanup:everything +cleanup: bundle exec rake cleanup:everything diff --git a/monit.conf b/monit.conf index 07cd1c1e..ea6925fd 100644 --- a/monit.conf +++ b/monit.conf @@ -1,5 +1,5 @@ # Limpiar mensualmente check program cleanup - with path "/usr/bin/foreman run -f /srv/Procfile -d /srv " as uid "rails" gid "http-data" + with path "/usr/bin/foreman run -f /srv/Procfile -d /srv cleanup" as uid "rails" gid "http-data" every "0 3 1 * *" if status != 0 then alert From 369b0c9937ea1b7baf8112d36e17b7df2f5dd45c Mon Sep 17 00:00:00 2001 From: f Date: Sat, 11 Jun 2022 19:52:38 -0300 Subject: [PATCH 045/109] fixup! comandos correctos --- monit.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monit.conf b/monit.conf index ea6925fd..20e4c703 100644 --- a/monit.conf +++ b/monit.conf @@ -1,5 +1,5 @@ # Limpiar mensualmente check program cleanup - with path "/usr/bin/foreman run -f /srv/Procfile -d /srv cleanup" as uid "rails" gid "http-data" + with path "/usr/bin/foreman run -f /srv/Procfile -d /srv cleanup" as uid "rails" gid "www-data" every "0 3 1 * *" if status != 0 then alert From a4eef2edc096db2e185e94b3aa5588e72e9e02bf Mon Sep 17 00:00:00 2001 From: f Date: Tue, 28 Jun 2022 15:07:08 -0300 Subject: [PATCH 046/109] =?UTF-8?q?notificar=20correctamente=20la=20excepc?= =?UTF-8?q?i=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index b45fa350..1c730c06 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -63,7 +63,7 @@ class Deploy < ApplicationRecord puts line if output end rescue IOError => e - ExceptionNotifier.notify(e, data: { site: site.name }) + ExceptionNotifier.notify_exception(e, data: { site: site.name }) end r = t.value From d18536f5871bc860d749edfdea3f9765e47d98d3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 29 Jun 2022 18:41:51 -0300 Subject: [PATCH 047/109] no generar issues para log --- app/models/deploy.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/deploy.rb b/app/models/deploy.rb index 1c730c06..65159bce 100644 --- a/app/models/deploy.rb +++ b/app/models/deploy.rb @@ -63,7 +63,8 @@ class Deploy < ApplicationRecord puts line if output end rescue IOError => e - ExceptionNotifier.notify_exception(e, data: { site: site.name }) + lines << e.message + puts e.message if output end r = t.value From 9e531e49955801bd41a4a8a48ca8d764ebfe342a Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Jul 2022 15:38:16 -0300 Subject: [PATCH 048/109] no cambiar el valor si no se pudo cargar el archivo esto hace que sutilmente desaparezcan archivos --- app/models/metadata_file.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index 71d3f049..2b628a57 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -41,14 +41,10 @@ class MetadataFile < MetadataTemplate end # Asociar la imagen subida al sitio y obtener la ruta - # - # XXX: Si evitamos guardar cambios con changed? no tenemos forma de - # saber que un archivo subido manualmente se convirtió en - # un Attachment y cada vez que lo editemos vamos a subir una imagen - # repetida. + # @return [Boolean] def save value['description'] = sanitize value['description'] - value['path'] = static_file ? relative_destination_path_with_filename.to_s : nil + value['path'] = relative_destination_path_with_filename.to_s if static_file true end From 0b06bf35417b1f23176f798611c70ffc49822985 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Jul 2022 15:39:08 -0300 Subject: [PATCH 049/109] notificar cuando no se pudo cargar el archivo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit no perder información silenciosamente --- app/models/metadata_file.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index 2b628a57..942b448d 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -58,9 +58,6 @@ class MetadataFile < MetadataTemplate # * El archivo es una ruta que apunta a un archivo asociado al sitio # * El archivo es una ruta a un archivo dentro del repositorio # - # XXX: La última opción provoca archivos duplicados, pero es lo mejor - # que tenemos hasta que resolvamos https://0xacab.org/sutty/sutty/-/issues/213 - # # @todo encontrar una forma de obtener el attachment sin tener que # recurrir al último subido. # @@ -77,8 +74,12 @@ class MetadataFile < MetadataTemplate site.static_files.last.tap do |s| s.blob.update(key: key_from_path) end + else + raise ArgumentError, 'No se pudo subir el archivo' end end + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, path: value['path'] }) end # Obtiene la ruta absoluta al archivo From def4402313e0d142b72321192c1b09783fdfe520 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Jul 2022 15:39:42 -0300 Subject: [PATCH 050/109] permitir cargar archivos con la misma key podemos tener sitios distintos con la misma llave identificatoria. ahora permitimos solo una llave por cada sitio distinto. si subimos un archivo duplicado en un mismo sitio el error va a seguir siendo el mismo. --- app/models/metadata_file.rb | 2 +- ...nge_blob_key_uniqueness_to_include_service_name.rb | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20220712135053_change_blob_key_uniqueness_to_include_service_name.rb diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index 942b448d..fa570ac0 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -68,7 +68,7 @@ class MetadataFile < MetadataTemplate when ActionDispatch::Http::UploadedFile site.static_files.last if site.static_files.attach(value['path']) when String - if (blob_id = ActiveStorage::Blob.where(key: key_from_path).pluck(:id).first) + if (blob_id = ActiveStorage::Blob.where(key: key_from_path, service_name: site.name).pluck(:id).first) site.static_files.find_by(blob_id: blob_id) elsif path? && pathname.exist? && site.static_files.attach(io: pathname.open, filename: pathname.basename) site.static_files.last.tap do |s| diff --git a/db/migrate/20220712135053_change_blob_key_uniqueness_to_include_service_name.rb b/db/migrate/20220712135053_change_blob_key_uniqueness_to_include_service_name.rb new file mode 100644 index 00000000..00bae7ea --- /dev/null +++ b/db/migrate/20220712135053_change_blob_key_uniqueness_to_include_service_name.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# Cambia el índice único para incluir el nombre del servicio, de forma +# que podamos tener varias copias del mismo sitio (por ejemplo para +# test) sin que falle la creación de archivos. +class ChangeBlobKeyUniquenessToIncludeServiceName < ActiveRecord::Migration[6.1] + def change + remove_index :active_storage_blobs, %i[key], unique: true + add_index :active_storage_blobs, %i[key service_name], unique: true + end +end From cd523babade074fd69471e9c54cf1c391a2730da Mon Sep 17 00:00:00 2001 From: f Date: Tue, 12 Jul 2022 15:58:31 -0300 Subject: [PATCH 051/109] siempre devolver Pathname closes #6982 closes #6979 closes #6974 closes #6973 closes #6972 closes #6970 closes #6968 closes #6967 --- app/models/metadata_file.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index fa570ac0..4ea026b4 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -126,7 +126,7 @@ class MetadataFile < MetadataTemplate rescue Errno::ENOENT => e ExceptionNotifier.notify_exception(e) - value['path'] + Pathname.new(value['path']) end def relative_destination_path_with_filename From aab8ed9fed5c1411da527814a78e5ad7db132bd6 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Jul 2022 13:34:45 -0300 Subject: [PATCH 052/109] =?UTF-8?q?informar=20cuando=20el=20nombre=20de=20?= =?UTF-8?q?archivo=20est=C3=A1=20vac=C3=ADo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/lib/active_storage/service/jekyll_service.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/lib/active_storage/service/jekyll_service.rb b/app/lib/active_storage/service/jekyll_service.rb index 92b26e0e..3edd2653 100644 --- a/app/lib/active_storage/service/jekyll_service.rb +++ b/app/lib/active_storage/service/jekyll_service.rb @@ -67,7 +67,9 @@ module ActiveStorage # @param :key [String] # @return [String] def filename_for(key) - ActiveStorage::Blob.where(key: key).limit(1).pluck(:filename).first + ActiveStorage::Blob.where(key: key).limit(1).pluck(:filename).first.tap do |filename| + raise ArgumentError, "Filename for key #{key} is blank" if filename.blank? + end end # Crea una ruta para la llave con un nombre conocido. From 5397ae66a2709aeb30da2dbb2b9064cf3e42e8c7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 13 Jul 2022 14:18:39 -0300 Subject: [PATCH 053/109] informar con mas detalle cuando el archivo no existe closes #6991 closes #6990 closes #6985 closes #6969 closes #6966 --- app/models/metadata_file.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index 4ea026b4..00ac7af0 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -124,13 +124,15 @@ class MetadataFile < MetadataTemplate # devolvemos la ruta original, que puede ser el archivo que no existe # o vacía si se está subiendo uno. rescue Errno::ENOENT => e - ExceptionNotifier.notify_exception(e) + ExceptionNotifier.notify_exception(e, data: { site: site.name, path: value['path'] }) Pathname.new(value['path']) end def relative_destination_path_with_filename destination_path_with_filename.relative_path_from(Pathname.new(site.path).realpath) + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, path: value['path'] }) end def static_file_path From 83384b686af0ddb9be18ee3fbbb10d1a9d3ea899 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Jul 2022 18:22:06 -0300 Subject: [PATCH 054/109] solo copiar el archivo si no existe --- app/lib/active_storage/service/jekyll_service.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/lib/active_storage/service/jekyll_service.rb b/app/lib/active_storage/service/jekyll_service.rb index 3edd2653..88ffa83c 100644 --- a/app/lib/active_storage/service/jekyll_service.rb +++ b/app/lib/active_storage/service/jekyll_service.rb @@ -20,6 +20,18 @@ module ActiveStorage end end + # Solo copiamos el archivo si no existe + # + # @param :key [String] + # @param :io [IO] + # @param :checksum [String] + def upload(key, io, checksum: nil, **) + instrument :upload, key: key, checksum: checksum do + IO.copy_stream(io, make_path_for(key)) unless exist?(key) + ensure_integrity_of(key, checksum) if checksum + end + end + # Lo mismo que en DiskService agregando el nombre de archivo en la # firma. Esto permite que luego podamos guardar el archivo donde # corresponde. From 6c62c20572a1a763ceb23b62eea924fed4b86e25 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 15 Jul 2022 19:32:06 -0300 Subject: [PATCH 055/109] subir directamente los archivos a la base de datos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cuando subimos un archivo usando attach en realidad estábamos generando una copia y dejándola huérfana en el repositorio del sitio. usando blob podemos imitar un servicio de subida de archivos sin generar io innecesario. --- app/models/metadata_file.rb | 42 ++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index 00ac7af0..c7296de4 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -68,18 +68,8 @@ class MetadataFile < MetadataTemplate when ActionDispatch::Http::UploadedFile site.static_files.last if site.static_files.attach(value['path']) when String - if (blob_id = ActiveStorage::Blob.where(key: key_from_path, service_name: site.name).pluck(:id).first) - site.static_files.find_by(blob_id: blob_id) - elsif path? && pathname.exist? && site.static_files.attach(io: pathname.open, filename: pathname.basename) - site.static_files.last.tap do |s| - s.blob.update(key: key_from_path) - end - else - raise ArgumentError, 'No se pudo subir el archivo' - end + site.static_files.find_by(blob_id: blob_id) || migrate_static_file! end - rescue ArgumentError => e - ExceptionNotifier.notify_exception(e, data: { site: site.name, path: value['path'] }) end # Obtiene la ruta absoluta al archivo @@ -95,7 +85,7 @@ class MetadataFile < MetadataTemplate # # @return [String] def key_from_path - pathname.dirname.basename.to_s + @key_from_path ||= pathname.dirname.basename.to_s end def path? @@ -148,4 +138,32 @@ class MetadataFile < MetadataTemplate def no_file_for_description? !path? && description? end + + # Obtiene el id del blob asociado + # + # @return [Integer,nil] + def blob_id + @blob_id ||= ActiveStorage::Blob.where(key: key_from_path, service_name: site.name).pluck(:id).first + end + + # Genera el blob para un archivo que ya se encuentra en el + # repositorio y lo agrega a la base de datos. + # + # @return [ActiveStorage::Attachment] + def migrate_static_file! + raise ArgumentError, 'El archivo no existe' unless path? && pathname.exist? + + Site.transaction do + blob = + ActiveStorage::Blob.create_after_unfurling!(key: key_from_path, + io: pathname.open, + filename: pathname.basename, + service_name: site.name) + + ActiveStorage::Attachment.create!(name: 'static_files', record: site, blob: blob) + end + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { site: site.name, path: value['path'] }) + nil + end end From 0d6a2c020c0a7efa0f16c3af41d70cafc41f688a Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Jul 2022 13:49:59 -0300 Subject: [PATCH 056/109] reindexar los sitios al terminar de compilarlos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit para poder soportar modificaciones durante la generación del sitio --- app/models/deploy_reindex.rb | 19 +++++++++++++++++++ app/views/deploys/_deploy_reindex.haml | 1 + config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 4 files changed, 28 insertions(+) create mode 100644 app/models/deploy_reindex.rb create mode 100644 app/views/deploys/_deploy_reindex.haml diff --git a/app/models/deploy_reindex.rb b/app/models/deploy_reindex.rb new file mode 100644 index 00000000..d2ff0679 --- /dev/null +++ b/app/models/deploy_reindex.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# Reindexa los artículos al terminar la compilación +class DeployReindex < Deploy + def deploy + site.reset + site.indexed_posts.destroy_all + site.index_posts! + site.touch + end + + def limit + 1 + end + + def hostname + nil + end +end diff --git a/app/views/deploys/_deploy_reindex.haml b/app/views/deploys/_deploy_reindex.haml new file mode 100644 index 00000000..af058968 --- /dev/null +++ b/app/views/deploys/_deploy_reindex.haml @@ -0,0 +1 @@ +-# NADA diff --git a/config/locales/en.yml b/config/locales/en.yml index 530a9381..b08ddc95 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -102,6 +102,10 @@ en: title: Alternative domain name success: Success! error: Error + deploy_reindex: + title: Reindex + success: Success! + error: Error help: You can contact us by replying to this e-mail maintenance_mailer: notice: diff --git a/config/locales/es.yml b/config/locales/es.yml index eaa23137..026f2bc5 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -102,6 +102,10 @@ es: title: Dominio alternativo success: ¡Éxito! error: Hubo un error + deploy_reindex: + title: Reindexación + success: ¡Éxito! + error: Hubo un error help: Por cualquier duda, responde este correo para contactarte con nosotres. maintenance_mailer: notice: From b983353223c8f46e8c03a4d9a6336500e011fc57 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Jul 2022 14:13:54 -0300 Subject: [PATCH 057/109] =?UTF-8?q?log=20de=20reindexaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_reindex.rb | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/app/models/deploy_reindex.rb b/app/models/deploy_reindex.rb index d2ff0679..2bc8f642 100644 --- a/app/models/deploy_reindex.rb +++ b/app/models/deploy_reindex.rb @@ -3,12 +3,29 @@ # Reindexa los artículos al terminar la compilación class DeployReindex < Deploy def deploy + time_start + site.reset - site.indexed_posts.destroy_all - site.index_posts! + + Site.transaction do + site.indexed_posts.destroy_all + site.index_posts! + end + + time_stop + + build_stats.create action: 'reindex', + log: 'Reindex', + seconds: time_spent_in_seconds, + bytes: size, + status: true site.touch end + def size + 0 + end + def limit 1 end From 70ee31325467db20b0f33fcf67d999846e838c85 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Jul 2022 14:50:46 -0300 Subject: [PATCH 058/109] tampoco tienen url --- app/models/deploy_reindex.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/deploy_reindex.rb b/app/models/deploy_reindex.rb index 2bc8f642..921451d9 100644 --- a/app/models/deploy_reindex.rb +++ b/app/models/deploy_reindex.rb @@ -33,4 +33,8 @@ class DeployReindex < Deploy def hostname nil end + + def url + nil + end end From d5f6d3c61b5ccee54f1ef58f7bfdbe1063fd09c8 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 3 Aug 2022 12:56:39 -0300 Subject: [PATCH 059/109] =?UTF-8?q?no=20compartir=20el=20uuid=20del=20post?= =?UTF-8?q?=20con=20su=20indexaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit aunque los uuid son únicos, en el contexto de un sitio los posts son únicos por cada sitio. si tenemos sitios duplicados (por ejemplo un sitio de testing), la indexación funciona pero va moviendo posts de un panel a otro. ahora los uuid de cada post se guardan por separado y las indexaciones tienen sus propios uuids únicos. por ahora no los estamos usando para nada, pero cuando tengamos permalinks, los registros van a estar relacionados con sus posts indexados. --- app/models/post/indexable.rb | 3 +-- ...53308_indexed_posts_by_uuid_and_site_id.rb | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20220802153308_indexed_posts_by_uuid_and_site_id.rb diff --git a/app/models/post/indexable.rb b/app/models/post/indexable.rb index 7757e7f7..48dc6b0d 100644 --- a/app/models/post/indexable.rb +++ b/app/models/post/indexable.rb @@ -14,9 +14,8 @@ class Post # # @return [IndexedPost] def to_index - IndexedPost.find_or_create_by(id: uuid.value).tap do |indexed_post| + IndexedPost.find_or_create_by(post_id: uuid.value, site_id: site.id).tap do |indexed_post| indexed_post.layout = layout.name - indexed_post.site_id = site.id indexed_post.path = path.basename indexed_post.locale = locale.value indexed_post.dictionary = IndexedPost.to_dictionary(locale: locale.value) diff --git a/db/migrate/20220802153308_indexed_posts_by_uuid_and_site_id.rb b/db/migrate/20220802153308_indexed_posts_by_uuid_and_site_id.rb new file mode 100644 index 00000000..e6572ffb --- /dev/null +++ b/db/migrate/20220802153308_indexed_posts_by_uuid_and_site_id.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# No podemos compartir el uuid entre indexed_posts y posts porque +# podemos tener sitios duplicados. Al menos hasta que los sitios de +# testeo estén integrados en el panel vamos a tener que generar otros +# UUID. +class IndexedPostsByUuidAndSiteId < ActiveRecord::Migration[6.1] + def up + add_column :indexed_posts, :post_id, :uuid, index: true + + IndexedPost.transaction do + ActiveRecord::Base.connection.execute('update indexed_posts set post_id = id where post_id is null') + end + end + + def down + remove_column :indexed_posts, :post_id + end +end From 3e442865ab8d5f7559f5fb42e80dc27eed003647 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 3 Aug 2022 13:11:06 -0300 Subject: [PATCH 060/109] permitir indexar --- app/models/post/indexable.rb | 6 +++--- app/models/site/index.rb | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/models/post/indexable.rb b/app/models/post/indexable.rb index 48dc6b0d..4e46d7b2 100644 --- a/app/models/post/indexable.rb +++ b/app/models/post/indexable.rb @@ -14,7 +14,7 @@ class Post # # @return [IndexedPost] def to_index - IndexedPost.find_or_create_by(post_id: uuid.value, site_id: site.id).tap do |indexed_post| + IndexedPost.find_or_initialize_by(post_id: uuid.value, site_id: site.id).tap do |indexed_post| indexed_post.layout = layout.name indexed_post.path = path.basename indexed_post.locale = locale.value @@ -27,8 +27,6 @@ class Post end end - private - # Indexa o reindexa el Post # # @return [Boolean] @@ -40,6 +38,8 @@ class Post to_index.destroy.destroyed? end + private + # Los metadatos que se almacenan como objetos JSON. Empezamos con # las categorías porque se usan para filtrar en el listado de # artículos. diff --git a/app/models/site/index.rb b/app/models/site/index.rb index e10fa523..e11095e3 100644 --- a/app/models/site/index.rb +++ b/app/models/site/index.rb @@ -14,9 +14,7 @@ class Site def index_posts! Site.transaction do - docs.each do |post| - post.to_index.save - end + docs.each(&:index!) end end end From fff679b98184f5ab0ee20e30bb40382f3aed483c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 3 Aug 2022 13:23:03 -0300 Subject: [PATCH 061/109] no devolver un destino closes #7151 closes #7152 closes #7153 closes #7154 closes #7167 closes #7168 closes #7169 closes #7170 closes #7380 closes #7381 closes #7382 closes #7383 closes #7394 closes #7395 closes #7396 closes #7397 closes #7405 closes #7406 closes #7407 closes #7408 closes #7491 closes #7492 closes #7493 closes #7494 closes #7509 closes #7510 closes #7511 closes #7512 closes #7527 closes #7528 closes #7529 closes #7530 --- app/models/deploy_reindex.rb | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/app/models/deploy_reindex.rb b/app/models/deploy_reindex.rb index 921451d9..d6b2be65 100644 --- a/app/models/deploy_reindex.rb +++ b/app/models/deploy_reindex.rb @@ -30,11 +30,9 @@ class DeployReindex < Deploy 1 end - def hostname - nil - end + def hostname; end - def url - nil - end + def url; end + + def destination; end end From 2d0090c488b2befff5b7eca8b01a8641b2489e4b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 Aug 2022 18:00:18 -0300 Subject: [PATCH 062/109] usar el uuid del post para reordenar --- app/views/posts/index.haml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 90d65670..70748570 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -93,15 +93,15 @@ TODO: Solo les usuaries cachean porque tenemos que separar les botones por permisos. - cache_if @usuarie, [post, I18n.locale] do - - checkbox_id = "checkbox-#{post.id}" - %tr{ id: post.id, data: { target: 'reorder.row' } } + - checkbox_id = "checkbox-#{post.post_id}" + %tr{ id: post.post_id, data: { target: 'reorder.row' } } %td .custom-control.custom-checkbox %input.custom-control-input{ id: checkbox_id, type: 'checkbox', autocomplete: 'off', data: { action: 'reorder#select' } } %label.custom-control-label{ for: checkbox_id } %span.sr-only= t('posts.reorder.select') -# Orden más alto es mayor prioridad - = hidden_field 'post[reorder]', post.id, + = hidden_field 'post[reorder]', post.post_id, value: size - i, data: { reorder: true } %td.w-100{ class: dir } From 0afe4b6aba50264634045b05bee6ecf3ec033425 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 27 Aug 2022 19:30:52 -0300 Subject: [PATCH 063/109] permitir a les usuaries elegir idioma y registrarse con ese --- app/controllers/application_controller.rb | 2 +- app/models/usuarie.rb | 9 +++++++++ app/views/devise/registrations/new.haml | 2 +- app/views/devise/shared/_links.haml | 14 ++++++++------ app/views/layouts/_breadcrumb.haml | 3 +++ 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index acd0134d..823e3264 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -54,7 +54,7 @@ class ApplicationController < ActionController::Base # corresponde con el idioma de los artículos, porque puede querer # traducirlos. def set_locale(&action) - I18n.with_locale(current_locale(include_params: false), &action) + I18n.with_locale(current_locale(include_params: params[:controller].start_with?('devise')), &action) end # Muestra una página 404 diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index 6de7ba4b..9126885a 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -9,6 +9,8 @@ class Usuarie < ApplicationRecord validates_uniqueness_of :email validates_with EmailAddress::ActiveRecordValidator, field: :email + before_create :lang_from_locale! + has_many :roles has_many :sites, through: :roles @@ -36,4 +38,11 @@ class Usuarie < ApplicationRecord increment_failed_attempts lock_access! if attempts_exceeded? && !access_locked? end + + private + + def lang_from_locale! + binding.pry + self.lang = I18n.locale.to_s + end end diff --git a/app/views/devise/registrations/new.haml b/app/views/devise/registrations/new.haml index cb6ff0d1..21676556 100644 --- a/app/views/devise/registrations/new.haml +++ b/app/views/devise/registrations/new.haml @@ -8,7 +8,7 @@ = form_for(resource, as: resource_name, - url: registration_path(resource_name)) do |f| + url: registration_path(resource_name, params: { locale: params[:locale] })) do |f| = render 'devise/shared/error_messages', resource: resource diff --git a/app/views/devise/shared/_links.haml b/app/views/devise/shared/_links.haml index c182d323..c8a6c041 100644 --- a/app/views/devise/shared/_links.haml +++ b/app/views/devise/shared/_links.haml @@ -1,35 +1,37 @@ %hr/ +- locale = params.permit(:locale) + - if controller_name != 'sessions' - = link_to t('.sign_in'), new_session_path(resource_name) + = link_to t('.sign_in'), new_session_path(resource_name, params: locale) %br/ - if devise_mapping.registerable? && controller_name != 'registrations' - = link_to t('.sign_up'), new_registration_path(resource_name), + = link_to t('.sign_up'), new_registration_path(resource_name, params: locale), class: 'btn btn-lg btn-block btn-success' %br/ - if devise_mapping.recoverable? - unless %w[passwords registrations].include?(controller_name) = link_to t('.forgot_your_password'), - new_password_path(resource_name) + new_password_path(resource_name, params: locale) %br/ - if devise_mapping.confirmable? && controller_name != 'confirmations' = link_to t('.didn_t_receive_confirmation_instructions'), - new_confirmation_path(resource_name) + new_confirmation_path(resource_name, params: locale) %br/ - if devise_mapping.lockable? - if resource_class.unlock_strategy_enabled?(:email) - if controller_name != 'unlocks' = link_to t('.didn_t_receive_unlock_instructions'), - new_unlock_path(resource_name) + new_unlock_path(resource_name, params: locale) %br/ - if devise_mapping.omniauthable? - resource_class.omniauth_providers.each do |provider| = link_to t('.sign_in_with_provider', provider: OmniAuth::Utils.camelize(provider)), - omniauth_authorize_path(resource_name, provider) + omniauth_authorize_path(resource_name, provider, params: locale) %br/ diff --git a/app/views/layouts/_breadcrumb.haml b/app/views/layouts/_breadcrumb.haml index c4920bc7..04375ca4 100644 --- a/app/views/layouts/_breadcrumb.haml +++ b/app/views/layouts/_breadcrumb.haml @@ -22,3 +22,6 @@ %li.nav-item = link_to t('.logout'), destroy_usuarie_session_path, method: :delete, role: 'button', class: 'btn' + - else + - other_locale = I18n.available_locales.find { |locale| locale != I18n.locale } + = link_to t(other_locale), "?locale=#{other_locale}" From 3595342d3a2df840e7b040c50b6151a010fe3f9d Mon Sep 17 00:00:00 2001 From: f Date: Sat, 3 Sep 2022 10:51:58 -0300 Subject: [PATCH 064/109] pry! --- app/models/usuarie.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index 9126885a..605eb819 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -42,7 +42,6 @@ class Usuarie < ApplicationRecord private def lang_from_locale! - binding.pry self.lang = I18n.locale.to_s end end From 6c7ddb082df96249cf0c20b7e021b1ba2e8d48a2 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 1 Nov 2022 13:08:06 -0300 Subject: [PATCH 065/109] fix: no guardar el valor en texto plano si estuvo cifrado MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cuando un campo está cifrado y no fue modificado, al guardar se guardaba en texto plano y luego salían errores de decifrado. closes #1515 closes #1938 closes #1939 closes #1940 closes #1942 closes #1943 closes #1944 closes #8204 --- app/models/metadata_template.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/metadata_template.rb b/app/models/metadata_template.rb index c778e1b2..5de54be1 100644 --- a/app/models/metadata_template.rb +++ b/app/models/metadata_template.rb @@ -134,7 +134,11 @@ MetadataTemplate = Struct.new(:site, :document, :name, :label, :type, # En caso de que algún campo necesite realizar acciones antes de ser # guardado def save - return true unless changed? + if !changed? + self[:value] = document_value if private? + + return true + end self[:value] = sanitize value self[:value] = encrypt(value) if private? From 3d8c9b4031d4290a27c3faaecd02323f6b9c6a77 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 1 Nov 2022 13:17:03 -0300 Subject: [PATCH 066/109] feat: implementar campo de tipo password #8342 --- app/models/metadata_password.rb | 25 +++++++++++++++++++++ app/views/posts/attribute_ro/_password.haml | 6 +++++ app/views/posts/attributes/_password.haml | 7 ++++++ config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 5 files changed, 42 insertions(+) create mode 100644 app/models/metadata_password.rb create mode 100644 app/views/posts/attribute_ro/_password.haml create mode 100644 app/views/posts/attributes/_password.haml diff --git a/app/models/metadata_password.rb b/app/models/metadata_password.rb new file mode 100644 index 00000000..1e0e2698 --- /dev/null +++ b/app/models/metadata_password.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# Almacena una contraseña +class MetadataPassword < MetadataString + # Las contraseñas no son indexables + # + # @return [boolean] + def indexable? + false + end + + private + + alias_method :original_sanitize, :sanitize + + # Sanitizar la string y generar un hash Bcrypt + # + # @param :string [String] + # @return [String] + def sanitize(string) + string = original_sanitize string + + ::BCrypt::Password.create(string).to_s + end +end diff --git a/app/views/posts/attribute_ro/_password.haml b/app/views/posts/attribute_ro/_password.haml new file mode 100644 index 00000000..e55b021f --- /dev/null +++ b/app/views/posts/attribute_ro/_password.haml @@ -0,0 +1,6 @@ +%tr{ id: attribute } + %th= post_label_t(attribute, post: post) + %td{ dir: dir, lang: locale } + = metadata.value + %br/ + %small= t('.safety') diff --git a/app/views/posts/attributes/_password.haml b/app/views/posts/attributes/_password.haml new file mode 100644 index 00000000..0aace30f --- /dev/null +++ b/app/views/posts/attributes/_password.haml @@ -0,0 +1,7 @@ +.form-group + = label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post) + = password_field base, attribute, value: metadata.value, + dir: dir, lang: locale, + **field_options(attribute, metadata) + = render 'posts/attribute_feedback', + post: post, attribute: attribute, metadata: metadata diff --git a/config/locales/en.yml b/config/locales/en.yml index 530a9381..b9d4d8f9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -414,6 +414,8 @@ en: attribute_ro: file: download: Download file + password: + safety: Passwords are stored safely show: front_matter: Post metadata submit: diff --git a/config/locales/es.yml b/config/locales/es.yml index eaa23137..b737f5c2 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -422,6 +422,8 @@ es: attribute_ro: file: download: Descargar archivo + password: + safety: Las contraseñas se almacenan de forma segura show: front_matter: Metadatos del artículo submit: From f582e692ef784fcea3fd2a264afc324d4c9fb5bb Mon Sep 17 00:00:00 2001 From: f Date: Wed, 9 Nov 2022 18:43:55 -0300 Subject: [PATCH 067/109] =?UTF-8?q?fix:=20explicar=20mejor=20por=20qu?= =?UTF-8?q?=C3=A9=20no=20es=20una=20preview=20completa=20#8400?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/en.yml | 2 +- config/locales/es.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 530a9381..ec5171ec 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -475,7 +475,7 @@ en: preview: btn: 'Preliminary version' alert: 'Not every article type has a preliminary version' - message: 'This is a preliminary version, use the Publish changes button back on the panel to publish the article onto your site.' + message: 'This is a preview of your post with some contextual elements from your site.' open: 'Tip: You can add new options by typing them and pressing Enter' private: '🔒 The values of this field will remain private' select: diff --git a/config/locales/es.yml b/config/locales/es.yml index eaa23137..b9f45032 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -483,7 +483,7 @@ es: preview: btn: 'Versión preliminar' alert: 'No todos los tipos de artículos poseen vista preliminar :)' - message: 'Esta es una versión preliminar, para que el artículo aparezca en tu sitio utiliza el botón Publicar cambios en el panel' + message: 'Esta es la vista previa de tu artículo, con algunos elementos contextuales del sitio' open: 'Nota: Puedes agregar más opciones a medida que las escribes y presionas Entrar' private: '🔒 Los valores de este campo serán privados' select: From b141b09ee452aa75e92b5755ffe24b549333a345 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 9 Nov 2022 18:44:27 -0300 Subject: [PATCH 068/109] fix: poder mostrar la vista previa sin errores de liquid closes #8397 closes #8263 closes #8153 --- app/models/post.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/post.rb b/app/models/post.rb index cab7665f..3e824108 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -90,6 +90,10 @@ class Post 'page' => document.to_liquid } + # No tener errores de Liquid + site.jekyll.config['liquid']['strict_filters'] = false + site.jekyll.config['liquid']['strict_variables'] = false + # Renderizar lo estrictamente necesario y convertir a HTML para # poder reemplazar valores. html = Nokogiri::HTML document.renderer.render_document From 5a5d41448237870e5c8c5d1d763b3502d1f56e28 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 11 Nov 2022 19:09:38 -0300 Subject: [PATCH 069/109] =?UTF-8?q?fix:=20traducci=C3=B3n=20de=20algunos?= =?UTF-8?q?=20locales=20en=20uso=20#8427?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/locales/en.yml | 9 +++++++++ config/locales/es.yml | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index 530a9381..a07533a9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -13,6 +13,15 @@ en: ar: name: Arabic dir: rtl + zh: + name: Chinese + dir: ltr + de: + name: German + dir: ltr + fr: + name: French + dir: ltr login: email: E-mail address password: Password diff --git a/config/locales/es.yml b/config/locales/es.yml index eaa23137..3d6a2e10 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -13,6 +13,15 @@ es: ar: name: Árabe dir: rtl + zh: + name: Chino + dir: ltr + de: + name: Alemán + dir: ltr + fr: + name: Francés + dir: ltr login: email: Correo electrónico password: Contraseña From 4fc2ece2d5bd7f913559a9a501bd6a724ef01fa4 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 28 Nov 2022 19:30:20 -0300 Subject: [PATCH 070/109] =?UTF-8?q?fix:=20permitir=20borrar=20la=20imagen?= =?UTF-8?q?=20sin=20vaciar=20la=20descripci=C3=B3n=20#8347?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sin embargo no estamos pudiendo distinguir entre imagen borrada e imagen sin subir, con lo que perdimos una verificación --- app/models/metadata_file.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index c7296de4..e67761b2 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -23,7 +23,6 @@ class MetadataFile < MetadataTemplate errors << I18n.t("metadata.#{type}.site_invalid") if site.invalid? errors << I18n.t("metadata.#{type}.path_required") if path_missing? - errors << I18n.t("metadata.#{type}.no_file_for_description") if no_file_for_description? errors << I18n.t("metadata.#{type}.attachment_missing") if path? && !static_file errors.compact! @@ -134,11 +133,6 @@ class MetadataFile < MetadataTemplate end end - # No hay archivo pero se lo describió - def no_file_for_description? - !path? && description? - end - # Obtiene el id del blob asociado # # @return [Integer,nil] From 581e8e10c2af693a9d0b43fc38e398bc12c8b000 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 28 Nov 2022 19:31:09 -0300 Subject: [PATCH 071/109] fix: vaciar la imagen al borrarla --- app/models/metadata_file.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index e67761b2..a155a414 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -42,8 +42,12 @@ class MetadataFile < MetadataTemplate # Asociar la imagen subida al sitio y obtener la ruta # @return [Boolean] def save - value['description'] = sanitize value['description'] - value['path'] = relative_destination_path_with_filename.to_s if static_file + if value['path'].blank? + self[:value] = default_value + else + value['description'] = sanitize value['description'] + value['path'] = relative_destination_path_with_filename.to_s if static_file + end true end From 53b11cba155e4cef51dd5e0801220c5112eae318 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 11 Jan 2023 16:54:45 -0300 Subject: [PATCH 072/109] fix: no devolver 'true' si no existe el archivo closes #9380 closes #9379 closes #9375 closes #9374 closes #9366 closes #8888 closes #8765 closes #8764 closes #8674 closes #8099 closes #8098 closes #7845 closes #7844 closes #7612 closes #7611 closes #9378 closes #9377 closes #9364 closes #9362 --- app/models/metadata_file.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index a155a414..a55549cb 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -122,10 +122,17 @@ class MetadataFile < MetadataTemplate Pathname.new(value['path']) end + # Obtener la ruta relativa al sitio. + # + # Si algo falla, devolver la ruta original para no romper el archivo. + # + # @return [String, nil] def relative_destination_path_with_filename destination_path_with_filename.relative_path_from(Pathname.new(site.path).realpath) rescue ArgumentError => e ExceptionNotifier.notify_exception(e, data: { site: site.name, path: value['path'] }) + + value['path'] end def static_file_path From 5117ffbce3e41ee3315803e25cf3d2f05c8259a9 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 11 Jan 2023 17:04:22 -0300 Subject: [PATCH 073/109] fix: siempre devolver la ruta completa closes #6984 closes #7053 closes #7807 closes #7998 closes #8262 closes #8690 closes #8887 closes #9363 closes #9376 --- app/models/metadata_file.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_file.rb b/app/models/metadata_file.rb index a55549cb..3ac89c9b 100644 --- a/app/models/metadata_file.rb +++ b/app/models/metadata_file.rb @@ -119,7 +119,7 @@ class MetadataFile < MetadataTemplate rescue Errno::ENOENT => e ExceptionNotifier.notify_exception(e, data: { site: site.name, path: value['path'] }) - Pathname.new(value['path']) + Pathname.new(File.join(site.path, value['path'])) end # Obtener la ruta relativa al sitio. From 2352ce52ec4ee784ca5e1b82859e7070e0c06871 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 12 Jan 2023 13:40:43 -0300 Subject: [PATCH 074/109] fix: no filtrar la url del panel en sitios proxeados #9386 --- app/controllers/api/v1/notices_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v1/notices_controller.rb b/app/controllers/api/v1/notices_controller.rb index cd44130c..436c78b5 100644 --- a/app/controllers/api/v1/notices_controller.rb +++ b/app/controllers/api/v1/notices_controller.rb @@ -15,7 +15,7 @@ module Api params: airbrake_params.to_h end - render status: 201, json: { id: 1, url: root_url } + render status: 201, json: { id: 1, url: '' } end private From 247e069f2b3a7bc7907f2c388467f0c8d8d082cc Mon Sep 17 00:00:00 2001 From: f Date: Thu, 12 Jan 2023 14:24:21 -0300 Subject: [PATCH 075/109] fix: fast_jsonparser 0.6.0 da segfaults #9386 --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 1e476dde..6ecb7456 100644 --- a/Gemfile +++ b/Gemfile @@ -89,7 +89,7 @@ gem 'stackprof' gem 'prometheus_exporter' # debug -gem 'fast_jsonparser' +gem 'fast_jsonparser', '~> 0.5.0' gem 'down' gem 'sourcemap' gem 'rack-cors' From b091b3212a71fa182be5ddb884f700faec05f3ae Mon Sep 17 00:00:00 2001 From: f Date: Wed, 8 Feb 2023 18:55:05 -0300 Subject: [PATCH 076/109] feat: refactorizar mailer para que use menos recursors y soporte varias urls --- app/jobs/deploy_job.rb | 4 +- app/mailers/deploy_mailer.rb | 63 ++++++++++++++++++---- app/views/deploy_mailer/deployed.html.haml | 31 +++++------ app/views/deploy_mailer/deployed.text.haml | 12 ++--- 4 files changed, 73 insertions(+), 37 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index ae6cb279..6250cf73 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -32,7 +32,7 @@ class DeployJob < ApplicationJob status: deploy_locally, seconds: deploy_local.build_stats.last.seconds, size: deploy_local.size, - url: deploy_local.url + urls: [deploy_local.url] } } @@ -74,7 +74,7 @@ class DeployJob < ApplicationJob status: status, seconds: build_stat.try(:seconds) || 0, size: d.size, - url: d.url + urls: d.respond_to?(:urls) ? d.urls : [d.url] } end end diff --git a/app/mailers/deploy_mailer.rb b/app/mailers/deploy_mailer.rb index 1d0c7308..aeb13676 100644 --- a/app/mailers/deploy_mailer.rb +++ b/app/mailers/deploy_mailer.rb @@ -8,21 +8,64 @@ # TODO: Agregar firma GPG y header Autocrypt # TODO: Cifrar con GPG si le usuarie nos dio su llave class DeployMailer < ApplicationMailer + include ActionView::Helpers::NumberHelper + include ActionView::Helpers::DateHelper + # 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') + def deployed(deploys) + usuarie = Usuarie.find(params[:usuarie]) + site = usuarie.sites.find(params[:site]) + subject = t('.subject', site: site.name) + hostname = site.hostname + + @hi = t('.hi') + @explanation = t('.explanation', fqdn: hostname) + @help = t('.help') + + @headers = %w[type status url seconds size].map do |header| + t(".th.#{header}") + end + + @table = deploys.each_pair.map do |deploy, value| + { + title: t(".#{deploy}.title"), + status: t(".#{deploy}.#{value[:status] ? 'success' : 'error'}"), + urls: value[:urls], + seconds: { + human: distance_of_time_in_words(value[:seconds].seconds), + machine: "PT#{value[:seconds]}S" + }, + size: number_to_human_size(value[:size], precision: 2) + } + end + + @terminal_table = Terminal::Table.new do |t| + t << @headers + t.add_separator + @table.each do |row| + row[:urls].each do |url| + t << (row.map do |k, v| + case k + when :seconds then v[:human] + when :urls then url + else v + end + end) + end + end + end # 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('deploy_mailer.deployed.subject', - site: @site.name)) + I18n.with_locale(usuarie.lang) do + mail(to: usuarie.email, reply_to: "sutty@#{Site.domain}", subject: subject) end end # rubocop:enable Metrics/AbcSize + + private + + def t(key, **args) + I18n.t("deploy_mailer.deployed#{key}", **args) + end end diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml index 0053accf..20548f16 100644 --- a/app/views/deploy_mailer/deployed.html.haml +++ b/app/views/deploy_mailer/deployed.html.haml @@ -1,24 +1,21 @@ -%h1= t('.hi') +%h1= @hi -= sanitize_markdown t('.explanation', fqdn: @deploy_local.site.hostname), - tags: %w[p a strong em] += sanitize_markdown @explanation, tags: %w[p a strong em] %table %thead %tr - %th= t('.th.type') - %th= t('.th.status') - %th= t('.th.url') - %th= t('.th.seconds') - %th= t('.th.size') + - @headers.each do |header| + %th= header %tbody - - @deploys.each_pair do |deploy, value| - %tr - %td= t(".#{deploy}.title") - %td= value[:status] ? t(".#{deploy}.success") : t(".#{deploy}.error") - %td= link_to value[:url], value[:url] - %td - %time{ datetime: "PT#{value[:seconds]}S" }= distance_of_time_in_words value[:seconds].seconds - %td= number_to_human_size value[:size], precision: 2 + - @table.each do |row| + - row[:urls].each do |url| + %tr + %td= row[:title] + %td= row[:status] + %td= link_to url, url + %td + %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] + %td= row[:size] -= sanitize_markdown t('.help'), tags: %w[p a strong em] += sanitize_markdown @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 index 48e8000c..b2d0416f 100644 --- a/app/views/deploy_mailer/deployed.text.haml +++ b/app/views/deploy_mailer/deployed.text.haml @@ -1,11 +1,7 @@ -= '# ' + t('.hi') += "# #{@hi}" \ -= t('.explanation', fqdn: @deploy_local.site.hostname) += @explanation \ -= Terminal::Table.new do |table| - - table << [t('.th.type'), t('.th.status'), t('.th.url'), t('.th.seconds'), t('.th.size')] - - table.add_separator - - @deploys.each_pair do |deploy, value| - - table << [t(".#{deploy}.title"), value[:status] ? t(".#{deploy}.success") : t(".#{deploy}.error"), value[:url], distance_of_time_in_words(value[:seconds].seconds), number_to_human_size(value[:size], precision: 2)] += @terminal_table \ -= t('.help') += @help From e81f188147e062400721dcd609eef5d62d8f089c Mon Sep 17 00:00:00 2001 From: f Date: Wed, 8 Feb 2023 19:30:05 -0300 Subject: [PATCH 077/109] =?UTF-8?q?fix:=20no=20generar=20links=20si=20la?= =?UTF-8?q?=20url=20viene=20vac=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/deploy_mailer/deployed.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/deploy_mailer/deployed.html.haml b/app/views/deploy_mailer/deployed.html.haml index 20548f16..f5afe5de 100644 --- a/app/views/deploy_mailer/deployed.html.haml +++ b/app/views/deploy_mailer/deployed.html.haml @@ -13,7 +13,7 @@ %tr %td= row[:title] %td= row[:status] - %td= link_to url, url + %td= link_to_if url.present?, url, url %td %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] %td= row[:size] From d821f143058eb515062a55e397a25ad58cd687fd Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Mar 2023 15:08:48 -0300 Subject: [PATCH 078/109] fix: temporalmente deshabilitar el boton #9989 --- app/views/posts/show.haml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index e46114af..64daee41 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -6,13 +6,6 @@ edit_site_post_path(@site, @post.id), class: 'btn btn-block' - - unless @post.layout.ignored? - = link_to t('posts.preview.btn'), - site_post_preview_path(@site, @post.id), - class: 'btn btn-block', - target: '_blank', - rel: 'noopener' - %table.table.table-condensed %thead %tr From 611a1f0eb043807d8ebc96cca88fb37fa6d5cf83 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Mar 2023 15:08:48 -0300 Subject: [PATCH 079/109] fix: temporalmente deshabilitar el boton #9989 --- app/views/posts/show.haml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index e46114af..64daee41 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -6,13 +6,6 @@ edit_site_post_path(@site, @post.id), class: 'btn btn-block' - - unless @post.layout.ignored? - = link_to t('posts.preview.btn'), - site_post_preview_path(@site, @post.id), - class: 'btn btn-block', - target: '_blank', - rel: 'noopener' - %table.table.table-condensed %thead %tr From ffce90daf3af38634a5892fb6bf4111f4f29f2d9 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Mar 2023 15:13:43 -0300 Subject: [PATCH 080/109] =?UTF-8?q?wip:=20no=20mostrar=20errores=20al=20te?= =?UTF-8?q?ner=20errores=20de=20renderizaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pero no muestra nada de nada --- app/models/post.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/post.rb b/app/models/post.rb index cab7665f..bb2afd3c 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -108,6 +108,10 @@ class Post # Cacofonía html.to_html.html_safe + rescue Liquid::Error => e + ExceptionNotifier.notify(e, data: { site: site.name, post: post.id }) + + '' end end From 866b11ff74ff3eba6095389340f62761029cff2a Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 17:29:13 -0300 Subject: [PATCH 081/109] fix: poder distinguir entre errores de deploy --- app/jobs/deploy_job.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 70997ce1..84119416 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -3,6 +3,7 @@ # Realiza el deploy de un sitio class DeployJob < ApplicationJob class DeployException < StandardError; end + class DeployTimedOutException < DeployException; end # rubocop:disable Metrics/MethodLength def perform(site, notify = true, time = Time.now) @@ -17,7 +18,7 @@ class DeployJob < ApplicationJob if @site.building? if 10.minutes.ago >= time @site.update status: 'waiting' - raise DeployException, + raise DeployTimedOutException, "#{@site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" end From e62172e37a188effecdf1319f9e76991dbaa3192 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 18:46:22 -0300 Subject: [PATCH 082/109] =?UTF-8?q?chore:=20secar=20el=20c=C3=B3digo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit la primera hipótesis sobre #10031 es que las excepciones cancelan la actualización de la información, como si fueran una transacción, pero haciendo pruebas manuales no pasa. con este cambio al menos el código queda más limpio. --- app/jobs/deploy_job.rb | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 84119416..9c0ed1dd 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -17,7 +17,6 @@ class DeployJob < ApplicationJob # hora original para poder ir haciendo timeouts. if @site.building? if 10.minutes.ago >= time - @site.update status: 'waiting' raise DeployTimedOutException, "#{@site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" end @@ -32,17 +31,13 @@ class DeployJob < ApplicationJob # No es opcional unless @deployed[:deploy_local] - @site.update status: 'waiting' - notify_usuaries if notify - # Hacer fallar la tarea raise DeployException, deploy_local.build_stats.last.log end deploy_others - - # Volver a la espera - @site.update status: 'waiting' + ensure + @site&.update status: 'waiting' notify_usuaries if notify end From 6a7a0dddda284fde2e2eb9f6c8b493e45b407d50 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 18:46:56 -0300 Subject: [PATCH 083/109] fix: no notificar al liberar la tarea --- app/jobs/deploy_job.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 9c0ed1dd..2165ed11 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -17,6 +17,7 @@ class DeployJob < ApplicationJob # hora original para poder ir haciendo timeouts. if @site.building? if 10.minutes.ago >= time + notify = false raise DeployTimedOutException, "#{@site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" end From 955786be0e6a48a88e55510b0e16de595b7680ea Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 18:52:15 -0300 Subject: [PATCH 084/109] =?UTF-8?q?fix:=20cancelar=20la=20compilaci=C3=B3n?= =?UTF-8?q?=20al=20primer=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recupera el comportamiento de #1716 #1730 #1735 #1738 #1739 #1740 #1741 #1743 #1744 #1746 #1832 #1952 #2057 #2058 #2059 #2062 #1104 #1124 #1152 #1153 #1154 #1175 #1191 #1230 #1303 #1461 #1478 #1609 #1610 #1667 #504 --- app/jobs/deploy_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 2165ed11..9f58e3a1 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -31,7 +31,7 @@ class DeployJob < ApplicationJob @deployed = { deploy_local: deploy_locally } # No es opcional - unless @deployed[:deploy_local] + unless @deployed[:deploy_local][:status] # Hacer fallar la tarea raise DeployException, deploy_local.build_stats.last.log end From 1d08b3fdcd080c28702b6a692827399a1c828bd8 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 19:04:55 -0300 Subject: [PATCH 085/109] fix: llegar hasta el final aunque fallen algunos metodos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit al usar ensure en el commit anterior, podemos garantizar que cualquier excepción en otros deploys no deja la compilación en estado de compilación permanente, pero no se notifica a les usuaries. --- app/jobs/deploy_job.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 9f58e3a1..2dacf08e 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -58,6 +58,10 @@ class DeployJob < ApplicationJob def deploy_others @site.deploys.where.not(type: 'DeployLocal').find_each do |d| @deployed[d.type.underscore.to_sym] = d.deploy + rescue StandardError => e + @deployed[d.type.underscore.to_sym] = false + + ExceptionNotifier.notify_exception(e, data: { site: site.id, deploy: d.type }) end end From efe3474f5f4db5bb0b47ab9c4bab6db84691022f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 19:14:36 -0300 Subject: [PATCH 086/109] fix: hay deploys sin url --- app/jobs/deploy_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 48366bb9..6dd93129 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -78,7 +78,7 @@ class DeployJob < ApplicationJob status: status, seconds: seconds || 0, size: d.size, - urls: d.respond_to?(:urls) ? d.urls : [d.url] + urls: d.respond_to?(:urls) ? d.urls : [d.url].compact } end end From e0a7232643bbad491887d121bb7a237ac95b6923 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 19:27:03 -0300 Subject: [PATCH 087/109] fix: notificar las excepciones manualmente MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit por alguna razón sucker punch dejó de enviarlas! --- app/jobs/deploy_job.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index 2dacf08e..e187b6bd 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -37,6 +37,8 @@ class DeployJob < ApplicationJob end deploy_others + rescue DeployException => e + notify_exception e ensure @site&.update status: 'waiting' @@ -47,6 +49,12 @@ class DeployJob < ApplicationJob private + # @param :exception [StandardError] + # @param :deploy [Deploy] + def notify_exception(exception, deploy = nil) + ExceptionNotifier.notify_exception(exception, data: { site: @site.id, deploy: deploy&.type }) + end + def deploy_local @deploy_local ||= @site.deploys.find_by(type: 'DeployLocal') end From 8c5a1096107d7fb904ba327d83e3af12f2f4743d Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 20:04:18 -0300 Subject: [PATCH 088/109] fix: informar cuando no se puede procesar un issue --- app/jobs/gitlab_notifier_job.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/jobs/gitlab_notifier_job.rb b/app/jobs/gitlab_notifier_job.rb index 7218f68a..129697ba 100644 --- a/app/jobs/gitlab_notifier_job.rb +++ b/app/jobs/gitlab_notifier_job.rb @@ -3,6 +3,8 @@ # Notifica excepciones a una instancia de Gitlab, como incidencias # nuevas o como comentarios a las incidencias pre-existentes. class GitlabNotifierJob < ApplicationJob + class GitlabNotifierError < StandardError; end + include ExceptionNotifier::BacktraceCleaner # Variables que vamos a acceder luego @@ -18,22 +20,28 @@ class GitlabNotifierJob < ApplicationJob @issue_data = { count: 1 } # Necesitamos saber si el issue ya existía @cached = false + @issue = {} # Traemos los datos desde la caché si existen, sino generamos un # issue nuevo e inicializamos la caché @issue_data = Rails.cache.fetch(cache_key) do - issue = client.new_issue confidential: true, title: title, description: description, issue_type: 'incident' + @issue = client.new_issue confidential: true, title: title, description: description, issue_type: 'incident' @cached = true { count: 1, - issue: issue['iid'], + issue: @issue['iid'], user_agents: [user_agent].compact, params: [request&.filtered_parameters].compact, urls: [url].compact } end + unless @issue['iid'] + Rails.cache.delete(cache_key) + raise GitlabNotifierError, @issue.dig('message', 'title')&.join(', ') + end + # No seguimos actualizando si acabamos de generar el issue return if cached From a0263ad3fbaed7238a9e017e29a89665e009d6aa Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 20:04:53 -0300 Subject: [PATCH 089/109] =?UTF-8?q?fix:=20el=20log=20completo=20hace=20un?= =?UTF-8?q?=20t=C3=ADtulo=20demasiado=20largo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/deploy_job.rb | 10 ++++++++-- app/jobs/gitlab_notifier_job.rb | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index e187b6bd..b411568e 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -33,7 +33,7 @@ class DeployJob < ApplicationJob # No es opcional unless @deployed[:deploy_local][:status] # Hacer fallar la tarea - raise DeployException, deploy_local.build_stats.last.log + raise DeployException, 'Falló la compilación' end deploy_others @@ -52,7 +52,13 @@ class DeployJob < ApplicationJob # @param :exception [StandardError] # @param :deploy [Deploy] def notify_exception(exception, deploy = nil) - ExceptionNotifier.notify_exception(exception, data: { site: @site.id, deploy: deploy&.type }) + data = { + site: @site.id, + deploy: deploy&.type, + log: deploy&.build_stats&.last&.log + } + + ExceptionNotifier.notify_exception(exception, data: data) end def deploy_local diff --git a/app/jobs/gitlab_notifier_job.rb b/app/jobs/gitlab_notifier_job.rb index 129697ba..701c6789 100644 --- a/app/jobs/gitlab_notifier_job.rb +++ b/app/jobs/gitlab_notifier_job.rb @@ -112,6 +112,7 @@ class GitlabNotifierJob < ApplicationJob # @return [String] def description @description ||= ''.dup.tap do |d| + d << log_section d << request_section d << javascript_section d << javascript_footer @@ -159,6 +160,19 @@ class GitlabNotifierJob < ApplicationJob @client ||= GitlabApiClient.new end + # @return [String] + def log_section + return '' unless options[:log] + + <<~LOG + # Log + + ``` + #{options[:log]} + ``` + LOG + end + # Muestra información de la petición # # @return [String] From 6bac8ed65dbb413715631a9477bbd2abc038f8b3 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 13 Mar 2023 20:11:12 -0300 Subject: [PATCH 090/109] fix: agrupar por sitio y enviar el log --- app/jobs/deploy_job.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index b411568e..961f8d69 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -33,12 +33,14 @@ class DeployJob < ApplicationJob # No es opcional unless @deployed[:deploy_local][:status] # Hacer fallar la tarea - raise DeployException, 'Falló la compilación' + raise DeployException, "#{@site.name}: Falló la compilación" end deploy_others - rescue DeployException => e + rescue DeployTimedOutException => e notify_exception e + rescue DeployException => e + notify_exception e, deploy_local ensure @site&.update status: 'waiting' From 222cc8f62656486c08d6f48e1e3a95c164053f4d Mon Sep 17 00:00:00 2001 From: f Date: Tue, 14 Mar 2023 16:45:39 -0300 Subject: [PATCH 091/109] fix: volver a traducir los correos #9941 --- app/mailers/deploy_mailer.rb | 74 ++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/app/mailers/deploy_mailer.rb b/app/mailers/deploy_mailer.rb index aeb13676..7d939940 100644 --- a/app/mailers/deploy_mailer.rb +++ b/app/mailers/deploy_mailer.rb @@ -18,46 +18,46 @@ class DeployMailer < ApplicationMailer subject = t('.subject', site: site.name) hostname = site.hostname - @hi = t('.hi') - @explanation = t('.explanation', fqdn: hostname) - @help = t('.help') - - @headers = %w[type status url seconds size].map do |header| - t(".th.#{header}") - end - - @table = deploys.each_pair.map do |deploy, value| - { - title: t(".#{deploy}.title"), - status: t(".#{deploy}.#{value[:status] ? 'success' : 'error'}"), - urls: value[:urls], - seconds: { - human: distance_of_time_in_words(value[:seconds].seconds), - machine: "PT#{value[:seconds]}S" - }, - size: number_to_human_size(value[:size], precision: 2) - } - end - - @terminal_table = Terminal::Table.new do |t| - t << @headers - t.add_separator - @table.each do |row| - row[:urls].each do |url| - t << (row.map do |k, v| - case k - when :seconds then v[:human] - when :urls then url - else v - end - end) - end - end - end - # 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 + @hi = t('.hi') + @explanation = t('.explanation', fqdn: hostname) + @help = t('.help') + + @headers = %w[type status url seconds size].map do |header| + t(".th.#{header}") + end + + @table = deploys.each_pair.map do |deploy, value| + { + title: t(".#{deploy}.title"), + status: t(".#{deploy}.#{value[:status] ? 'success' : 'error'}"), + urls: value[:urls], + seconds: { + human: distance_of_time_in_words(value[:seconds].seconds), + machine: "PT#{value[:seconds]}S" + }, + size: number_to_human_size(value[:size], precision: 2) + } + end + + @terminal_table = Terminal::Table.new do |t| + t << @headers + t.add_separator + @table.each do |row| + row[:urls].each do |url| + t << (row.map do |k, v| + case k + when :seconds then v[:human] + when :urls then url + else v + end + end) + end + end + end + mail(to: usuarie.email, reply_to: "sutty@#{Site.domain}", subject: subject) end end From 51c7c57572177632f1971dd8fba61fe1533e2fdd Mon Sep 17 00:00:00 2001 From: f Date: Tue, 14 Mar 2023 16:48:44 -0300 Subject: [PATCH 092/109] fix: strings #10030 --- config/locales/en.yml | 4 ++++ config/locales/es.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index b814796d..6aa9acd3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -100,6 +100,10 @@ en: title: Alternative domain name success: Success! error: Error + deploy_localized_domain: + title: Domain name by language + success: Success! + error: Error help: You can contact us by replying to this e-mail maintenance_mailer: notice: diff --git a/config/locales/es.yml b/config/locales/es.yml index a6fbd407..ff916b07 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -100,6 +100,10 @@ es: title: Dominio alternativo success: ¡Éxito! error: Hubo un error + deploy_localized_domain: + title: Dominio según idioma + success: ¡Éxito! + error: Hubo un error help: Por cualquier duda, responde este correo para contactarte con nosotres. maintenance_mailer: notice: From 77e209ac9704185fad57271df9a5f058e0583f4e Mon Sep 17 00:00:00 2001 From: f Date: Tue, 14 Mar 2023 19:23:17 -0300 Subject: [PATCH 093/109] fix: traducir el asunto #9941 --- app/mailers/deploy_mailer.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/mailers/deploy_mailer.rb b/app/mailers/deploy_mailer.rb index 7d939940..25efb18d 100644 --- a/app/mailers/deploy_mailer.rb +++ b/app/mailers/deploy_mailer.rb @@ -15,12 +15,13 @@ class DeployMailer < ApplicationMailer def deployed(deploys) usuarie = Usuarie.find(params[:usuarie]) site = usuarie.sites.find(params[:site]) - subject = t('.subject', site: site.name) hostname = site.hostname # 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 + subject = t('.subject', site: site.name) + @hi = t('.hi') @explanation = t('.explanation', fqdn: hostname) @help = t('.help') From 8b479d1743a2dd94603b550024ccff9639ad5304 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Mar 2023 18:22:20 -0300 Subject: [PATCH 094/109] refactor: convertir deploy en un servicio --- app/controllers/sites_controller.rb | 4 +--- app/services/site_service.rb | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb index b4826226..f0eff0dc 100644 --- a/app/controllers/sites_controller.rb +++ b/app/controllers/sites_controller.rb @@ -68,9 +68,7 @@ class SitesController < ApplicationController def enqueue authorize site - # XXX: Convertir en una máquina de estados? - site.enqueue! - DeployJob.perform_async site.id + SiteService.new(site: site).deploy redirect_to site_posts_path(site, locale: site.default_locale) end diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 22423bb8..e9a134b5 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -3,6 +3,11 @@ # Se encargar de guardar cambios en sitios # TODO: Implementar rollback en la configuración SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do + def deploy + site.enqueue! + DeployJob.perform_async site.id + end + # Crea un sitio, agrega un rol nuevo y guarda los cambios a la # configuración en el repositorio git def create From 805eb28273abf02fce6853e8c792fb81532dbd17 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Mar 2023 18:23:06 -0300 Subject: [PATCH 095/109] feat: publicar cambios apenas se crea el sitio #2466 --- app/services/site_service.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/services/site_service.rb b/app/services/site_service.rb index e9a134b5..9e5a4988 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -24,6 +24,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do add_licencias + deploy + site end From bf45707be48b9f850975eefabf118df40a759663 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 16 Mar 2023 13:17:39 -0300 Subject: [PATCH 096/109] fix: obtener correctamente los dominios con www #10452 --- app/controllers/api/v1/sites_controller.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/controllers/api/v1/sites_controller.rb b/app/controllers/api/v1/sites_controller.rb index 32fdae1d..10a92907 100644 --- a/app/controllers/api/v1/sites_controller.rb +++ b/app/controllers/api/v1/sites_controller.rb @@ -69,12 +69,11 @@ module Api end end + # Todos los dominios con WWW habilitado def www_names - Site.where(contact: true) - .or(Site.where(colaboracion_anonima: true)) - .select("'www.' || name as name").map(&:name).map do |name| - canonicalize name - end + Site.where(id: DeployWww.all.pluck(:site_id)).select("'www.' || name as name").map(&:name).map do |name| + canonicalize name + end end end end From 74af7512648f997f34a4ad4ced4b0a7c268101d3 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 16 Mar 2023 18:26:17 -0300 Subject: [PATCH 097/109] feat: al crear un sitio configurarlo con el idioma de le usuarie #10022 --- app/models/site.rb | 11 +++++++++++ app/services/site_service.rb | 9 ++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/models/site.rb b/app/models/site.rb index 8cab0ae0..b8050591 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -179,10 +179,20 @@ class Site < ApplicationRecord # Siempre tiene que tener algo porque las traducciones están # incorporadas a los sitios de Sutty, aunque les usuaries no traduzcan # sus sitios. + # + # @return [Array] def locales @locales ||= config.fetch('locales', I18n.available_locales).map(&:to_sym) end + # Modificar los locales disponibles + # + # @param :new_locales [Array] + # @return [Array] + def locales=(new_locales) + @locales = new_locales.map(&:to_sym).uniq + end + # Similar a site.i18n en jekyll-locales # # @return [Hash] @@ -484,6 +494,7 @@ class Site < ApplicationRecord config.title = title config.url = url(slash: false) config.hostname = hostname + config.locales = locales.map(&:to_s) end # Valida si el sitio tiene al menos una forma de alojamiento asociada diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 22423bb8..d21bd597 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -11,7 +11,14 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do add_role temporal: false, rol: 'usuarie' sync_nodes - I18n.with_locale(usuarie&.lang&.to_sym || I18n.default_locale) do + I18n.with_locale(usuarie.lang.to_sym || I18n.default_locale) do + # No se puede llamar a site.config antes de save porque el sitio + # todavía no existe. + # + # TODO: hacer que el repositorio se cree cuando es necesario, para + # que no haya estados intermedios. + site.locales = [usuarie.lang] + I18n.available_locales + site.save && site.config.write && commit_config(action: :create) From 59bbc04230baeacee6a4dc0ec9b8a2ce3bf6b1ed Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 14:05:47 -0300 Subject: [PATCH 098/109] fix: actualizar el hash solo cuando se escribir cambios y devolver el resultado de Site::Writer#save --- app/models/site/config.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/site/config.rb b/app/models/site/config.rb index 3215277e..d2e78d98 100644 --- a/app/models/site/config.rb +++ b/app/models/site/config.rb @@ -33,10 +33,10 @@ class Site def write return if persisted? - @saved = Site::Writer.new(site: site, file: path, - content: content.to_yaml).save - # Actualizar el hash para no escribir dos veces - @hash = content.hash + @saved = Site::Writer.new(site: site, file: path, content: content.to_yaml).save.tap do |result| + # Actualizar el hash para no escribir dos veces + @hash = content.hash + end end alias save write From 2f3a596fa5033d99c859e2b8cfde0d4175623b8a Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 15:27:06 -0300 Subject: [PATCH 099/109] =?UTF-8?q?feat:=20cambiar=20el=20idioma=20en=20to?= =?UTF-8?q?da=20la=20sesi=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/application_controller.rb | 18 ++++++++++++++---- app/views/layouts/_breadcrumb.haml | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 79fc7d73..c72392c7 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -46,17 +46,19 @@ class ApplicationController < ActionController::Base # defecto. # # Esto se refiere al idioma de la interfaz, no de los artículos. - def current_locale(include_params: true, site: nil) - return params[:locale] if include_params && params[:locale].present? + # + # @return [String,Symbol] + def current_locale + session[:locale] ||= params[:change_locale_to] - current_usuarie&.lang || I18n.locale + session[:locale] || current_usuarie&.lang || I18n.locale end # El idioma es el preferido por le usuarie, pero no necesariamente se # corresponde con el idioma de los artículos, porque puede querer # traducirlos. def set_locale(&action) - I18n.with_locale(current_locale(include_params: params[:controller].start_with?('devise')), &action) + I18n.with_locale(current_locale, &action) end # Muestra una página 404 @@ -88,4 +90,12 @@ class ApplicationController < ActionController::Base def prepare_exception_notifier request.env['exception_notifier.exception_data'] = { usuarie: current_usuarie } end + + # Olvidar el idioma elegido antes de iniciar la sesión y reenviar a + # los sitios en el idioma de le usuarie. + def after_sign_in_path_for(resource) + session[:locale] = nil + + sites_path + end end diff --git a/app/views/layouts/_breadcrumb.haml b/app/views/layouts/_breadcrumb.haml index 131c3281..0823b1be 100644 --- a/app/views/layouts/_breadcrumb.haml +++ b/app/views/layouts/_breadcrumb.haml @@ -24,4 +24,4 @@ method: :delete, role: 'button', class: 'btn' - else - other_locale = I18n.available_locales.find { |locale| locale != I18n.locale } - = link_to t(other_locale), "?locale=#{other_locale}" + = link_to t(other_locale), "?change_locale_to=#{other_locale}" From 5ac72f8b2bec443ef3009164e4dfc4a276df4b44 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 15:32:56 -0300 Subject: [PATCH 100/109] feat: soportar varios idiomas --- app/views/layouts/_breadcrumb.haml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/layouts/_breadcrumb.haml b/app/views/layouts/_breadcrumb.haml index 0823b1be..099ddde4 100644 --- a/app/views/layouts/_breadcrumb.haml +++ b/app/views/layouts/_breadcrumb.haml @@ -23,5 +23,6 @@ = link_to t('.logout'), main_app.destroy_usuarie_session_path, method: :delete, role: 'button', class: 'btn' - else - - other_locale = I18n.available_locales.find { |locale| locale != I18n.locale } - = link_to t(other_locale), "?change_locale_to=#{other_locale}" + - I18n.available_locales.each do |locale| + - next if locale == I18n.locale + = link_to t(locale), "?change_locale_to=#{locale}" From da721ddaaf611cffd33f862d22291b0ffacb7ecd Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 15:49:26 -0300 Subject: [PATCH 101/109] =?UTF-8?q?feat:=20enviar=20el=20idioma=20en=20el?= =?UTF-8?q?=20correo=20de=20confirmaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/devise/mailer/confirmation_instructions.html.haml | 2 +- app/views/devise/mailer/confirmation_instructions.text.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/devise/mailer/confirmation_instructions.html.haml b/app/views/devise/mailer/confirmation_instructions.html.haml index 46706c40..76b10d7f 100644 --- a/app/views/devise/mailer/confirmation_instructions.html.haml +++ b/app/views/devise/mailer/confirmation_instructions.html.haml @@ -1,3 +1,3 @@ %p= t('.greeting', recipient: @email) %p= t('.instruction') -%p= link_to t('.action'), confirmation_url(@resource, confirmation_token: @token) +%p= link_to t('.action'), confirmation_url(@resource, confirmation_token: @token, change_locale_to: @resource.lang) diff --git a/app/views/devise/mailer/confirmation_instructions.text.haml b/app/views/devise/mailer/confirmation_instructions.text.haml index 38e4c548..7123a738 100644 --- a/app/views/devise/mailer/confirmation_instructions.text.haml +++ b/app/views/devise/mailer/confirmation_instructions.text.haml @@ -2,4 +2,4 @@ \ = t('.instruction') \ -= confirmation_url(@resource, confirmation_token: @token) += confirmation_url(@resource, confirmation_token: @token, change_locale_to: @resource.lang) From 6887e5319a8f0c07f493a5543a5849163f3d0e18 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 15:52:10 -0300 Subject: [PATCH 102/109] =?UTF-8?q?feat:=20mantener=20el=20idioma=20de=20l?= =?UTF-8?q?e=20usuarie=20en=20todos=20los=20links=20que=20env=C3=ADe=20dev?= =?UTF-8?q?ise?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/devise/mailer/invitation_instructions.html.haml | 2 +- app/views/devise/mailer/invitation_instructions.text.haml | 2 +- app/views/devise/mailer/reset_password_instructions.html.haml | 2 +- app/views/devise/mailer/reset_password_instructions.text.haml | 2 +- app/views/devise/mailer/unlock_instructions.html.haml | 2 +- app/views/devise/mailer/unlock_instructions.text.haml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/views/devise/mailer/invitation_instructions.html.haml b/app/views/devise/mailer/invitation_instructions.html.haml index 74193878..a2434abd 100644 --- a/app/views/devise/mailer/invitation_instructions.html.haml +++ b/app/views/devise/mailer/invitation_instructions.html.haml @@ -9,7 +9,7 @@ %p= site.description %p= link_to t('devise.mailer.invitation_instructions.accept'), - accept_invitation_url(@resource, invitation_token: @token) + accept_invitation_url(@resource, invitation_token: @token, change_locale_to: @resource.lang) - if @resource.invitation_due_at %p= t('devise.mailer.invitation_instructions.accept_until', diff --git a/app/views/devise/mailer/invitation_instructions.text.haml b/app/views/devise/mailer/invitation_instructions.text.haml index 16a9f0a8..27b1580c 100644 --- a/app/views/devise/mailer/invitation_instructions.text.haml +++ b/app/views/devise/mailer/invitation_instructions.text.haml @@ -9,7 +9,7 @@ \ = site.description \ -= accept_invitation_url(@resource, invitation_token: @token) += accept_invitation_url(@resource, invitation_token: @token, change_locale_to: @resource.lang) \ - if @resource.invitation_due_at = t('devise.mailer.invitation_instructions.accept_until', diff --git a/app/views/devise/mailer/reset_password_instructions.html.haml b/app/views/devise/mailer/reset_password_instructions.html.haml index ccc4aa55..8d8f5919 100644 --- a/app/views/devise/mailer/reset_password_instructions.html.haml +++ b/app/views/devise/mailer/reset_password_instructions.html.haml @@ -1,5 +1,5 @@ %p= t('.greeting', recipient: @resource.email) %p= t('.instruction') -%p= link_to t('.action'), edit_password_url(@resource, reset_password_token: @token) +%p= link_to t('.action'), edit_password_url(@resource, reset_password_token: @token, change_locale_to: @resource.lang) %p= t('.instruction_2') %p= t('.instruction_3') diff --git a/app/views/devise/mailer/reset_password_instructions.text.haml b/app/views/devise/mailer/reset_password_instructions.text.haml index 3d0fe64d..923c2a0c 100644 --- a/app/views/devise/mailer/reset_password_instructions.text.haml +++ b/app/views/devise/mailer/reset_password_instructions.text.haml @@ -2,7 +2,7 @@ \ = t('.instruction') \ -= edit_password_url(@resource, reset_password_token: @token) += edit_password_url(@resource, reset_password_token: @token, change_locale_to: @resource.lang) \ = t('.instruction_2') \ diff --git a/app/views/devise/mailer/unlock_instructions.html.haml b/app/views/devise/mailer/unlock_instructions.html.haml index d68bf7c7..9f8cd492 100644 --- a/app/views/devise/mailer/unlock_instructions.html.haml +++ b/app/views/devise/mailer/unlock_instructions.html.haml @@ -1,4 +1,4 @@ %p= t('.greeting', recipient: @resource.email) %p= t('.message') %p= t('.instruction') -%p= link_to t('.action'), unlock_url(@resource, unlock_token: @token) +%p= link_to t('.action'), unlock_url(@resource, unlock_token: @token, change_locale_to: @resource.lang) diff --git a/app/views/devise/mailer/unlock_instructions.text.haml b/app/views/devise/mailer/unlock_instructions.text.haml index cf06927b..950e04b7 100644 --- a/app/views/devise/mailer/unlock_instructions.text.haml +++ b/app/views/devise/mailer/unlock_instructions.text.haml @@ -4,4 +4,4 @@ \ = t('.instruction') \ -= unlock_url(@resource, unlock_token: @token) += unlock_url(@resource, unlock_token: @token, change_locale_to: @resource.lang) From 0910753437697a1f2e6f1f158a56574fef97390d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 15:53:56 -0300 Subject: [PATCH 103/109] =?UTF-8?q?fix:=20login=20como=20bot=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/devise/shared/_links.haml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/devise/shared/_links.haml b/app/views/devise/shared/_links.haml index c8a6c041..b4b89175 100644 --- a/app/views/devise/shared/_links.haml +++ b/app/views/devise/shared/_links.haml @@ -3,7 +3,8 @@ - locale = params.permit(:locale) - if controller_name != 'sessions' - = link_to t('.sign_in'), new_session_path(resource_name, params: locale) + = link_to t('.sign_in'), new_session_path(resource_name, params: locale), + class: 'btn btn-lg btn-block btn-success' %br/ - if devise_mapping.registerable? && controller_name != 'registrations' From a2660485b8bc3ae7e59435e1755efadf86580d03 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 17 Mar 2023 16:03:11 -0300 Subject: [PATCH 104/109] fix: poder cambiar el idioma! --- app/controllers/application_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c72392c7..e80c279d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -49,7 +49,7 @@ class ApplicationController < ActionController::Base # # @return [String,Symbol] def current_locale - session[:locale] ||= params[:change_locale_to] + session[:locale] = params[:change_locale_to] if params[:change_locale_to].present? session[:locale] || current_usuarie&.lang || I18n.locale end From 50f1ce51d9219149da38aaba5eef0fb37554da17 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 18 Mar 2023 19:14:12 -0300 Subject: [PATCH 105/109] fix: el locale de los posts es distinto al de le usuarie #10454 --- app/controllers/posts_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index c5dc0f54..3c529c24 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -12,7 +12,7 @@ class PostsController < ApplicationController # Las URLs siempre llevan el idioma actual o el de le usuarie def default_url_options - { locale: current_locale } + { locale: locale } end def index From 7160cb01df19c39fe150d3a6479813105acc5ded Mon Sep 17 00:00:00 2001 From: f Date: Sat, 18 Mar 2023 19:22:08 -0300 Subject: [PATCH 106/109] fix: la tienda se activa luego de crear el sitio #10512 --- app/views/sites/_form.haml | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index 6f15d570..9a044c7f 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -104,27 +104,27 @@ %hr/ - .form-group#tienda - %h2= t('.tienda.title') - %p.lead - - if site.tienda? - = t('.tienda.help') - - else - = t('.tienda.first_time_html') - - .row - .col - .form-group - = f.label :tienda_url - = f.url_field :tienda_url, class: 'form-control' - .col - .form-group - = f.label :tienda_api_key - = f.text_field :tienda_api_key, class: 'form-control' - - %hr/ - - if site.persisted? + .form-group#tienda + %h2= t('.tienda.title') + %p.lead + - if site.tienda? + = t('.tienda.help') + - else + = t('.tienda.first_time_html') + + .row + .col + .form-group + = f.label :tienda_url + = f.url_field :tienda_url, class: 'form-control' + .col + .form-group + = f.label :tienda_api_key + = f.text_field :tienda_api_key, class: 'form-control' + + %hr/ + .form-group#contact %h2= t('.contact.title') %p.lead= t('.contact.help') From 1496a6f04bb6ce3c0842bb1791057ee91ce8d1f7 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Mar 2023 11:59:27 -0300 Subject: [PATCH 107/109] fix: a veces no se puede deployear nada closes ##12735 closes ##12733 closes ##12722 closes ##12719 closes ##12716 closes ##10417 --- app/mailers/deploy_mailer.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/mailers/deploy_mailer.rb b/app/mailers/deploy_mailer.rb index 25efb18d..b7b464cb 100644 --- a/app/mailers/deploy_mailer.rb +++ b/app/mailers/deploy_mailer.rb @@ -12,10 +12,11 @@ class DeployMailer < ApplicationMailer include ActionView::Helpers::DateHelper # rubocop:disable Metrics/AbcSize - def deployed(deploys) + def deployed(deploys = {}) usuarie = Usuarie.find(params[:usuarie]) site = usuarie.sites.find(params[:site]) hostname = site.hostname + deploys ||= {} # Informamos a cada quien en su idioma y damos una dirección de # respuesta porque a veces les usuaries nos escriben From b590396a6bba72d890b4f63fbf292558ce69881f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Mar 2023 19:11:33 -0300 Subject: [PATCH 108/109] fix: implementar output --- app/models/deploy_reindex.rb | 2 +- app/models/deploy_rsync.rb | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/deploy_reindex.rb b/app/models/deploy_reindex.rb index d6b2be65..f3eb3d23 100644 --- a/app/models/deploy_reindex.rb +++ b/app/models/deploy_reindex.rb @@ -2,7 +2,7 @@ # Reindexa los artículos al terminar la compilación class DeployReindex < Deploy - def deploy + def deploy(**) time_start site.reset diff --git a/app/models/deploy_rsync.rb b/app/models/deploy_rsync.rb index 996f8cdd..a658de6b 100644 --- a/app/models/deploy_rsync.rb +++ b/app/models/deploy_rsync.rb @@ -5,8 +5,8 @@ class DeployRsync < Deploy store :values, accessors: %i[destination host_keys], coder: JSON - def deploy - ssh? && rsync + def deploy(output: false) + ssh? && rsync(output: output) end # El espacio remoto es el mismo que el local @@ -83,8 +83,8 @@ class DeployRsync < Deploy # Sincroniza hacia el directorio remoto # # @return [Boolean] - def rsync - run %(rsync -aviH --timeout=5 #{Shellwords.escape source}/ #{Shellwords.escape destination}/) + def rsync(output: output) + run %(rsync -aviH --timeout=5 #{Shellwords.escape source}/ #{Shellwords.escape destination}/), output: output end # El origen es el destino de la compilación From 3e6288fefedae54e57bb1ba998d747c78d101808 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 24 Mar 2023 14:36:37 -0300 Subject: [PATCH 109/109] fix: filtrar #12774 --- config/locales/en.yml | 1 + config/locales/es.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index c79bea2d..567ab6bb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -275,6 +275,7 @@ en: stats: index: title: Statistics + filter: "Filter" help: | These statistics show information about how your site is generated and how many resources it uses. diff --git a/config/locales/es.yml b/config/locales/es.yml index 8e4e594b..0a829e4a 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -280,6 +280,7 @@ es: stats: index: title: Estadísticas + filter: "Filtrar" help: | Las estadísticas visibilizan información sobre cómo se genera y cuántos recursos utiliza tu sitio.