From 8fc705158847a10c5c928c703e3a12d6f5a49c6d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 24 Dec 2021 10:08:09 -0300 Subject: [PATCH 01/85] 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 02/85] 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 03/85] 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 04/85] 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 05/85] 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 06/85] 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 07/85] =?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 08/85] 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 09/85] 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 10/85] =?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 11/85] 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 12/85] 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 13/85] 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 14/85] =?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 15/85] =?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 16/85] 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 17/85] 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 18/85] 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 19/85] 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 20/85] 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 21/85] 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 22/85] 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 23/85] 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 24/85] 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 026b3879e3fff88a5ca5f997875fc74f9423fa6f Mon Sep 17 00:00:00 2001 From: f Date: Mon, 11 Apr 2022 13:29:42 -0300 Subject: [PATCH 25/85] 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 26/85] 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 27/85] 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 28/85] 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 29/85] 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 30/85] =?UTF-8?q?correr=20la=20recolecci=C3=B3n=20de=20bas?= =?UTF-8?q?ura=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 31/85] 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 32/85] 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 33/85] 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 34/85] 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 35/85] =?UTF-8?q?agregar=20modo=20de=20slugificaci=C3=B3n?= =?UTF-8?q?=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 36/85] 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 6a7511a5e1c1398f770ca67194acc7b00f935c72 Mon Sep 17 00:00:00 2001 From: Nulo Date: Mon, 2 May 2022 18:55:35 +0000 Subject: [PATCH 37/85] Arreglar scroll al reordenar posts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Utilizaba https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoViewIfNeeded que es propietario. Ahora usa scrollIntoView siempre, configurado para que prácticamente siempre se pueda ver el post al reordenar. --- app/javascript/controllers/reorder_controller.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/app/javascript/controllers/reorder_controller.js b/app/javascript/controllers/reorder_controller.js index dca6e166..2cba4163 100644 --- a/app/javascript/controllers/reorder_controller.js +++ b/app/javascript/controllers/reorder_controller.js @@ -103,11 +103,7 @@ export default class extends Controller { this.reorder() // Mantenemos el primero a la vista - if ("scrollIntoViewIfNeeded" in rows[0].row) { - rows[0].row.scrollIntoViewIfNeeded() - } else { - rows[0].row.scrollIntoView() - } + rows[0].row.scrollIntoView({ block: "center" }); } counter () { @@ -146,7 +142,7 @@ export default class extends Controller { this.reorder() // Mantenemos el primero a la vista - rows[0].row.scrollIntoViewIfNeeded() + rows[0].row.scrollIntoView({ block: "center" }); } bottom (event) { @@ -167,7 +163,7 @@ export default class extends Controller { this.reorder() // Mantenemos el primero a la vista - rows[0].row.scrollIntoViewIfNeeded() + rows[0].row.scrollIntoView({ block: "center" }); } /* From 87c09323dc60f1f21856edec9330efcc673fa0ef Mon Sep 17 00:00:00 2001 From: f Date: Thu, 5 May 2022 19:37:14 -0300 Subject: [PATCH 38/85] 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 39/85] 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 40/85] 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 41/85] =?UTF-8?q?notificar=20correctamente=20la=20excepci?= =?UTF-8?q?=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 42/85] 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 43/85] 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 44/85] 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 45/85] 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 46/85] 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 47/85] =?UTF-8?q?informar=20cuando=20el=20nombre=20de=20ar?= =?UTF-8?q?chivo=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 48/85] 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 49/85] 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 50/85] 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 d5f6d3c61b5ccee54f1ef58f7bfdbe1063fd09c8 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 3 Aug 2022 12:56:39 -0300 Subject: [PATCH 51/85] =?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 52/85] 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 2d0090c488b2befff5b7eca8b01a8641b2489e4b Mon Sep 17 00:00:00 2001 From: f Date: Wed, 24 Aug 2022 18:00:18 -0300 Subject: [PATCH 53/85] 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 54/85] 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 55/85] 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 56/85] 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 57/85] 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 58/85] =?UTF-8?q?fix:=20explicar=20mejor=20por=20qu=C3=A9?= =?UTF-8?q?=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 59/85] 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 60/85] =?UTF-8?q?fix:=20traducci=C3=B3n=20de=20algunos=20l?= =?UTF-8?q?ocales=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 61/85] =?UTF-8?q?fix:=20permitir=20borrar=20la=20imagen=20?= =?UTF-8?q?sin=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 62/85] 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 63/85] 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 64/85] 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 65/85] 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 66/85] 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 d821f143058eb515062a55e397a25ad58cd687fd Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Mar 2023 15:08:48 -0300 Subject: [PATCH 67/85] 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 68/85] 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 69/85] =?UTF-8?q?wip:=20no=20mostrar=20errores=20al=20tene?= =?UTF-8?q?r=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 51c7c57572177632f1971dd8fba61fe1533e2fdd Mon Sep 17 00:00:00 2001 From: f Date: Tue, 14 Mar 2023 16:48:44 -0300 Subject: [PATCH 70/85] 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 8b479d1743a2dd94603b550024ccff9639ad5304 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Mar 2023 18:22:20 -0300 Subject: [PATCH 71/85] 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 72/85] 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 73/85] 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 74/85] 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 75/85] 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 76/85] =?UTF-8?q?feat:=20cambiar=20el=20idioma=20en=20toda?= =?UTF-8?q?=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 77/85] 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 78/85] =?UTF-8?q?feat:=20enviar=20el=20idioma=20en=20el=20?= =?UTF-8?q?correo=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 79/85] =?UTF-8?q?feat:=20mantener=20el=20idioma=20de=20le?= =?UTF-8?q?=20usuarie=20en=20todos=20los=20links=20que=20env=C3=ADe=20devi?= =?UTF-8?q?se?= 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 80/85] =?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 81/85] 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 82/85] 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 83/85] 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 84/85] 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 85/85] 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