From a2669e0aa44a3bcd568535d937a143abe47b26ed Mon Sep 17 00:00:00 2001 From: f Date: Tue, 15 Jun 2021 17:07:52 -0300 Subject: [PATCH 01/99] =?UTF-8?q?actualizaci=C3=B3n=20de=20cuidados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile.lock | 69 +++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 36 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 942d7d6f..e0c19860 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -89,11 +89,11 @@ GEM jekyll-relative-urls (~> 0.0) jekyll-seo-tag (~> 2.1) ast (2.4.2) - autoprefixer-rails (10.2.5.0) - execjs (< 2.8.0) + autoprefixer-rails (10.2.5.1) + execjs (> 0) bcrypt (3.1.16-x86_64-linux-musl) bcrypt_pbkdf (1.1.0-x86_64-linux-musl) - benchmark-ips (2.8.4) + benchmark-ips (2.9.1) bindex (0.8.1-x86_64-linux-musl) blazer (2.4.2) activerecord (>= 5) @@ -104,7 +104,7 @@ GEM autoprefixer-rails (>= 9.1.0) popper_js (>= 1.14.3, < 2) sassc-rails (>= 2.0.0) - brakeman (5.0.1) + brakeman (5.0.4) builder (3.2.4) capybara (2.18.0) addressable @@ -119,9 +119,9 @@ GEM colorator (1.1.0) commonmarker (0.21.2-x86_64-linux-musl) ruby-enum (~> 0.5) - concurrent-ruby (1.1.8) - concurrent-ruby-ext (1.1.8-x86_64-linux-musl) - concurrent-ruby (= 1.1.8) + concurrent-ruby (1.1.9) + concurrent-ruby-ext (1.1.9-x86_64-linux-musl) + concurrent-ruby (= 1.1.9) crass (1.0.6) database_cleaner (2.0.1) database_cleaner-active_record (~> 2.0.0) @@ -157,7 +157,7 @@ GEM dotenv-rails (2.7.6) dotenv (= 2.7.6) railties (>= 3.2) - down (5.2.1) + down (5.2.2) addressable (~> 2.5) ed25519 (1.2.4-x86_64-linux-musl) editorial-autogestiva-jekyll-theme (0.3.4) @@ -188,7 +188,7 @@ GEM exception_notification (4.4.3) actionmailer (>= 4.0, < 7) activesupport (>= 4.0, < 7) - execjs (2.7.0) + execjs (2.8.1) factory_bot (6.2.0) activesupport (>= 5.0.0) factory_bot_rails (6.2.0) @@ -196,7 +196,7 @@ GEM railties (>= 5.0.0) fast_blank (1.0.0-x86_64-linux-musl) fast_jsonparser (0.5.0-x86_64-linux-musl) - ffi (1.15.0-x86_64-linux-musl) + ffi (1.15.1-x86_64-linux-musl) flamegraph (0.9.5) forwardable-extended (2.6.0) friendly_id (5.4.2) @@ -285,8 +285,6 @@ GEM jekyll-locales (0.1.12) jekyll-lunr (0.2.0) loofah (~> 2.4) - jekyll-node-modules (0.1.0) - jekyll (~> 4) jekyll-order (0.1.4) jekyll-relative-urls (0.0.6) jekyll (~> 4) @@ -328,7 +326,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.9.1) + loofah (2.10.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) @@ -343,7 +341,6 @@ GEM mini_histogram (0.3.1) mini_magick (4.11.0) mini_mime (1.0.3) - mini_portile2 (2.5.1) minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) @@ -356,8 +353,7 @@ GEM net-ssh (6.1.0) netaddr (2.0.4) nio4r (2.5.7-x86_64-linux-musl) - nokogiri (1.11.5-x86_64-linux-musl) - mini_portile2 (~> 2.5.0) + nokogiri (1.11.7-x86_64-linux) racc (~> 1.4) orm_adapter (0.5.0) parallel (1.20.1) @@ -373,7 +369,7 @@ GEM coderay (~> 1.1) method_source (~> 1.0) public_suffix (4.0.6) - puma (5.3.1-x86_64-linux-musl) + puma (5.3.2-x86_64-linux-musl) nio4r (~> 2.0) pundit (2.1.0) activesupport (>= 3.0.0) @@ -383,11 +379,11 @@ GEM rack (>= 2.0.0) rack-mini-profiler (2.3.2) rack (>= 1.2.0) - rack-proxy (0.6.5) + rack-proxy (0.7.0) rack rack-test (1.1.0) rack (>= 1.0, < 3) - radios-comunitarias-jekyll-theme (0.1.4) + radios-comunitarias-jekyll-theme (0.1.5) jekyll (~> 4.0) jekyll-data (~> 1.1) jekyll-feed (~> 0.9) @@ -434,29 +430,30 @@ GEM rb-fsevent (0.11.0) rb-inotify (0.10.1) ffi (~> 1.0) - recursero-jekyll-theme (0.1.3) - jekyll (~> 4.0) + recursero-jekyll-theme (0.2.0) + jekyll (~> 4) + jekyll-commonmark (~> 1.3) jekyll-data (~> 1.1) - jekyll-feed (~> 0.9) + jekyll-dotenv (>= 0.2) + jekyll-feed (~> 0.15) + jekyll-ignore-layouts (~> 0) jekyll-images (~> 0.2) jekyll-include-cache (~> 0) - jekyll-linked-posts (~> 0.2) + jekyll-linked-posts (~> 0) jekyll-locales (~> 0.1) jekyll-lunr (~> 0.1) - jekyll-node-modules (~> 0.1) - jekyll-order (~> 0.1) - jekyll-relative-urls (~> 0.0) - jekyll-seo-tag (~> 2.1) - jekyll-turbolinks (~> 0) + jekyll-order (~> 0) + jekyll-relative-urls (~> 0) + jekyll-seo-tag (~> 2) jekyll-unique-urls (~> 0.1) sutty-archives (~> 2.2) - sutty-liquid (~> 0.1) - redis (4.2.5) + sutty-liquid (~> 0) + redis (4.3.1) redis-actionpack (5.2.0) actionpack (>= 5, < 7) redis-rack (>= 2.1.0, < 3) redis-store (>= 1.1.0, < 2) - redis-activesupport (5.2.0) + redis-activesupport (5.2.1) activesupport (>= 3, < 7) redis-store (>= 1.3, < 2) redis-rack (2.1.3) @@ -476,16 +473,16 @@ GEM railties (>= 5.0) rexml (3.2.5) rouge (3.26.0) - rubocop (1.15.0) + rubocop (1.17.0) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml - rubocop-ast (>= 1.5.0, < 2.0) + rubocop-ast (>= 1.7.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.5.0) + rubocop-ast (1.7.0) parser (>= 3.0.1.1) rubocop-rails (2.10.1) activesupport (>= 4.2.0) @@ -571,7 +568,7 @@ GEM jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) - symbol-fstring (1.0.0-x86_64-linux-musl) + symbol-fstring (1.0.2-x86_64-linux-musl) sysexits (1.2.0) temple (0.8.2) terminal-table (2.0.0) @@ -606,7 +603,7 @@ GEM railties (>= 5.2) semantic_range (>= 2.3.0) webrick (1.7.0) - websocket-driver (0.7.3-x86_64-linux-musl) + websocket-driver (0.7.5-x86_64-linux-musl) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) From 2ceeeff86c23dcdd32d2c05d3164c11c6e3712fe Mon Sep 17 00:00:00 2001 From: f Date: Sat, 10 Jul 2021 20:03:19 -0300 Subject: [PATCH 02/99] Mejorar el entorno de desarrollo fixes #1190 fixes #732 --- .env.example | 2 + Makefile | 180 +++++++++++++++++++++++++-------------------------- README.md | 21 ++++++ 3 files changed, 112 insertions(+), 91 deletions(-) diff --git a/.env.example b/.env.example index a1348593..a62e2b0a 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,5 @@ +DELEGATE=athshe.sutty.nl +HAINISH=../haini.sh/haini.sh DATABASE= RAILS_ENV= IMAP_SERVER= diff --git a/Makefile b/Makefile index c083ddf8..a4480476 100644 --- a/Makefile +++ b/Makefile @@ -1,134 +1,111 @@ -.SHELL := /bin/bash -# Incluir las variables de entorno -mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) -root_dir := $(patsubst %/,%,$(dir $(mkfile_path))) -include $(root_dir)/.env +SHELL := /bin/bash +.DEFAULT_GOAL := help -delegate := athshe +# Copiar el archivo de configuración y avisar cuando hay que +# actualizarlo. +.env: .env.example + @test -f $@ || cp -v $< $@ + @test -f $@ && echo "Revisa $@ para actualizarlo con respecto a $<" + @test -f $@ && diff -auN --color $@ $< -assets := package.json yarn.lock $(shell find app/assets/ app/javascript/ -type f) +include .env -alpine_version := 3.13 -hain ?= ../haini.sh/haini.sh +export -env ?= staging +args ?= ## Argumentos para Hain +commit ?= origin/rails ## Commit desde el que actualizar +env ?= staging ## Entorno del nodo delegado +sutty ?= $(SUTTY) ## Dirección local +delegate ?= $(DELEGATE) ## Cambia el nodo delegado +hain ?= $(HAINISH) ## Ubicación de Hainish +# El nodo delegado tiene dos entornos, production y staging. +# Dependiendo del entorno que elijamos, se van a generar los assets y el +# contenedor y subirse a un servidor u otro. No utilizamos CI/CD (aún). +# +# Production es el entorno de panel.sutty.nl ifeq ($(env),production) container ?= sutty +## TODO: Cambiar a otra cosa branch ?= rails public ?= public endif +# Staging es el entorno de panel.staging.sutty.nl ifeq ($(env),staging) container := staging branch := staging public := staging endif -export +help: always ## Ayuda + @echo -e "Sutty\n" | sed -re "s/^.*/\x1B[38;5;197m&\x1B[0m/" + @echo -e "Servidor: https://panel.$(SUTTY_WITH_PORT)/\n" + @echo -e "Uso: make TAREA args=\"ARGUMENTOS\"\n" + @echo -e "Tareas:\n" + @grep -E "^[a-z\-]+:.*##" Makefile | sed -re "s/(.*):.*##(.*)/\1;\2/" | column -s ";" -t | sed -re "s/^([^ ]+) /\x1B[38;5;197m\1\x1B[0m/" + @echo -e "\nArgumentos:\n" + @grep -E "^[a-z\-]+ \?=.*##" Makefile | sed -re "s/(.*) \?=.*##(.*)/\1;\2/" | column -s ";" -t | sed -re "s/^([^ ]+) /\x1B[38;5;197m\1\x1B[0m/" -public/packs/manifest.json.br: $(assets) - $(hain) 'cd /Sutty/sutty; PANEL_URL=https://panel.sutty.nl RAILS_ENV=production NODE_ENV=production bundle exec rake assets:precompile assets:clean' +assets: node_modules public/packs/manifest.json.br ## Compilar los assets -assets: public/packs/manifest.json.br +test: always ## Ejecutar los tests + $(MAKE) rake args="test RAILS_ENV=test $(args)" -tests := $(shell find test/ -name "*_test.rb") -$(tests): always - $(hain) 'cd /Sutty/sutty; bundle exec rake test TEST="$@" RAILS_ENV=test' - -test: always - $(hain) 'cd /Sutty/sutty; RAILS_ENV=test bundle exec rake test' - -postgresql: /etc/hosts +postgresql: /etc/hosts ## Iniciar la base de datos pgrep postgres >/dev/null || $(hain) postgresql -serve: /etc/hosts postgresql +serve-js: /etc/hosts node_modules ## Iniciar el servidor de desarrollo de Javascript + $(hain) 'bundle exec ./bin/webpack-dev-server' + +serve: /etc/hosts postgresql Gemfile.lock ## Iniciar el servidor de desarrollo de Rails $(MAKE) rails args=server -# make rails args="db:migrate" -rails: +rails: ## Tareas de Rails $(MAKE) bundle args="exec rails $(args)" -rake: +rake: ## Tareas de Rake $(MAKE) bundle args="exec rake $(args)" -bundle: - $(hain) 'cd /Sutty/sutty; bundle $(args)' +bundle: ## Tareas de bundler + $(hain) 'bundle $(args)' -yarn: +rubocop: ## Yutea el código que está por ser commiteado + git status --porcelain \ + | grep -E "^(A|M)" \ + | sed "s/^...//" \ + | grep ".rb$$" \ + | ../haini.sh/haini.sh "xargs -r ./bin/rubocop --auto-correct" + +audit: ## Encuentra dependencias con vulnerabilidades + $(hain) 'gem install bundler-audit' + $(hain) 'bundle audit --update' + +brakeman: ## Busca posibles vulnerabilidades en Sutty + $(MAKE) bundle args='exec brakeman' + +yarn: ## Tareas de yarn $(hain) 'yarn $(args)' -# Servir JS con el dev server. -# Esto acelera la compilación del javascript, tiene que correrse por separado -# de serve. -serve-js: /etc/hosts - $(hain) 'cd /Sutty/sutty; bundle exec ./bin/webpack-dev-server' +clean: ## Limpieza + rm -rf _sites/test-* _deploy/test-* log/*.log tmp/cache tmp/letter_opener tmp/miniprofiler tmp/storage -# Limpiar los archivos de testeo -clean: - rm -rf _sites/test-* _deploy/test-* - -# Generar la imagen Docker -build: assets +build: Gemfile.lock ## Generar la imagen Docker time docker build --build-arg="BRANCH=$(branch)" --build-arg="RAILS_MASTER_KEY=`cat config/master.key`" -t sutty/$(container) . docker tag sutty/$(container):latest sutty:keep + @echo -e "\a" -save: - time docker save sutty/$(container):latest | ssh root@$(delegate).sutty.nl docker load +save: ## Subir la imagen Docker al nodo delegado + time docker save sutty/$(container):latest | ssh root@$(delegate) docker load date +%F | xargs -I {} git tag -f $(container)-{} @echo -e "\a" -# proyectos. -../gems/: - mkdir -p $@ - -# Crear el directorio donde se almacenan las gemas binarias -# TODO: Mover a un proyecto propio, porque lo utilizamos en todos los -gem_dir := $(shell readlink -f ../gems) -gem_cache_dir := $(gem_dir)/cache -gem_binary_dir := $(gem_dir)/$(alpine_version) -ifeq ($(MAKECMDGOALS),build-gems) -gems := $(shell bundle show --paths | xargs -I {} sh -c 'find {}/ext/ -name extconf.rb &>/dev/null && basename {}') -gems := $(patsubst %-x86_64-linux,%,$(gems)) -gems := $(patsubst %,$(gem_cache_dir)/%.gem,$(gems)) -gems_musl := $(patsubst $(gem_cache_dir)/%.gem,$(gem_binary_dir)/%-x86_64-linux-musl.gem,$(gems)) -endif - -$(gem_binary_dir)/%-x86_64-linux-musl.gem: - @docker run \ - -v $(gem_dir):/srv/gems \ - -v `readlink -f ~/.ccache`:/home/builder/.ccache \ - -e HTTP_BASIC_USER=$(HTTP_BASIC_USER) \ - -e HTTP_BASIC_PASSWORD=$(HTTP_BASIC_PASSWORD) \ - -e GEM=`echo $(notdir $*) | sed -re "s/-[^-]+$$//"` \ - -e VERSION=`echo $(notdir $*) | sed -re "s/.*-([^-]+)$$/\1/"` \ - -e JOBS=2 \ - --rm -it \ - sutty/gem-compiler:latest || echo "No se pudo compilar $*" - -# Compilar todas las gemas binarias y subirlas a gems.sutty.nl para que -# al crear el contenedor no tengamos que compilarlas cada vez -build-gems: $(gems_musl) - -cached_gems = $(wildcard $(gem_dir)/cache/*.gem) -rebuild_gems = $(patsubst $(gem_dir)/cache/%.gem,$(gem_dir)/$(alpine_version)/%-x86_64-linux-musl.gem,$(cached_gems)) -rebuild-gems: $(rebuild_gems) - -dirs := $(patsubst %,root/%,data sites deploy public) - -$(dirs): - mkdir -p $@ - -ota: assets +ota-js: assets ## Actualizar Javascript en el nodo delegado sudo chgrp -R 82 public/ - rsync -avi --delete-after public/ $(delegate):/srv/sutty/srv/http/data/_$(public)/ - ssh $(delegate) docker exec $(container) sh -c "cat /srv/http/tmp/puma.pid | xargs -r kill -USR2" + rsync -avi --delete-after public/ root@$(delegate):/srv/sutty/srv/http/data/_$(public)/ + ssh root@$(delegate) docker exec $(container) sh -c "cat /srv/http/tmp/puma.pid | xargs -r kill -USR2" -# Hotfixes -# -# TODO: Reemplazar esto por git pull en el contenedor -commit ?= origin/rails -ota-rb: +ota: ## Actualizar Rails en el nodo delegado umask 022; git format-patch $(commit) scp ./0*.patch $(delegate):/tmp/ ssh $(delegate) mkdir -p /tmp/patches-$(commit)/ @@ -140,6 +117,19 @@ ota-rb: ssh $(delegate) docker exec $(container) ota $(commit) rm ./0*.patch +# Todos los archivos de assets. Si alguno cambia, se van a recompilar +# los assets que luego se suben al nodo delegado. +assets := package.json yarn.lock $(shell find app/assets/ app/javascript/ -type f) +public/packs/manifest.json.br: $(assets) + $(hain) 'PANEL_URL=https://panel.sutty.nl RAILS_ENV=production NODE_ENV=production bundle exec rake assets:precompile assets:clean' + +# Correr un test en particular por ejemplo +# `make test/models/usuarie_test.rb` +tests := $(shell find test/ -name "*_test.rb") +$(tests): always + $(MAKE) test args="TEST=$@" + +# Agrega las direcciones locales al sistema /etc/hosts: always @echo "Chequeando si es necesario agregar el dominio local $(SUTTY)" @grep -q " $(SUTTY)$$" $@ || echo -e "127.0.0.1 $(SUTTY)\n::1 $(SUTTY)" | sudo tee -a $@ @@ -147,4 +137,12 @@ ota-rb: @grep -q " panel.$(SUTTY)$$" $@ || echo -e "127.0.0.1 panel.$(SUTTY)\n::1 panel.$(SUTTY)" | sudo tee -a $@ @grep -q " postgresql.$(SUTTY)$$" $@ || echo -e "127.0.0.1 postgresql.$(SUTTY)\n::1 postgresql.$(SUTTY)" | sudo tee -a $@ +# Instala las dependencias de Javascript +node_modules: package.json + $(MAKE) yarn + +# Instala las dependencias de Rails +Gemfile.lock: Gemfile + $(MAKE) bundle args=install + .PHONY: always diff --git a/README.md b/README.md index ef889f9b..25d0d31c 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,17 @@ Este repositorio es la plataforma _Ruby on Rails_ para alojar el Para más información visita el [sitio de Sutty](https://sutty.nl/). +### Desarrollar + +Todas las tareas se gestionan con `make`, por favor instala GNU Make +antes de comenzar. + +```bash +make help +``` + +[Leer la documentación](https://docs.sutty.nl/) + ## English Sutty is a platform for hosting safer, faster and more resilient @@ -25,3 +36,13 @@ This repository is the Ruby on Rails platform that hosts the self-managed [panel](https://panel.sutty.nl/). For more information, visit [Sutty's website](https://sutty.nl/en/). + +### Development + +Every task is run via `make`, please install GNU Make before developing. + +```bash +make help +``` + +[Read the documentation](https://docs.sutty.nl/en/) From 68bd68a2ee2cac6e990f49f1266b612e771fd4d3 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 13 Jul 2021 17:22:05 -0300 Subject: [PATCH 03/99] =?UTF-8?q?actualizaci=C3=B3n=20de=20cuidados,=20res?= =?UTF-8?q?uelve=20un=20cve=20en=20addressable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile.lock | 162 +++++++++++++++++++++++++-------------------------- 1 file changed, 81 insertions(+), 81 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index aed60b18..33fba3a0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,66 +18,66 @@ GIT GEM remote: https://gems.sutty.nl/ specs: - actioncable (6.1.3.2) - actionpack (= 6.1.3.2) - activesupport (= 6.1.3.2) + actioncable (6.1.4) + actionpack (= 6.1.4) + activesupport (= 6.1.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.3.2) - actionpack (= 6.1.3.2) - activejob (= 6.1.3.2) - activerecord (= 6.1.3.2) - activestorage (= 6.1.3.2) - activesupport (= 6.1.3.2) + actionmailbox (6.1.4) + actionpack (= 6.1.4) + activejob (= 6.1.4) + activerecord (= 6.1.4) + activestorage (= 6.1.4) + activesupport (= 6.1.4) mail (>= 2.7.1) - actionmailer (6.1.3.2) - actionpack (= 6.1.3.2) - actionview (= 6.1.3.2) - activejob (= 6.1.3.2) - activesupport (= 6.1.3.2) + actionmailer (6.1.4) + actionpack (= 6.1.4) + actionview (= 6.1.4) + activejob (= 6.1.4) + activesupport (= 6.1.4) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.3.2) - actionview (= 6.1.3.2) - activesupport (= 6.1.3.2) + actionpack (6.1.4) + actionview (= 6.1.4) + activesupport (= 6.1.4) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.3.2) - actionpack (= 6.1.3.2) - activerecord (= 6.1.3.2) - activestorage (= 6.1.3.2) - activesupport (= 6.1.3.2) + actiontext (6.1.4) + actionpack (= 6.1.4) + activerecord (= 6.1.4) + activestorage (= 6.1.4) + activesupport (= 6.1.4) nokogiri (>= 1.8.5) - actionview (6.1.3.2) - activesupport (= 6.1.3.2) + actionview (6.1.4) + activesupport (= 6.1.4) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.3.2) - activesupport (= 6.1.3.2) + activejob (6.1.4) + activesupport (= 6.1.4) globalid (>= 0.3.6) - activemodel (6.1.3.2) - activesupport (= 6.1.3.2) - activerecord (6.1.3.2) - activemodel (= 6.1.3.2) - activesupport (= 6.1.3.2) - activestorage (6.1.3.2) - actionpack (= 6.1.3.2) - activejob (= 6.1.3.2) - activerecord (= 6.1.3.2) - activesupport (= 6.1.3.2) + activemodel (6.1.4) + activesupport (= 6.1.4) + activerecord (6.1.4) + activemodel (= 6.1.4) + activesupport (= 6.1.4) + activestorage (6.1.4) + actionpack (= 6.1.4) + activejob (= 6.1.4) + activerecord (= 6.1.4) + activesupport (= 6.1.4) marcel (~> 1.0.0) - mini_mime (~> 1.0.2) - activesupport (6.1.3.2) + mini_mime (>= 1.1.0) + activesupport (6.1.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) zeitwerk (~> 2.3) - addressable (2.7.0) + addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) adhesiones-jekyll-theme (0.2.1) jekyll (~> 4.0) @@ -113,7 +113,7 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (>= 2.0, < 4.0) - chartkick (4.0.4) + chartkick (4.0.5) childprocess (3.0.0) coderay (1.1.3) colorator (1.1.0) @@ -130,7 +130,7 @@ GEM database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) dead_end (1.1.7) - derailed_benchmarks (2.1.0) + derailed_benchmarks (2.1.1) benchmark-ips (~> 2) dead_end get_process_mem (~> 0) @@ -148,8 +148,8 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-i18n (1.9.4) - devise (>= 4.7.1) + devise-i18n (1.10.0) + devise (>= 4.8.0) devise_invitable (2.0.5) actionmailer (>= 5.0) devise (>= 4.6) @@ -196,7 +196,7 @@ GEM railties (>= 5.0.0) fast_blank (1.0.0-x86_64-linux-musl) fast_jsonparser (0.5.0-x86_64-linux-musl) - ffi (1.15.1-x86_64-linux-musl) + ffi (1.15.3-x86_64-linux-musl) flamegraph (0.9.5) forwardable-extended (2.6.0) friendly_id (5.4.2) @@ -214,7 +214,7 @@ GEM tilt haml-lint (0.999.999) haml_lint - haml_lint (0.37.0) + haml_lint (0.37.1) haml (>= 4.0, < 5.3) parallel (~> 1.10) rainbow @@ -264,8 +264,8 @@ GEM rouge (~> 3.0) safe_yaml (~> 1.0) terminal-table (~> 2.0) - jekyll-commonmark (1.3.1) - commonmarker (~> 0.14) + jekyll-commonmark (1.3.2) + commonmarker (~> 0.14, < 0.22) jekyll (>= 3.7, < 5.0) jekyll-data (1.1.2) jekyll (>= 3.3, < 5.0.0) @@ -284,10 +284,10 @@ GEM ruby-vips (~> 2) jekyll-include-cache (0.2.1) jekyll (>= 3.7, < 5.0) - jekyll-linked-posts (0.2.0) + jekyll-linked-posts (0.4.0) jekyll (~> 4) jekyll-locales (0.1.12) - jekyll-lunr (0.2.0) + jekyll-lunr (0.3.0) loofah (~> 2.4) jekyll-order (0.1.4) jekyll-relative-urls (0.0.6) @@ -296,7 +296,7 @@ GEM sassc (> 2.0.1, < 3.0) jekyll-seo-tag (2.7.1) jekyll (>= 3.8, < 5.0) - jekyll-spree-client (0.1.14) + jekyll-spree-client (0.1.15) fast_blank (~> 1) spree-api-client (~> 0.2) jekyll-turbolinks (0.0.5) @@ -324,7 +324,7 @@ GEM ruby_dep (~> 1.2) loaf (0.10.0) railties (>= 3.2) - lockbox (0.6.4) + lockbox (0.6.5) lograge (0.11.2) actionpack (>= 4) activesupport (>= 4) @@ -341,10 +341,10 @@ GEM method_source (1.0.0) mime-types (3.3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2021.0225) + mime-types-data (3.2021.0704) mini_histogram (0.3.1) mini_magick (4.11.0) - mini_mime (1.0.3) + mini_mime (1.1.0) minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) @@ -361,7 +361,7 @@ GEM racc (~> 1.4) orm_adapter (0.5.0) parallel (1.20.1) - parser (3.0.1.1) + parser (3.0.2.0) ast (~> 2.4.1) pathutil (0.16.2) forwardable-extended (~> 2.6) @@ -370,7 +370,7 @@ GEM activerecord (>= 5.2) activesupport (>= 5.2) popper_js (1.16.0) - prometheus_exporter (0.7.0) + prometheus_exporter (0.8.0) webrick pry (0.14.1) coderay (~> 1.1) @@ -401,20 +401,20 @@ GEM jekyll-relative-urls (~> 0.0) jekyll-seo-tag (~> 2.1) jekyll-turbolinks (~> 0) - rails (6.1.3.2) - actioncable (= 6.1.3.2) - actionmailbox (= 6.1.3.2) - actionmailer (= 6.1.3.2) - actionpack (= 6.1.3.2) - actiontext (= 6.1.3.2) - actionview (= 6.1.3.2) - activejob (= 6.1.3.2) - activemodel (= 6.1.3.2) - activerecord (= 6.1.3.2) - activestorage (= 6.1.3.2) - activesupport (= 6.1.3.2) + rails (6.1.4) + actioncable (= 6.1.4) + actionmailbox (= 6.1.4) + actionmailer (= 6.1.4) + actionpack (= 6.1.4) + actiontext (= 6.1.4) + actionview (= 6.1.4) + activejob (= 6.1.4) + activemodel (= 6.1.4) + activerecord (= 6.1.4) + activestorage (= 6.1.4) + activesupport (= 6.1.4) bundler (>= 1.15.0) - railties (= 6.1.3.2) + railties (= 6.1.4) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) @@ -426,14 +426,14 @@ GEM railties (>= 6.0.0, < 7) rails_warden (0.6.0) warden (>= 1.2.0) - railties (6.1.3.2) - actionpack (= 6.1.3.2) - activesupport (= 6.1.3.2) + railties (6.1.4) + actionpack (= 6.1.4) + activesupport (= 6.1.4) method_source - rake (>= 0.8.7) + rake (>= 0.13) thor (~> 1.0) rainbow (3.0.0) - rake (13.0.3) + rake (13.0.6) rb-fsevent (0.11.0) rb-inotify (0.10.1) ffi (~> 1.0) @@ -480,7 +480,7 @@ GEM railties (>= 5.0) rexml (3.2.5) rouge (3.26.0) - rubocop (1.17.0) + rubocop (1.18.3) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) @@ -491,7 +491,7 @@ GEM unicode-display_width (>= 1.4.0, < 3.0) rubocop-ast (1.7.0) parser (>= 3.0.1.1) - rubocop-rails (2.10.1) + rubocop-rails (2.11.3) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.7.0, < 2.0) @@ -506,10 +506,10 @@ GEM ruby_parser (~> 3.1) sexp_processor (~> 4.6) ruby_dep (1.5.0) - ruby_parser (3.15.1) - sexp_processor (~> 4.9) - rubyzip (2.3.0) - rugged (1.1.0-x86_64-linux-musl) + ruby_parser (3.16.0) + sexp_processor (~> 4.15, >= 4.15.1) + rubyzip (2.3.2) + rugged (1.1.1-x86_64-linux-musl) safe_yaml (1.0.6) safely_block (0.3.0) errbase (>= 0.1.1) @@ -525,7 +525,7 @@ GEM childprocess (>= 0.5, < 4.0) rubyzip (>= 1.2.2) semantic_range (3.0.0) - sexp_processor (4.15.2) + sexp_processor (4.15.3) share-to-fediverse-jekyll-theme (0.1.4) jekyll (~> 4.0) jekyll-data (~> 1.1) @@ -537,7 +537,7 @@ GEM simpleidn (0.2.1) unf (~> 0.1.4) sourcemap (0.1.1) - spree-api-client (0.2.1) + spree-api-client (0.2.2) fast_blank (~> 1) httparty (~> 0.18.0) spring (2.1.1) From 8f88023d52257fba2152dfcd8bc4bc62ea57214f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Jul 2021 16:16:10 -0300 Subject: [PATCH 04/99] El espacio es importante --- Makefile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index a4480476..0bb5f582 100644 --- a/Makefile +++ b/Makefile @@ -12,12 +12,13 @@ include .env export -args ?= ## Argumentos para Hain -commit ?= origin/rails ## Commit desde el que actualizar -env ?= staging ## Entorno del nodo delegado -sutty ?= $(SUTTY) ## Dirección local -delegate ?= $(DELEGATE) ## Cambia el nodo delegado -hain ?= $(HAINISH) ## Ubicación de Hainish +# XXX: El espacio antes del comentario cuenta como espacio +args ?=## Argumentos para Hain +commit ?= origin/rails## Commit desde el que actualizar +env ?= staging## Entorno del nodo delegado +sutty ?= $(SUTTY)## Dirección local +delegate ?= $(DELEGATE)## Cambia el nodo delegado +hain ?= $(HAINISH)## Ubicación de Hainish # El nodo delegado tiene dos entornos, production y staging. # Dependiendo del entorno que elijamos, se van a generar los assets y el From d474b819ad60ebe24e3f3ba63616bfe2300c6d5c Mon Sep 17 00:00:00 2001 From: f Date: Thu, 22 Jul 2021 16:19:25 -0300 Subject: [PATCH 05/99] agregar request_uri a los logs sutty/containers/nginx!1 --- .../20210722191718_add_request_uri_to_access_logs.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 db/migrate/20210722191718_add_request_uri_to_access_logs.rb diff --git a/db/migrate/20210722191718_add_request_uri_to_access_logs.rb b/db/migrate/20210722191718_add_request_uri_to_access_logs.rb new file mode 100644 index 00000000..3d225aed --- /dev/null +++ b/db/migrate/20210722191718_add_request_uri_to_access_logs.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# Agrega la columna de request_uri a la tabla de logs +class AddRequestUriToAccessLogs < ActiveRecord::Migration[6.1] + def change + return unless Rails.env.production? + + add_column :access_logs, :request_uri, :string, default: '' + end +end From d456feac8e70418f52c962e82a40b58559858a4e Mon Sep 17 00:00:00 2001 From: f Date: Thu, 29 Jul 2021 14:46:29 -0300 Subject: [PATCH 06/99] =?UTF-8?q?Cancelar=20la=20tarea=20pendiente=20si=20?= =?UTF-8?q?tom=C3=B3=20mas=20de=2010=20minutos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Si la tarea se reintentó durante 10 minutos, lo más probable es que haya quedado trabada en algún lado. Este cambio permite volver a compilar sitios al cambiar el estado a espera y cancelarse a sí misma. --- app/jobs/deploy_job.rb | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/app/jobs/deploy_job.rb b/app/jobs/deploy_job.rb index f1ceca9e..70997ce1 100644 --- a/app/jobs/deploy_job.rb +++ b/app/jobs/deploy_job.rb @@ -5,13 +5,23 @@ class DeployJob < ApplicationJob class DeployException < StandardError; end # rubocop:disable Metrics/MethodLength - def perform(site, notify = true) + def perform(site, notify = true, time = Time.now) ActiveRecord::Base.connection_pool.with_connection do @site = Site.find(site) - # Si ya hay una tarea corriendo, aplazar esta + # Si ya hay una tarea corriendo, aplazar esta. Si estuvo + # esperando más de 10 minutos, recuperar el estado anterior. + # + # Como el trabajo actual se aplaza al siguiente, arrastrar la + # hora original para poder ir haciendo timeouts. if @site.building? - DeployJob.perform_in(60, site, notify) + if 10.minutes.ago >= time + @site.update status: 'waiting' + raise DeployException, + "#{@site.name} la tarea estuvo más de 10 minutos esperando, volviendo al estado original" + end + + DeployJob.perform_in(60, site, notify, time) return end @@ -29,8 +39,11 @@ class DeployJob < ApplicationJob end deploy_others - notify_usuaries if notify + + # Volver a la espera @site.update status: 'waiting' + + notify_usuaries if notify end end # rubocop:enable Metrics/MethodLength From 4c84389b3561f8b34831736f196a9729f96f9bbb Mon Sep 17 00:00:00 2001 From: Nulo <5151-Nulo@users.noreply.0xacab.org> Date: Mon, 2 Aug 2021 16:17:30 +0000 Subject: [PATCH 07/99] Apply 3 suggestion(s) to 1 file(s) --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 0bb5f582..03fd395d 100644 --- a/Makefile +++ b/Makefile @@ -62,13 +62,13 @@ serve-js: /etc/hosts node_modules ## Iniciar el servidor de desarrollo de Javasc serve: /etc/hosts postgresql Gemfile.lock ## Iniciar el servidor de desarrollo de Rails $(MAKE) rails args=server -rails: ## Tareas de Rails +rails: ## Corre rails dentro del entorno de desarrollo (pasar argumentos con args=). $(MAKE) bundle args="exec rails $(args)" -rake: ## Tareas de Rake +rake: ## Corre rake dentro del entorno de desarrollo (pasar argumentos con args=). $(MAKE) bundle args="exec rake $(args)" -bundle: ## Tareas de bundler +bundle: ## Corre bundle dentro del entorno de desarrollo (pasar argumentos con args=). $(hain) 'bundle $(args)' rubocop: ## Yutea el código que está por ser commiteado From 9f84c14a69e3102d96087f589d1fa1bc18b6a877 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 7 Aug 2021 15:55:00 -0300 Subject: [PATCH 08/99] Soportar sitios sin yarn.lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Como el chequeo devuelve nil, un sitio sin yarn.lock nunca se compilaría. --- 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 02b837f0..c063b7bc 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -80,7 +80,7 @@ class DeployLocal < Deploy # Corre yarn dentro del repositorio def yarn - return unless yarn_lock? + return true unless yarn_lock? run 'yarn' end From 0bd8a2243e88db85da363ad2101056c9361aeec2 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 11 Aug 2021 10:25:05 -0300 Subject: [PATCH 09/99] Solo permitir URLs web al sanitizar fixes #2382 --- app/models/metadata_content.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_content.rb b/app/models/metadata_content.rb index 437a0dd9..9d3a1040 100644 --- a/app/models/metadata_content.rb +++ b/app/models/metadata_content.rb @@ -56,7 +56,7 @@ class MetadataContent < MetadataTemplate uri = URI element['src'] # No permitimos recursos externos - element.remove unless uri.hostname.end_with? Site.domain + element.remove unless uri.scheme == 'https' && uri.hostname.end_with?(Site.domain) rescue URI::Error element.remove end From 9ccc1be89834df97127370bb6f3552a3ef1003d8 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 28 Aug 2021 12:56:04 -0300 Subject: [PATCH 10/99] =?UTF-8?q?actualizaci=C3=B3n=20de=20cuidados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 2 + Gemfile.lock | 175 ++++++++++++++++++++++++++------------------------- 2 files changed, 91 insertions(+), 86 deletions(-) diff --git a/Gemfile b/Gemfile index 4256e307..cb78d4c3 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,8 @@ gem 'sassc-rails' gem 'uglifier', '>= 1.3.0' gem 'bootstrap', '~> 4' +gem 'nokogiri', '~>1.11.0' + # Turbolinks makes navigating your web application faster. Read more: # https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' diff --git a/Gemfile.lock b/Gemfile.lock index 33fba3a0..8ce97f31 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,60 +18,60 @@ GIT GEM remote: https://gems.sutty.nl/ specs: - actioncable (6.1.4) - actionpack (= 6.1.4) - activesupport (= 6.1.4) + actioncable (6.1.4.1) + actionpack (= 6.1.4.1) + activesupport (= 6.1.4.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.4) - actionpack (= 6.1.4) - activejob (= 6.1.4) - activerecord (= 6.1.4) - activestorage (= 6.1.4) - activesupport (= 6.1.4) + actionmailbox (6.1.4.1) + actionpack (= 6.1.4.1) + activejob (= 6.1.4.1) + activerecord (= 6.1.4.1) + activestorage (= 6.1.4.1) + activesupport (= 6.1.4.1) mail (>= 2.7.1) - actionmailer (6.1.4) - actionpack (= 6.1.4) - actionview (= 6.1.4) - activejob (= 6.1.4) - activesupport (= 6.1.4) + actionmailer (6.1.4.1) + actionpack (= 6.1.4.1) + actionview (= 6.1.4.1) + activejob (= 6.1.4.1) + activesupport (= 6.1.4.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.4) - actionview (= 6.1.4) - activesupport (= 6.1.4) + actionpack (6.1.4.1) + actionview (= 6.1.4.1) + activesupport (= 6.1.4.1) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.4) - actionpack (= 6.1.4) - activerecord (= 6.1.4) - activestorage (= 6.1.4) - activesupport (= 6.1.4) + actiontext (6.1.4.1) + actionpack (= 6.1.4.1) + activerecord (= 6.1.4.1) + activestorage (= 6.1.4.1) + activesupport (= 6.1.4.1) nokogiri (>= 1.8.5) - actionview (6.1.4) - activesupport (= 6.1.4) + actionview (6.1.4.1) + activesupport (= 6.1.4.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (6.1.4) - activesupport (= 6.1.4) + activejob (6.1.4.1) + activesupport (= 6.1.4.1) globalid (>= 0.3.6) - activemodel (6.1.4) - activesupport (= 6.1.4) - activerecord (6.1.4) - activemodel (= 6.1.4) - activesupport (= 6.1.4) - activestorage (6.1.4) - actionpack (= 6.1.4) - activejob (= 6.1.4) - activerecord (= 6.1.4) - activesupport (= 6.1.4) + activemodel (6.1.4.1) + activesupport (= 6.1.4.1) + activerecord (6.1.4.1) + activemodel (= 6.1.4.1) + activesupport (= 6.1.4.1) + activestorage (6.1.4.1) + actionpack (= 6.1.4.1) + activejob (= 6.1.4.1) + activerecord (= 6.1.4.1) + activesupport (= 6.1.4.1) marcel (~> 1.0.0) mini_mime (>= 1.1.0) - activesupport (6.1.4) + activesupport (6.1.4.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -89,13 +89,13 @@ GEM jekyll-relative-urls (~> 0.0) jekyll-seo-tag (~> 2.1) ast (2.4.2) - autoprefixer-rails (10.2.5.1) - execjs (> 0) + autoprefixer-rails (10.3.1.0) + execjs (~> 2) bcrypt (3.1.16-x86_64-linux-musl) bcrypt_pbkdf (1.1.0-x86_64-linux-musl) benchmark-ips (2.9.1) bindex (0.8.1-x86_64-linux-musl) - blazer (2.4.2) + blazer (2.4.3) activerecord (>= 5) chartkick (>= 3.2) railties (>= 5) @@ -104,7 +104,7 @@ GEM autoprefixer-rails (>= 9.1.0) popper_js (>= 1.14.3, < 2) sassc-rails (>= 2.0.0) - brakeman (5.0.4) + brakeman (5.1.1) builder (3.2.4) capybara (2.18.0) addressable @@ -157,8 +157,8 @@ GEM dotenv-rails (2.7.6) dotenv (= 2.7.6) railties (>= 3.2) - down (5.2.2) - addressable (~> 2.5) + down (5.2.3) + addressable (~> 2.8) ed25519 (1.2.4-x86_64-linux-musl) editorial-autogestiva-jekyll-theme (0.3.4) jekyll (~> 4) @@ -194,7 +194,7 @@ GEM factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) railties (>= 5.0.0) - fast_blank (1.0.0-x86_64-linux-musl) + fast_blank (1.0.1-x86_64-linux-musl) fast_jsonparser (0.5.0-x86_64-linux-musl) ffi (1.15.3-x86_64-linux-musl) flamegraph (0.9.5) @@ -203,13 +203,13 @@ GEM activerecord (>= 4.0.0) get_process_mem (0.2.7) ffi (~> 1.0) - globalid (0.4.2) - activesupport (>= 4.2.0) + globalid (0.5.2) + activesupport (>= 5.0) hairtrigger (0.2.24) activerecord (>= 5.0, < 7) ruby2ruby (~> 2.4) ruby_parser (~> 3.10) - haml (5.2.1) + haml (5.2.2) temple (>= 0.8.0) tilt haml-lint (0.999.999) @@ -220,7 +220,7 @@ GEM rainbow rubocop (>= 0.50.0) sysexits (~> 1.1) - hamlit (2.15.0-x86_64-linux-musl) + hamlit (2.15.1-x86_64-linux-musl) temple (>= 0.8.2) thor tilt @@ -276,7 +276,7 @@ GEM jekyll (>= 3.7, < 5.0) jekyll-hardlinks (0.1.2) jekyll (~> 4) - jekyll-ignore-layouts (0.1.0) + jekyll-ignore-layouts (0.1.2) jekyll (~> 4) jekyll-images (0.2.7) jekyll (~> 4) @@ -284,7 +284,7 @@ GEM ruby-vips (~> 2) jekyll-include-cache (0.2.1) jekyll (>= 3.7, < 5.0) - jekyll-linked-posts (0.4.0) + jekyll-linked-posts (0.4.2) jekyll (~> 4) jekyll-locales (0.1.12) jekyll-lunr (0.3.0) @@ -296,9 +296,9 @@ GEM sassc (> 2.0.1, < 3.0) jekyll-seo-tag (2.7.1) jekyll (>= 3.8, < 5.0) - jekyll-spree-client (0.1.15) + jekyll-spree-client (0.1.17) fast_blank (~> 1) - spree-api-client (~> 0.2) + spree-api-client (>= 0.2.3) jekyll-turbolinks (0.0.5) jekyll (~> 4) turbolinks-source (~> 5) @@ -306,7 +306,7 @@ GEM jekyll (~> 4) jekyll-watch (2.2.1) listen (~> 3.0) - jekyll-write-and-commit-changes (0.1.2) + jekyll-write-and-commit-changes (0.2.0) jekyll (~> 4) rugged (~> 1) kramdown (2.3.1) @@ -330,7 +330,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.10.0) + loofah (2.12.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) @@ -344,20 +344,22 @@ GEM mime-types-data (3.2021.0704) mini_histogram (0.3.1) mini_magick (4.11.0) - mini_mime (1.1.0) + mini_mime (1.1.1) + mini_portile2 (2.5.3) minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) minitest (5.14.4) - mobility (1.1.2) + mobility (1.1.3) i18n (>= 0.6.10, < 2) request_store (~> 1.0) multi_xml (0.6.0) net-ssh (6.1.0) netaddr (2.0.4) - nio4r (2.5.7-x86_64-linux-musl) - nokogiri (1.11.7-x86_64-linux) + nio4r (2.5.8-x86_64-linux-musl) + nokogiri (1.11.7-x86_64-linux-musl) + mini_portile2 (~> 2.5.0) racc (~> 1.4) orm_adapter (0.5.0) parallel (1.20.1) @@ -370,15 +372,15 @@ GEM activerecord (>= 5.2) activesupport (>= 5.2) popper_js (1.16.0) - prometheus_exporter (0.8.0) + prometheus_exporter (0.8.1) webrick pry (0.14.1) coderay (~> 1.1) method_source (~> 1.0) public_suffix (4.0.6) - puma (5.3.2-x86_64-linux-musl) + puma (5.4.0-x86_64-linux-musl) nio4r (~> 2.0) - pundit (2.1.0) + pundit (2.1.1) activesupport (>= 3.0.0) racc (1.5.2-x86_64-linux-musl) rack (2.2.3) @@ -401,34 +403,34 @@ GEM jekyll-relative-urls (~> 0.0) jekyll-seo-tag (~> 2.1) jekyll-turbolinks (~> 0) - rails (6.1.4) - actioncable (= 6.1.4) - actionmailbox (= 6.1.4) - actionmailer (= 6.1.4) - actionpack (= 6.1.4) - actiontext (= 6.1.4) - actionview (= 6.1.4) - activejob (= 6.1.4) - activemodel (= 6.1.4) - activerecord (= 6.1.4) - activestorage (= 6.1.4) - activesupport (= 6.1.4) + rails (6.1.4.1) + actioncable (= 6.1.4.1) + actionmailbox (= 6.1.4.1) + actionmailer (= 6.1.4.1) + actionpack (= 6.1.4.1) + actiontext (= 6.1.4.1) + actionview (= 6.1.4.1) + activejob (= 6.1.4.1) + activemodel (= 6.1.4.1) + activerecord (= 6.1.4.1) + activestorage (= 6.1.4.1) + activesupport (= 6.1.4.1) bundler (>= 1.15.0) - railties (= 6.1.4) + railties (= 6.1.4.1) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.3.0) + rails-html-sanitizer (1.4.2) loofah (~> 2.3) rails-i18n (6.0.0) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 7) rails_warden (0.6.0) warden (>= 1.2.0) - railties (6.1.4) - actionpack (= 6.1.4) - activesupport (= 6.1.4) + railties (6.1.4.1) + actionpack (= 6.1.4.1) + activesupport (= 6.1.4.1) method_source rake (>= 0.13) thor (~> 1.0) @@ -455,7 +457,7 @@ GEM jekyll-unique-urls (~> 0.1) sutty-archives (~> 2.2) sutty-liquid (~> 0) - redis (4.3.1) + redis (4.4.0) redis-actionpack (5.2.0) actionpack (>= 5, < 7) redis-rack (>= 2.1.0, < 3) @@ -480,16 +482,16 @@ GEM railties (>= 5.0) rexml (3.2.5) rouge (3.26.0) - rubocop (1.18.3) + rubocop (1.20.0) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml - rubocop-ast (>= 1.7.0, < 2.0) + rubocop-ast (>= 1.9.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.7.0) + rubocop-ast (1.11.0) parser (>= 3.0.1.1) rubocop-rails (2.11.3) activesupport (>= 4.2.0) @@ -500,13 +502,13 @@ GEM ruby-filemagic (0.7.2-x86_64-linux-musl) ruby-progressbar (1.11.0) ruby-statistics (2.1.3) - ruby-vips (2.1.2) + ruby-vips (2.1.3) ffi (~> 1.12) ruby2ruby (2.4.4) ruby_parser (~> 3.1) sexp_processor (~> 4.6) ruby_dep (1.5.0) - ruby_parser (3.16.0) + ruby_parser (3.17.0) sexp_processor (~> 4.15, >= 4.15.1) rubyzip (2.3.2) rugged (1.1.1-x86_64-linux-musl) @@ -537,7 +539,7 @@ GEM simpleidn (0.2.1) unf (~> 0.1.4) sourcemap (0.1.1) - spree-api-client (0.2.2) + spree-api-client (0.2.3) fast_blank (~> 1) httparty (~> 0.18.0) spring (2.1.1) @@ -610,7 +612,7 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webpacker (5.4.0) + webpacker (5.4.2) activesupport (>= 5.2) rack-proxy (>= 0.6.1) railties (>= 5.2) @@ -677,6 +679,7 @@ DEPENDENCIES minima mobility net-ssh + nokogiri (~> 1.11.0) pg pg_search prometheus_exporter From be549c5cd518b942ff65abf31ffe8969ddfb6f1f Mon Sep 17 00:00:00 2001 From: f Date: Sat, 28 Aug 2021 13:02:12 -0300 Subject: [PATCH 11/99] ruby 2.7.4 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b3253b4..59352b61 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ ENV RAILS_MASTER_KEY=$RAILS_MASTER_KEY RUN apk add --no-cache libxslt libxml2 tzdata ruby ruby-bundler ruby-json ruby-bigdecimal ruby-rake RUN apk add --no-cache postgresql-libs git yarn brotli libssh2 python3 -RUN test "2.7.3" = `ruby -e 'puts RUBY_VERSION'` +RUN test "2.7.4" = `ruby -e 'puts RUBY_VERSION'` # https://github.com/rubygems/rubygems/issues/2918 # https://gitlab.alpinelinux.org/alpine/aports/issues/10808 @@ -85,7 +85,7 @@ RUN apk add --no-cache ffmpeg imagemagick pandoc tectonic oxipng jemalloc RUN apk add --no-cache git-lfs openssh-client patch # Chequear que la versión de ruby sea la correcta -RUN test "2.7.3" = `ruby -e 'puts RUBY_VERSION'` +RUN test "2.7.4" = `ruby -e 'puts RUBY_VERSION'` # https://github.com/rubygems/rubygems/issues/2918 # https://gitlab.alpinelinux.org/alpine/aports/issues/10808 From 094a8092de7721edab16cfb052db058dbe3464cd Mon Sep 17 00:00:00 2001 From: f Date: Fri, 3 Sep 2021 15:23:11 -0300 Subject: [PATCH 12/99] Agregar rollups --- Gemfile | 1 + Gemfile.lock | 10 +++++++++- db/migrate/20210807003928_create_rollups.rb | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20210807003928_create_rollups.rb diff --git a/Gemfile b/Gemfile index 4256e307..2f5446a0 100644 --- a/Gemfile +++ b/Gemfile @@ -58,6 +58,7 @@ gem 'rails-i18n' gem 'rails_warden' gem 'redis', require: %w[redis redis/connection/hiredis] gem 'redis-rails' +gem 'rollups' gem 'rubyzip' gem 'rugged' gem 'concurrent-ruby-ext' diff --git a/Gemfile.lock b/Gemfile.lock index 33fba3a0..6c873d9b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -205,6 +205,8 @@ GEM ffi (~> 1.0) globalid (0.4.2) activesupport (>= 4.2.0) + groupdate (5.2.2) + activesupport (>= 5) hairtrigger (0.2.24) activerecord (>= 5.0, < 7) ruby2ruby (~> 2.4) @@ -345,6 +347,7 @@ GEM mini_histogram (0.3.1) mini_magick (4.11.0) mini_mime (1.1.0) + mini_portile2 (2.5.3) minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) @@ -357,7 +360,8 @@ GEM net-ssh (6.1.0) netaddr (2.0.4) nio4r (2.5.7-x86_64-linux-musl) - nokogiri (1.11.7-x86_64-linux) + nokogiri (1.11.7-x86_64-linux-musl) + mini_portile2 (~> 2.5.0) racc (~> 1.4) orm_adapter (0.5.0) parallel (1.20.1) @@ -479,6 +483,9 @@ GEM actionpack (>= 5.0) railties (>= 5.0) rexml (3.2.5) + rollups (0.1.2) + activesupport (>= 5.1) + groupdate (>= 5.2) rouge (3.26.0) rubocop (1.18.3) parallel (~> 1.10) @@ -692,6 +699,7 @@ DEPENDENCIES recursero-jekyll-theme redis redis-rails + rollups rubocop-rails rubyzip rugged diff --git a/db/migrate/20210807003928_create_rollups.rb b/db/migrate/20210807003928_create_rollups.rb new file mode 100644 index 00000000..932513a4 --- /dev/null +++ b/db/migrate/20210807003928_create_rollups.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +# Crear la tabla de Rollups +class CreateRollups < ActiveRecord::Migration[6.1] + def change + create_table :rollups do |t| + t.string :name, null: false + t.string :interval, null: false + t.datetime :time, null: false + t.jsonb :dimensions, null: false, default: {} + t.float :value + end + add_index :rollups, %i[name interval time dimensions], unique: true + end +end From 604c16bfb8947b42634bc3f2f8c30f168fecee13 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 3 Sep 2021 15:28:45 -0300 Subject: [PATCH 13/99] Agregar created_at a access_logs para poder agrupar por fecha --- ...10807004941_add_create_at_to_access_logs.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 db/migrate/20210807004941_add_create_at_to_access_logs.rb diff --git a/db/migrate/20210807004941_add_create_at_to_access_logs.rb b/db/migrate/20210807004941_add_create_at_to_access_logs.rb new file mode 100644 index 00000000..0e106061 --- /dev/null +++ b/db/migrate/20210807004941_add_create_at_to_access_logs.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Cambia los msec a datetime para poder agregar por tiempos +class AddCreateAtToAccessLogs < ActiveRecord::Migration[6.1] + def up + add_column :access_logs, :created_at, :datetime, precision: 6 + + create_trigger(compatibility: 1).on(:access_logs).before(:insert) do + 'new.created_at := to_timestamp(new.msec)' + end + + ActiveRecord::Base.connection.execute('update access_logs set created_at = to_timestamp(msec);') + end + + def down + remove_column :access_logs, :created_at + end +end From 016da2852926436142e89fcdf1f80c840496a084 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 3 Sep 2021 15:53:45 -0300 Subject: [PATCH 14/99] Inflexiones para Rollup --- config/initializers/inflections.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 35b309ea..0e18b987 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -11,6 +11,8 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.singular 'licencias', 'licencia' inflect.plural 'rol', 'roles' inflect.singular 'roles', 'rol' + inflect.plural 'rollup', 'rollups' + inflect.singular 'rollups', 'rollup' end ActiveSupport::Inflector.inflections(:es) do |inflect| @@ -24,4 +26,6 @@ ActiveSupport::Inflector.inflections(:es) do |inflect| inflect.singular 'roles', 'rol' inflect.plural 'licencia', 'licencias' inflect.singular 'licencias', 'licencia' + inflect.plural 'rollup', 'rollups' + inflect.singular 'rollups', 'rollup' end From 4e4b5888a35e403133c8d9a0934a09cd6520f9ae Mon Sep 17 00:00:00 2001 From: f Date: Fri, 3 Sep 2021 15:55:30 -0300 Subject: [PATCH 15/99] Peticiones completas --- app/models/access_log.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/models/access_log.rb b/app/models/access_log.rb index 85cd4c36..0dceb7d7 100644 --- a/app/models/access_log.rb +++ b/app/models/access_log.rb @@ -1,4 +1,9 @@ # frozen_string_literal: true class AccessLog < ApplicationRecord + # Las peticiones completas son las que terminaron bien y se + # respondieron con 200 OK o 304 Not Modified + # + # @see {https://en.wikipedia.org/wiki/List_of_HTTP_status_codes} + scope :completed_requests, -> { where(request_method: 'GET', request_completion: 'OK', status: [200, 304]) } end From 1623ab73dea22fbc63abf759245627926b2a5b63 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 11 Sep 2021 17:00:28 -0300 Subject: [PATCH 16/99] Soportar un campo con una lista de valores predefinidos y elegir uno --- app/models/metadata_predefined_value.rb | 24 +++++++++++++++++++ .../posts/attribute_ro/_predefined_value.haml | 3 +++ .../posts/attributes/_predefined_value.haml | 7 ++++++ 3 files changed, 34 insertions(+) create mode 100644 app/models/metadata_predefined_value.rb create mode 100644 app/views/posts/attribute_ro/_predefined_value.haml create mode 100644 app/views/posts/attributes/_predefined_value.haml diff --git a/app/models/metadata_predefined_value.rb b/app/models/metadata_predefined_value.rb new file mode 100644 index 00000000..9cf36382 --- /dev/null +++ b/app/models/metadata_predefined_value.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Un campo de texto seleccionado de una lista de valores posibles +class MetadataPredefinedValue < MetadataString + # Obtiene todos los valores desde el layout, en un formato compatible + # con options_for_select. + # + # @return [Hash] + def values + @values ||= layout.dig(:metadata, name, 'values', I18n.locale.to_s)&.invert || {} + end + + private + + # Solo permite almacenar los valores predefinidos. + # + # @return [String] + def sanitize(string) + v = super string + return '' unless values.values.include? v + + v + end +end diff --git a/app/views/posts/attribute_ro/_predefined_value.haml b/app/views/posts/attribute_ro/_predefined_value.haml new file mode 100644 index 00000000..67642e2c --- /dev/null +++ b/app/views/posts/attribute_ro/_predefined_value.haml @@ -0,0 +1,3 @@ +%tr{ id: attribute } + %th= post_label_t(attribute, post: post) + %td{ dir: dir, lang: locale }= metadata.value diff --git a/app/views/posts/attributes/_predefined_value.haml b/app/views/posts/attributes/_predefined_value.haml new file mode 100644 index 00000000..b0d21f35 --- /dev/null +++ b/app/views/posts/attributes/_predefined_value.haml @@ -0,0 +1,7 @@ +.form-group + = label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post) + = select_tag(plain_field_name_for(base, attribute), + options_for_select(metadata.values, metadata.value), + **field_options(attribute, metadata), include_blank: t('.empty')) + = render 'posts/attribute_feedback', + post: post, attribute: attribute, metadata: metadata From 9b8c09cb004581d2add73638edb3e1b5f7825eda Mon Sep 17 00:00:00 2001 From: f Date: Sat, 11 Sep 2021 17:06:27 -0300 Subject: [PATCH 17/99] =?UTF-8?q?Soportar=20campos=20n=C3=BAmericos=20con?= =?UTF-8?q?=20decimales?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_float.rb | 31 ++++++++++++++++++++++++ app/views/posts/attribute_ro/_float.haml | 3 +++ app/views/posts/attributes/_float.haml | 6 +++++ 3 files changed, 40 insertions(+) create mode 100644 app/models/metadata_float.rb create mode 100644 app/views/posts/attribute_ro/_float.haml create mode 100644 app/views/posts/attributes/_float.haml diff --git a/app/models/metadata_float.rb b/app/models/metadata_float.rb new file mode 100644 index 00000000..b4288a3b --- /dev/null +++ b/app/models/metadata_float.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# Un campo numérico de punto flotante +class MetadataFloat < MetadataTemplate + # Nada + def default_value + super || nil + end + + def save + return true unless changed? + + self[:value] = value.to_f + self[:value] = encrypt(value) if private? + + true + end + + # Indicarle al navegador que acepte números decimales + # + # @return [Float] + def step + 0.05 + end + + private + + def decrypt(value) + super(value).to_f + end +end diff --git a/app/views/posts/attribute_ro/_float.haml b/app/views/posts/attribute_ro/_float.haml new file mode 100644 index 00000000..67642e2c --- /dev/null +++ b/app/views/posts/attribute_ro/_float.haml @@ -0,0 +1,3 @@ +%tr{ id: attribute } + %th= post_label_t(attribute, post: post) + %td{ dir: dir, lang: locale }= metadata.value diff --git a/app/views/posts/attributes/_float.haml b/app/views/posts/attributes/_float.haml new file mode 100644 index 00000000..6239c613 --- /dev/null +++ b/app/views/posts/attributes/_float.haml @@ -0,0 +1,6 @@ +.form-group + = label_tag "#{base}_#{attribute}", post_label_t(attribute, post: post) + = number_field base, attribute, value: metadata.value, step: metadata.step, + **field_options(attribute, metadata) + = render 'posts/attribute_feedback', + post: post, attribute: attribute, metadata: metadata From a242ceee68c7058ca55fa35eb3721b2cb104b364 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 11 Sep 2021 17:26:44 -0300 Subject: [PATCH 18/99] Siempre guardar el valor de los campos booleanos --- app/models/metadata_boolean.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/models/metadata_boolean.rb b/app/models/metadata_boolean.rb index 5e4b456f..53a763fd 100644 --- a/app/models/metadata_boolean.rb +++ b/app/models/metadata_boolean.rb @@ -31,6 +31,11 @@ class MetadataBoolean < MetadataTemplate self[:value] = true_values.include? self[:value] end + # Siempre guardar el valor de este campo a menos que sea nulo + def empty? + !value.nil? + end + private # Los valores que evalúan a verdadero From 47096f20b7dd8c96aaa8cdf334e3698d92d10f37 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 11 Sep 2021 19:43:27 -0300 Subject: [PATCH 19/99] =?UTF-8?q?Traducci=C3=B3n=20de=20valores=20vac?= =?UTF-8?q?=C3=ADos?= 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, 4 insertions(+) diff --git a/config/locales/en.yml b/config/locales/en.yml index fc194eab..058456b1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -413,6 +413,8 @@ en: destroy: Remove image belongs_to: empty: "(Empty)" + predefined_value: + empty: "(Empty)" draft: label: Draft reorder: diff --git a/config/locales/es.yml b/config/locales/es.yml index e8185391..f5c13c8b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -421,6 +421,8 @@ es: destroy: 'Eliminar imagen' belongs_to: empty: "(Vacío)" + predefined_value: + empty: "(Vacío)" draft: label: Borrador reorder: From ed213cda9f040e0e8f6d9de29e1da9609a0c3415 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 11 Sep 2021 20:17:35 -0300 Subject: [PATCH 20/99] =?UTF-8?q?Actualizaci=C3=B3n=20de=20cuidados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8ce97f31..8846d2a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -89,7 +89,7 @@ GEM jekyll-relative-urls (~> 0.0) jekyll-seo-tag (~> 2.1) ast (2.4.2) - autoprefixer-rails (10.3.1.0) + autoprefixer-rails (10.3.3.0) execjs (~> 2) bcrypt (3.1.16-x86_64-linux-musl) bcrypt_pbkdf (1.1.0-x86_64-linux-musl) @@ -196,7 +196,7 @@ GEM railties (>= 5.0.0) fast_blank (1.0.1-x86_64-linux-musl) fast_jsonparser (0.5.0-x86_64-linux-musl) - ffi (1.15.3-x86_64-linux-musl) + ffi (1.15.4-x86_64-linux-musl) flamegraph (0.9.5) forwardable-extended (2.6.0) friendly_id (5.4.2) @@ -296,7 +296,7 @@ GEM sassc (> 2.0.1, < 3.0) jekyll-seo-tag (2.7.1) jekyll (>= 3.8, < 5.0) - jekyll-spree-client (0.1.17) + jekyll-spree-client (0.1.18) fast_blank (~> 1) spree-api-client (>= 0.2.3) jekyll-turbolinks (0.0.5) @@ -341,7 +341,7 @@ GEM method_source (1.0.0) mime-types (3.3.1) mime-types-data (~> 3.2015) - mime-types-data (3.2021.0704) + mime-types-data (3.2021.0901) mini_histogram (0.3.1) mini_magick (4.11.0) mini_mime (1.1.1) @@ -386,7 +386,7 @@ GEM rack (2.2.3) rack-cors (1.1.1) rack (>= 2.0.0) - rack-mini-profiler (2.3.2) + rack-mini-profiler (2.3.3) rack (>= 1.2.0) rack-proxy (0.7.0) rack @@ -493,7 +493,7 @@ GEM unicode-display_width (>= 1.4.0, < 3.0) rubocop-ast (1.11.0) parser (>= 3.0.1.1) - rubocop-rails (2.11.3) + rubocop-rails (2.12.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.7.0, < 2.0) @@ -511,7 +511,7 @@ GEM ruby_parser (3.17.0) sexp_processor (~> 4.15, >= 4.15.1) rubyzip (2.3.2) - rugged (1.1.1-x86_64-linux-musl) + rugged (1.2.0-x86_64-linux-musl) safe_yaml (1.0.6) safely_block (0.3.0) errbase (>= 0.1.1) From c601845a27c5f1a7244c4b88b3736cd115b498ff Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Sep 2021 19:50:24 -0300 Subject: [PATCH 21/99] Garantizar que todas las lecturas se hacen dentro del directorio del sitio fixes ##2667 fixes ##2655 fixes ##2640 fixes #2675 fixes #2653 fixes #2635 fixes #2624 fixes #2626 fixes #2627 fixes #2629 fixes #2634 fixes #2636 fixes #2637 fixes #2641 fixes #2642 fixes #2643 fixes #2644 fixes #2645 fixes #2646 fixes #2648 fixes #2649 fixes #2650 fixes #2651 fixes #2654 fixes #2657 fixes #2672 fixes #2676 fixes #2677 fixes #2678 fixes #2681 fixes #2682 fixes #2687 fixes #2688 fixes #2689 fixes #2691 fixes #2692 fixes #2693 --- app/models/site.rb | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index 58f20745..ddfe2bc9 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -65,9 +65,6 @@ class Site < ApplicationRecord accepts_nested_attributes_for :deploys, allow_destroy: true - # El sitio en Jekyll - attr_reader :jekyll - # XXX: Es importante incluir luego de los callbacks de :load_jekyll include Site::Index @@ -180,29 +177,28 @@ class Site < ApplicationRecord # Trae los datos del directorio _data dentro del sitio def data - unless @jekyll.data.present? - @jekyll.reader.read_data - - # Define los valores por defecto según la llave buscada - @jekyll.data.default_proc = proc do |data, key| - data[key] = case key - when 'layout' then {} - end + unless jekyll.data.present? + run_in_path do + jekyll.reader.read_data + jekyll.data['layouts'] ||= {} end end - @jekyll.data + jekyll.data end # Traer las colecciones. Todos los artículos van a estar dentro de # colecciones. def collections unless @read - @jekyll.reader.read_collections + run_in_path do + jekyll.reader.read_collections + end + @read = true end - @jekyll.collections + jekyll.collections end # Traer la configuración de forma modificable @@ -290,7 +286,9 @@ class Site < ApplicationRecord # # @return [Hash] def theme_layouts - @jekyll.reader.read_layouts + run_in_path do + jekyll.reader.read_layouts + end end # Trae todos los valores disponibles para un campo @@ -332,6 +330,12 @@ class Site < ApplicationRecord status == 'building' end + def jekyll + run_in_path do + @jekyll ||= Jekyll::Site.new(configuration) + end + end + # Cargar el sitio Jekyll # # TODO: En lugar de leer todo junto de una vez, extraer la carga de @@ -345,10 +349,7 @@ class Site < ApplicationRecord def reload_jekyll! reset - - Dir.chdir(path) do - @jekyll = Jekyll::Site.new(configuration) - end + jekyll end def reload @@ -526,4 +527,8 @@ class Site < ApplicationRecord errors.add(:design_id, I18n.t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.error')) end + + def run_in_path(&block) + Dir.chdir path, &block + end end From 5a324ae71f29616b4661c6b364ee5a3282a5dd14 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Sep 2021 21:00:10 -0300 Subject: [PATCH 22/99] No cortar las columnas --- app/views/posts/index.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 8b776590..c00d59af 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -112,11 +112,11 @@ %span{ lang: post.locale, dir: dir }= category = '/' unless post.front_matter['categories'].last == category - %td + %td.text-nowrap = post.created_at.strftime('%F') %br/ = post.order - %td + %td.text-nowrap - if @usuarie || policy(post).edit? = link_to t('posts.edit'), edit_site_post_path(@site, post.path), class: 'btn btn-block' - if @usuarie || policy(post).destroy? From 859b8518c0f722cfd06aaab0bc59259870c67609 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Sep 2021 21:00:48 -0300 Subject: [PATCH 23/99] =?UTF-8?q?Mostrar=20el=20tipo=20de=20art=C3=ADculo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/posts/index.haml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index c00d59af..5c47f679 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -104,13 +104,13 @@ %span{ lang: post.locale, dir: dir }= post.title - if post.front_matter['draft'].present? %span.badge.badge-primary= I18n.t('posts.attributes.draft.label') - - if post.front_matter['categories'].present? - %br - %small - - post.front_matter['categories'].each do |category| - = link_to site_posts_path(@site, **@filter_params.merge(category: category)) do - %span{ lang: post.locale, dir: dir }= category - = '/' unless post.front_matter['categories'].last == category + %br + %small + = link_to @site.layouts[post.layout].humanized_name, site_posts_path(@site, **@filter_params.merge(layout: post.layout)) + - post.front_matter['categories']&.each do |category| + = link_to site_posts_path(@site, **@filter_params.merge(category: category)) do + %span{ lang: post.locale, dir: dir }= category + = '/' unless post.front_matter['categories'].last == category %td.text-nowrap = post.created_at.strftime('%F') From 8e1f5c5558627efa0721703591d940aa288f9b85 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Sep 2021 21:02:09 -0300 Subject: [PATCH 24/99] =?UTF-8?q?Paginaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 1 + Gemfile.lock | 17 ++++++++++++++++- app/controllers/posts_controller.rb | 4 ++-- config/routes.rb | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 4256e307..db06827d 100644 --- a/Gemfile +++ b/Gemfile @@ -67,6 +67,7 @@ gem 'terminal-table' gem 'validates_hostname' gem 'webpacker' gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' +gem 'kaminari' # database gem 'hairtrigger' diff --git a/Gemfile.lock b/Gemfile.lock index 33fba3a0..e08bcb05 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -309,6 +309,18 @@ GEM jekyll-write-and-commit-changes (0.1.2) jekyll (~> 4) rugged (~> 1) + kaminari (1.2.1) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.1) + kaminari-activerecord (= 1.2.1) + kaminari-core (= 1.2.1) + kaminari-actionview (1.2.1) + actionview + kaminari-core (= 1.2.1) + kaminari-activerecord (1.2.1) + activerecord + kaminari-core (= 1.2.1) + kaminari-core (1.2.1) kramdown (2.3.1) rexml kramdown-parser-gfm (1.1.0) @@ -345,6 +357,7 @@ GEM mini_histogram (0.3.1) mini_magick (4.11.0) mini_mime (1.1.0) + mini_portile2 (2.5.3) minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) @@ -357,7 +370,8 @@ GEM net-ssh (6.1.0) netaddr (2.0.4) nio4r (2.5.7-x86_64-linux-musl) - nokogiri (1.11.7-x86_64-linux) + nokogiri (1.11.7-x86_64-linux-musl) + mini_portile2 (~> 2.5.0) racc (~> 1.4) orm_adapter (0.5.0) parallel (1.20.1) @@ -667,6 +681,7 @@ DEPENDENCIES jekyll-data! jekyll-images jekyll-include-cache + kaminari letter_opener listen (>= 3.0.5, < 3.2) loaf diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 3ef26720..05ae2736 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -24,7 +24,7 @@ class PostsController < ApplicationController # más simple saber si hubo cambios. if stale?([current_usuarie, site, filter_params]) # Todos los artículos de este sitio para el idioma actual - @posts = site.indexed_posts.where(locale: locale) + @posts = site.indexed_posts.where(locale: locale).page(filter_params.delete(:page)) # De este tipo @posts = @posts.where(layout: filter_params[:layout]) if filter_params[:layout] # Que estén dentro de la categoría @@ -154,7 +154,7 @@ class PostsController < ApplicationController # # @return [Hash] def filter_params - @filter_params ||= params.permit(:q, :category, :layout).to_h.select { |_, v| v.present? } + @filter_params ||= params.permit(:q, :category, :layout, :page).to_h.select { |_, v| v.present? } end def site diff --git a/config/routes.rb b/config/routes.rb index 2c5f1c60..15ee4150 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -60,6 +60,7 @@ Rails.application.routes.draw do scope '(:locale)' do post :'posts/reorder', to: 'posts#reorder' resources :posts do + get 'p/:page', action: :index, on: :collection get :preview, to: 'posts#preview' end end From f90c92dc26ff5e69385153ee1547c461d44210a1 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Sep 2021 21:03:07 -0300 Subject: [PATCH 25/99] =?UTF-8?q?Poder=20navegar=20p=C3=A1ginas=20en=20la?= =?UTF-8?q?=20lista=20de=20art=C3=ADculos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/posts/index.haml | 22 ++++++++++++++-------- config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 5c47f679..654210f2 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -72,14 +72,20 @@ %thead %tr %th.border-0.background-white.position-sticky{ style: 'top: 0; z-index: 2', colspan: '4' } - = submit_tag t('posts.reorder.submit'), class: 'btn' - %button.btn{ data: { action: 'reorder#unselect' } } - = t('posts.reorder.unselect') - %span.badge{ data: { target: 'reorder.counter' } } 0 - %button.btn{ data: { action: 'reorder#up' } }= t('posts.reorder.up') - %button.btn{ data: { action: 'reorder#down' } }= t('posts.reorder.down') - %button.btn{ data: { action: 'reorder#top' } }= t('posts.reorder.top') - %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') + .d-flex.flex-row.justify-content-between + %div + = submit_tag t('posts.reorder.submit'), class: 'btn' + %button.btn{ data: { action: 'reorder#unselect' } } + = t('posts.reorder.unselect') + %span.badge{ data: { target: 'reorder.counter' } } 0 + %button.btn{ data: { action: 'reorder#up' } }= t('posts.reorder.up') + %button.btn{ data: { action: 'reorder#down' } }= t('posts.reorder.down') + %button.btn{ data: { action: 'reorder#top' } }= t('posts.reorder.top') + %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') + + %div + = link_to_prev_page @posts, t('posts.prev'), class: 'btn' + = link_to_next_page @posts, t('posts.next'), class: 'btn' %tbody - dir = t("locales.#{@locale}.dir") - size = @posts.size diff --git a/config/locales/en.yml b/config/locales/en.yml index fc194eab..e950fc32 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -376,6 +376,8 @@ en: en: 'English' ar: 'Arabic' posts: + prev: Previous page + next: Next page empty: "There are no results for those search parameters." caption: Post list attribute_ro: diff --git a/config/locales/es.yml b/config/locales/es.yml index e8185391..459d643b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -384,6 +384,8 @@ es: en: 'inglés' ar: 'árabe' posts: + prev: Página anterior + next: Página siguiente empty: No hay artículos con estos parámetros de búsqueda. caption: Lista de artículos attribute_ro: From 0dece732aadc407b10674158fd86a4460e42e622 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 15 Sep 2021 21:03:28 -0300 Subject: [PATCH 26/99] =?UTF-8?q?Al=20buscar=20eliminar=20la=20paginaci?= =?UTF-8?q?=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/posts/index.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 654210f2..90e30966 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -40,7 +40,7 @@ %section.col = render 'layouts/flash' .d-flex.justify-content-between.align-items-center.pl-2-plus.pr-2-plus.mb-2 - %form + %form{ action: site_posts_path } - @filter_params.each do |param, value| - next if param == 'q' %input{ type: 'hidden', name: param, value: value } From 5c2e5fd62ee217880f8881f338a2db8130d37b06 Mon Sep 17 00:00:00 2001 From: f Date: Sun, 26 Sep 2021 19:29:03 -0300 Subject: [PATCH 27/99] =?UTF-8?q?Agregar=20=C3=ADndices=20=C3=BAnicos=20qu?= =?UTF-8?q?e=20pens=C3=A1bamos=20que=20ten=C3=ADamos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `unique: true` es un parámetro de `add_index` no de `add_column`. --- db/migrate/20210926205448_add_uniqueness.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 db/migrate/20210926205448_add_uniqueness.rb diff --git a/db/migrate/20210926205448_add_uniqueness.rb b/db/migrate/20210926205448_add_uniqueness.rb new file mode 100644 index 00000000..7399ba4c --- /dev/null +++ b/db/migrate/20210926205448_add_uniqueness.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# Agrega índices únicos que pensábamos que ya existían. +class AddUniqueness < ActiveRecord::Migration[6.1] + def change + add_index :designs, :name, unique: true + add_index :designs, :gem, unique: true + add_index :licencias, :name, unique: true + end +end From 662b5eeec4da85d4ae9fdd89f21e13501d6ff940 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 4 Oct 2021 14:48:19 -0300 Subject: [PATCH 28/99] guardar y mostrar la url actual en el campo permalink --- app/models/metadata_permalink.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/models/metadata_permalink.rb b/app/models/metadata_permalink.rb index 58feb9e5..dc65aa86 100644 --- a/app/models/metadata_permalink.rb +++ b/app/models/metadata_permalink.rb @@ -2,6 +2,12 @@ # 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 unless post.new? + end + # Los permalinks nunca pueden ser privados def private? false From f8b1752c04f08e6599ffd461d6cce3e0f33e1643 Mon Sep 17 00:00:00 2001 From: Maki Date: Mon, 4 Oct 2021 14:49:14 -0300 Subject: [PATCH 29/99] cambio texto cerrar sesion #2896 --- 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 fc194eab..28678b2f 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -163,7 +163,7 @@ en: signature: 'With love, Sutty' breadcrumb: title: 'Your location in Sutty' - logout: Exit + logout: Log out mutual_aid: Mutual aid collaborations: collaborate: diff --git a/config/locales/es.yml b/config/locales/es.yml index e8185391..ee55d9e7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -163,7 +163,7 @@ es: signature: 'Con cariño, Sutty' breadcrumb: title: 'Tu ubicación en Sutty' - logout: Salir + logout: Cerrar sesión mutual_aid: Ayuda mutua collaborations: collaborate: From 930f88903e5c73c0f5936f3124c34c9605bca837 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 7 Oct 2021 15:24:21 -0300 Subject: [PATCH 30/99] =?UTF-8?q?instalar=20chartkick=20para=20generar=20g?= =?UTF-8?q?r=C3=A1ficos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 1 + Gemfile.lock | 1 + package.json | 4 +++- yarn.lock | 24 ++++++++++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 2f5446a0..b5e8664b 100644 --- a/Gemfile +++ b/Gemfile @@ -28,6 +28,7 @@ gem 'jbuilder', '~> 2.5' # Use ActiveModel has_secure_password gem 'bcrypt', '~> 3.1.7' gem 'blazer' +gem 'chartkick' gem 'commonmarker' gem 'devise' gem 'devise-i18n' diff --git a/Gemfile.lock b/Gemfile.lock index 6c873d9b..9d1f512b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -642,6 +642,7 @@ DEPENDENCIES bootstrap (~> 4) brakeman capybara (~> 2.13) + chartkick commonmarker concurrent-ruby-ext database_cleaner diff --git a/package.json b/package.json index 0a2458a6..184f7ebb 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,8 @@ "zepto": "^1.2.0" }, "devDependencies": { - "@types/rails__activestorage": "^6.0.0" + "@types/rails__activestorage": "^6.0.0", + "chart.js": "^3.5.1", + "chartkick": "^4.0.5" } } diff --git a/yarn.lock b/yarn.lock index 11ff78cb..68b7fd23 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2119,6 +2119,25 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chart.js@>=3.0.2, chart.js@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-3.5.1.tgz#73e24d23a4134a70ccdb5e79a917f156b6f3644a" + integrity sha512-m5kzt72I1WQ9LILwQC4syla/LD/N413RYv2Dx2nnTkRS9iv/ey1xLTt0DnPc/eWV4zI+BgEgDYBIzbQhZHc/PQ== + +chartjs-adapter-date-fns@>=2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chartjs-adapter-date-fns/-/chartjs-adapter-date-fns-2.0.0.tgz#5e53b2f660b993698f936f509c86dddf9ed44c6b" + integrity sha512-rmZINGLe+9IiiEB0kb57vH3UugAtYw33anRiw5kS2Tu87agpetDDoouquycWc9pRsKtQo5j+vLsYHyr8etAvFw== + +chartkick@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/chartkick/-/chartkick-4.0.5.tgz#310a60c931e8ceedc39adee2ef8e9d1e474cb0e6" + integrity sha512-xKak4Fsgfvp1hj/LykRKkniDMaZASx2A4TdVc/sfsiNFFNf1m+D7PGwP1vgj1UsbsCjOCSfGWWyJpOYxkUCBug== + optionalDependencies: + chart.js ">=3.0.2" + chartjs-adapter-date-fns ">=2.0.0" + date-fns ">=2.0.0" + chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -2744,6 +2763,11 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" +date-fns@>=2.0.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.24.0.tgz#7d86dc0d93c87b76b63d213b4413337cfd1c105d" + integrity sha512-6ujwvwgPID6zbI0o7UbURi2vlLDR9uP26+tW6Lg+Ji3w7dd0i3DOcjcClLjLPranT60SSEFBwdSyYwn/ZkPIuw== + debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" From a7ae7f8e8d7cec044d2d01a49b51bc100e629e23 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 16:31:02 -0300 Subject: [PATCH 31/99] ver cantidad de visitas --- app/controllers/stats_controller.rb | 64 ++++++++++++++++++++++++++--- app/javascript/packs/application.js | 1 + app/policies/site_stat_policy.rb | 4 ++ app/views/stats/index.haml | 19 ++++----- config/locales/en.yml | 9 ++++ config/locales/es.yml | 13 ++++++ config/routes.rb | 1 + 7 files changed, 94 insertions(+), 17 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 07baaf1a..07be68c4 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -5,14 +5,68 @@ class StatsController < ApplicationController include Pundit before_action :authenticate_usuarie! + INTERVALS = %i[hour day week month].freeze + + # XXX: Permitir a Chart.js inyectar su propio CSS + content_security_policy only: :index do |policy| + policy.style_src :self, :unsafe_inline + policy.script_src :self, :unsafe_inline + end + def index @site = find_site authorize SiteStat.new(@site) - # Solo queremos el promedio de tiempo de compilación, no de - # instalación de dependencias. - stats = @site.build_stats.jekyll - @build_avg = stats.average(:seconds).to_f.round(2) - @build_max = stats.maximum(:seconds).to_f.round(2) + @chart_params = { interval: interval } + hostnames + end + + # Genera un gráfico de visitas por dominio asociado a este sitio + def host + @site = find_site + authorize SiteStat.new(@site) + + @stats = Rollup.where_dimensions(host: hostnames).multi_series('host', interval: interval).tap do |series| + series.each do |serie| + serie[:name] = serie.dig(:dimensions, 'host') + serie[:data].transform_values! do |value| + value * nodes + end + end + end + + render json: @stats + end + + private + + # TODO: Eliminar cuando mergeemos referer-origin + def hostnames + @hostnames ||= [@site.hostname, @site.alternative_hostnames].flatten + end + + # Obtiene y valida los intervalos + # + # @return [Symbol] + def interval + @interval ||= begin + i = params[:interval].to_sym + INTERVALS.include?(i) ? i : :day + end + end + + # Obtiene la cantidad de nodos de Sutty, para poder calcular la + # cantidad de visitas. + # + # Como repartimos las visitas por nodo rotando las IPs en el + # nameserver y los resolvedores de DNS eligen un nameserver + # aleatoriamente, la cantidad de visitas se reparte + # equitativamente. + # + # XXX: Remover cuando podamos centralizar los AccessLog + # + # @return [Integer] + def nodes + @nodes ||= ENV.fetch('NODES', 1).to_i end end diff --git a/app/javascript/packs/application.js b/app/javascript/packs/application.js index 6aa3a2e1..492ca736 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/packs/application.js @@ -18,6 +18,7 @@ import 'etc' import Rails from '@rails/ujs' import Turbolinks from 'turbolinks' import * as ActiveStorage from '@rails/activestorage' +import 'chartkick/chart.js' Rails.start() Turbolinks.start() diff --git a/app/policies/site_stat_policy.rb b/app/policies/site_stat_policy.rb index a797034c..d11be95d 100644 --- a/app/policies/site_stat_policy.rb +++ b/app/policies/site_stat_policy.rb @@ -12,4 +12,8 @@ class SiteStatPolicy def index? site_stat.site.usuarie? usuarie end + + def host? + index? + end end diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index f49cdd15..b5943690 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -1,17 +1,12 @@ -= render 'layouts/breadcrumb', - crumbs: [link_to(t('sites.index.title'), sites_path), - link_to(@site.name, site_path(@site)), t('.title')] - .row .col %h1= t('.title') %p.lead= t('.help') - %table.table.table-condensed - %tbody - %tr - %td= t('.build.average') - %td= distance_of_time_in_words_if_more_than_a_minute @build_avg - %tr - %td= t('.build.maximum') - %td= distance_of_time_in_words_if_more_than_a_minute @build_max + .mb-3 + - StatsController::INTERVALS.each do |interval| + = link_to t(".#{interval}"), site_stats_path(interval: interval), class: 'btn' + + .mb-3 + %h2= t('.host', count: @hostnames.size) + = line_chart site_stats_host_path(@chart_params), locale: 'es' diff --git a/config/locales/en.yml b/config/locales/en.yml index fc194eab..96250301 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -255,6 +255,15 @@ en: build: average: 'Average building time' maximum: 'Maximum building time' + hour: 'Hourly' + day: 'Daily' + week: 'Weekly' + month: 'Monthly' + year: 'Yearly' + host: + zero: 'Site visits' + one: 'Site visits' + other: 'Visits by site name' sites: donations: url: 'https://donaciones.sutty.nl/en/' diff --git a/config/locales/es.yml b/config/locales/es.yml index e8185391..7fcebcbe 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -260,6 +260,15 @@ es: build: average: 'Tiempo promedio de generación' maximum: 'Tiempo máximo de generación' + hour: 'Por hora' + day: 'Diarias' + week: 'Semanales' + month: 'Mensuales' + year: 'Anuales' + host: + zero: 'Visitas del sitio' + one: 'Visitas del sitio' + other: 'Visitas por nombre del sitio' sites: donations: url: 'https://donaciones.sutty.nl/' @@ -584,3 +593,7 @@ es: edit: 'Editando' usuaries: index: 'Usuaries' + day: 'Día' + week: 'Semana' + month: 'Mes' + year: 'Año' diff --git a/config/routes.rb b/config/routes.rb index 2c5f1c60..0af58080 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -75,5 +75,6 @@ Rails.application.routes.draw do post 'reorder_posts', to: 'sites#reorder_posts' resources :stats, only: [:index] + get :'stats/host', to: 'stats#host' end end From df2b66afe85d806e32aee341fdc4beb5ee5cd873 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:21:09 -0300 Subject: [PATCH 32/99] =?UTF-8?q?llevar=20el=20registro=20de=20las=20recol?= =?UTF-8?q?ecciones=20de=20estad=C3=ADsticas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/stat.rb | 3 +++ db/migrate/20211008201239_create_stats.rb | 12 ++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 app/models/stat.rb create mode 100644 db/migrate/20211008201239_create_stats.rb diff --git a/app/models/stat.rb b/app/models/stat.rb new file mode 100644 index 00000000..cf717b05 --- /dev/null +++ b/app/models/stat.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +class Stat < ApplicationRecord; end diff --git a/db/migrate/20211008201239_create_stats.rb b/db/migrate/20211008201239_create_stats.rb new file mode 100644 index 00000000..e1aff8f6 --- /dev/null +++ b/db/migrate/20211008201239_create_stats.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Una tabla que lleva el recuento de recolección de estadísticas, solo +# es necesario para saber cuándo se hicieron, si se hicieron y usar como +# caché. +class CreateStats < ActiveRecord::Migration[6.1] + def change + create_table :stats do |t| + t.timestamps + end + end +end From a2e4e0ab89910f85632ad231bbc2bdc01e69836b Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:24:19 -0300 Subject: [PATCH 33/99] =?UTF-8?q?informar=20hace=20cu=C3=A1nto=20se=20actu?= =?UTF-8?q?alizaron=20los=20datos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/stats_controller.rb | 5 +++++ app/views/stats/index.haml | 5 +++++ config/locales/en.yml | 4 +--- config/locales/es.yml | 4 +--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 07be68c4..8d1575bd 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -19,6 +19,7 @@ class StatsController < ApplicationController @chart_params = { interval: interval } hostnames + last_stat end # Genera un gráfico de visitas por dominio asociado a este sitio @@ -40,6 +41,10 @@ class StatsController < ApplicationController private + def last_stat + @last_stat ||= Stat.last + end + # TODO: Eliminar cuando mergeemos referer-origin def hostnames @hostnames ||= [@site.hostname, @site.alternative_hostnames].flatten diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index b5943690..e77454b1 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -2,6 +2,11 @@ .col %h1= t('.title') %p.lead= t('.help') + %p + %small + = t('.last_update') + %time{ datetime: @last_stat.created_at } + "#{time_ago_in_words @last_stat.created_at}." .mb-3 - StatsController::INTERVALS.each do |interval| diff --git a/config/locales/en.yml b/config/locales/en.yml index 96250301..623d8c2e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -252,9 +252,7 @@ en: help: | These statistics show information about how your site is generated and how many resources it uses. - build: - average: 'Average building time' - maximum: 'Maximum building time' + last_update: 'Updated every hour. Last update on ' hour: 'Hourly' day: 'Daily' week: 'Weekly' diff --git a/config/locales/es.yml b/config/locales/es.yml index 7fcebcbe..4085a862 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -257,9 +257,7 @@ es: help: | Las estadísticas visibilizan información sobre cómo se genera y cuántos recursos utiliza tu sitio. - build: - average: 'Tiempo promedio de generación' - maximum: 'Tiempo máximo de generación' + last_update: 'Actualizadas cada hora. Última actualización hace ' hour: 'Por hora' day: 'Diarias' week: 'Semanales' From cfb2d7a61d1c29da08d9dd000d7d9039fe2af54e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:33:31 -0300 Subject: [PATCH 34/99] todas las peticiones necesitan une usuarie --- app/controllers/stats_controller.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 8d1575bd..0c185329 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -4,6 +4,7 @@ class StatsController < ApplicationController include Pundit before_action :authenticate_usuarie! + before_action :authorize_stats INTERVALS = %i[hour day week month].freeze @@ -14,9 +15,6 @@ class StatsController < ApplicationController end def index - @site = find_site - authorize SiteStat.new(@site) - @chart_params = { interval: interval } hostnames last_stat @@ -24,8 +22,6 @@ class StatsController < ApplicationController # Genera un gráfico de visitas por dominio asociado a este sitio def host - @site = find_site - authorize SiteStat.new(@site) @stats = Rollup.where_dimensions(host: hostnames).multi_series('host', interval: interval).tap do |series| series.each do |serie| @@ -45,6 +41,11 @@ class StatsController < ApplicationController @last_stat ||= Stat.last end + def authorize_stats + @site = find_site + authorize SiteStat.new(@site) + end + # TODO: Eliminar cuando mergeemos referer-origin def hostnames @hostnames ||= [@site.hostname, @site.alternative_hostnames].flatten From 38090d7de72d5cfdb1cad2e4349479ed17f04221 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:34:16 -0300 Subject: [PATCH 35/99] resaltar el intervalo seleccionado --- app/views/stats/index.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index e77454b1..63aa76cd 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -10,7 +10,7 @@ .mb-3 - StatsController::INTERVALS.each do |interval| - = link_to t(".#{interval}"), site_stats_path(interval: interval), class: 'btn' + = link_to t(".#{interval}"), site_stats_path(interval: interval), class: "btn #{'btn-primary active' if params[:interval].to_sym == interval}" .mb-3 %h2= t('.host', count: @hostnames.size) From d2b1220df6f74ef46486beeb49ce9b1fd833658d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:35:40 -0300 Subject: [PATCH 36/99] informar cuando no hay datos --- app/controllers/stats_controller.rb | 24 ++++++++++++++++++++++++ config/locales/en.yml | 2 ++ config/locales/es.yml | 2 ++ 3 files changed, 28 insertions(+) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 0c185329..9cd1e5de 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -3,6 +3,8 @@ # Estadísticas del sitio class StatsController < ApplicationController include Pundit + include ActionView::Helpers::DateHelper + before_action :authenticate_usuarie! before_action :authorize_stats @@ -18,6 +20,7 @@ class StatsController < ApplicationController @chart_params = { interval: interval } hostnames last_stat + chart_options end # Genera un gráfico de visitas por dominio asociado a este sitio @@ -51,6 +54,27 @@ class StatsController < ApplicationController @hostnames ||= [@site.hostname, @site.alternative_hostnames].flatten end + # Opciones por defecto para los gráficos. + # + # La invitación a volver dentro de X tiempo es para dar un estimado de + # cuándo habrá información disponible, porque Rollup genera intervalos + # completos (¿aunque dice que no?) + # + # La diferencia se calcula sumando el intervalo a la hora de última + # toma de estadísticas y restando el tiempo que pasó desde ese + # momento. + def chart_options + time = last_stat.created_at + (1.send(interval)) + please_return_at = { please_return_at: distance_of_time_in_words(Time.now, time) } + + @chart_options ||= { + locale: I18n.locale, + empty: I18n.t('stats.index.empty', **please_return_at), + loading: I18n.t('stats.index.loading'), + html: %(
%{loading}
) + } + end + # Obtiene y valida los intervalos # # @return [Symbol] diff --git a/config/locales/en.yml b/config/locales/en.yml index 623d8c2e..58e0e726 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -253,6 +253,8 @@ en: These statistics show information about how your site is generated and how many resources it uses. last_update: 'Updated every hour. Last update on ' + empty: 'There is no enough information yet. We invite you to come back in %{please_return_at}!' + loading: 'Loading...' hour: 'Hourly' day: 'Daily' week: 'Weekly' diff --git a/config/locales/es.yml b/config/locales/es.yml index 4085a862..8df68896 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -258,6 +258,8 @@ es: Las estadísticas visibilizan información sobre cómo se genera y cuántos recursos utiliza tu sitio. last_update: 'Actualizadas cada hora. Última actualización hace ' + empty: 'Todavía no hay información suficiente. Te invitamos a volver en %{please_return_at} :)' + loading: 'Cargando...' hour: 'Por hora' day: 'Diarias' week: 'Semanales' From ef0055db0535492b62a95f6cd85970ead819ddb3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:36:31 -0300 Subject: [PATCH 37/99] =?UTF-8?q?agrupar=20por=20a=C3=B1o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/stats_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 9cd1e5de..a0937477 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -8,7 +8,7 @@ class StatsController < ApplicationController before_action :authenticate_usuarie! before_action :authorize_stats - INTERVALS = %i[hour day week month].freeze + INTERVALS = %i[hour day week month year].freeze # XXX: Permitir a Chart.js inyectar su propio CSS content_security_policy only: :index do |policy| From 8e9401036ce4f3c64aff0db21263d13e56e14e3b Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:38:02 -0300 Subject: [PATCH 38/99] =?UTF-8?q?cachear=20los=20resultados=20hasta=20la?= =?UTF-8?q?=20pr=C3=B3xima=20actualizaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/stats_controller.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index a0937477..0eae584b 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -25,17 +25,18 @@ class StatsController < ApplicationController # Genera un gráfico de visitas por dominio asociado a este sitio def host - - @stats = Rollup.where_dimensions(host: hostnames).multi_series('host', interval: interval).tap do |series| - series.each do |serie| - serie[:name] = serie.dig(:dimensions, 'host') - serie[:data].transform_values! do |value| - value * nodes + if stale? [last_stat, hostnames, interval] + stats = Rollup.where_dimensions(host: hostnames).multi_series('host', interval: interval).tap do |series| + series.each do |serie| + serie[:name] = serie.dig(:dimensions, 'host') + serie[:data].transform_values! do |value| + value * nodes + end end end end - render json: @stats + render json: stats end private From 224ea1ebc54ef6621614474eeaedd33f5dc633e3 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:39:55 -0300 Subject: [PATCH 39/99] =?UTF-8?q?mostrar=20gr=C3=A1ficos=20de=20recursos?= =?UTF-8?q?=20utilizados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/stats_controller.rb | 25 +++++++++++++++++++++++-- app/views/stats/index.haml | 11 +++++++++-- config/locales/en.yml | 18 +++++++++++++++--- config/locales/es.yml | 18 +++++++++++++++--- 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 0eae584b..d41573e2 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -9,6 +9,7 @@ class StatsController < ApplicationController before_action :authorize_stats INTERVALS = %i[hour day week month year].freeze + RESOURCES = %i[builds space_used build_time].freeze # XXX: Permitir a Chart.js inyectar su propio CSS content_security_policy only: :index do |policy| @@ -34,9 +35,22 @@ class StatsController < ApplicationController end end end - end - render json: stats + render json: stats + end + end + + def resources + if stale? [last_stat, interval, resource] + options = { + interval: interval, + dimensions: { + deploy_id: @site.deploys.where(type: 'DeployLocal').pluck(:id).first + } + } + + render json: Rollup.series(resource, **options) + end end private @@ -86,6 +100,13 @@ class StatsController < ApplicationController end end + def resource + @resource ||= begin + r = params[:resource].to_sym + RESOURCES.include?(r) ? r : :builds + end + end + # Obtiene la cantidad de nodos de Sutty, para poder calcular la # cantidad de visitas. # diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index 63aa76cd..0251955e 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -13,5 +13,12 @@ = link_to t(".#{interval}"), site_stats_path(interval: interval), class: "btn #{'btn-primary active' if params[:interval].to_sym == interval}" .mb-3 - %h2= t('.host', count: @hostnames.size) - = line_chart site_stats_host_path(@chart_params), locale: 'es' + %h2= t('.host.title', count: @hostnames.size) + %p.lead= t('.host.description') + = line_chart site_stats_host_path(@chart_params), **@chart_options + + - StatsController::RESOURCES.each do |resource| + .mb-3 + %h2= t(".resources.#{resource}.title") + %p.lead= t(".resources.#{resource}.description") + = line_chart site_stats_resources_path(resource: resource, **@chart_params), **@chart_options diff --git a/config/locales/en.yml b/config/locales/en.yml index 58e0e726..08313a03 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -261,9 +261,21 @@ en: month: 'Monthly' year: 'Yearly' host: - zero: 'Site visits' - one: 'Site visits' - other: 'Visits by site name' + title: + zero: 'Site visits' + one: 'Site visits' + other: 'Visits by site name' + description: 'Counts visited pages on your site, grouped by domain names in use.' + resources: + builds: + title: 'Site publication' + description: 'Times you published your site.' + space_used: + title: 'Server disk usage' + description: 'Average storage space used by your site.' + build_time: + title: 'Publication time' + description: 'Average time your site takes to build.' sites: donations: url: 'https://donaciones.sutty.nl/en/' diff --git a/config/locales/es.yml b/config/locales/es.yml index 8df68896..b1161287 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -266,9 +266,21 @@ es: month: 'Mensuales' year: 'Anuales' host: - zero: 'Visitas del sitio' - one: 'Visitas del sitio' - other: 'Visitas por nombre del sitio' + title: + zero: 'Visitas del sitio' + one: 'Visitas del sitio' + other: 'Visitas por nombre del sitio' + description: 'Cuenta la cantidad de páginas visitadas en tu sitio, dividida por los nombres de dominio en uso.' + resources: + builds: + title: 'Publicaciones del sitio' + description: 'Cantidad de veces que publicaste tu sitio.' + space_used: + title: 'Espacio utilizado en el servidor' + description: 'Espacio en disco que ocupa en promedio tu sitio.' + build_time: + title: 'Tiempo de publicación' + description: 'Tiempo promedio que toma en publicarse tu sitio.' sites: donations: url: 'https://donaciones.sutty.nl/' From 833213ec80c343379ccdd566aaa86e92e051b9ad Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:40:16 -0300 Subject: [PATCH 40/99] agregar opciones a cada recurso --- app/controllers/stats_controller.rb | 6 ++++++ app/views/stats/index.haml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index d41573e2..8045a653 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -10,6 +10,12 @@ class StatsController < ApplicationController INTERVALS = %i[hour day week month year].freeze RESOURCES = %i[builds space_used build_time].freeze + EXTRA_OPTIONS = { + builds: {}, + space_used: { bytes: true }, + build_time: {} + }.freeze + # XXX: Permitir a Chart.js inyectar su propio CSS content_security_policy only: :index do |policy| diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index 0251955e..101dee1e 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -21,4 +21,4 @@ .mb-3 %h2= t(".resources.#{resource}.title") %p.lead= t(".resources.#{resource}.description") - = line_chart site_stats_resources_path(resource: resource, **@chart_params), **@chart_options + = line_chart site_stats_resources_path(resource: resource, **@chart_params), **@chart_options.merge(StatsController::EXTRA_OPTIONS[resource]) From 86f1ac450469cfce2d53be41b7f9d594e2d3a985 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:40:52 -0300 Subject: [PATCH 41/99] =?UTF-8?q?fixup!=20mostrar=20gr=C3=A1ficos=20de=20r?= =?UTF-8?q?ecursos=20utilizados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/policies/site_stat_policy.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/policies/site_stat_policy.rb b/app/policies/site_stat_policy.rb index d11be95d..6c98c775 100644 --- a/app/policies/site_stat_policy.rb +++ b/app/policies/site_stat_policy.rb @@ -16,4 +16,8 @@ class SiteStatPolicy def host? index? end + + def resources? + index? + end end From 51c2fdf6d6899d5b931e2ac301007d33deb641b5 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:41:07 -0300 Subject: [PATCH 42/99] =?UTF-8?q?fixup!=20fixup!=20mostrar=20gr=C3=A1ficos?= =?UTF-8?q?=20de=20recursos=20utilizados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/routes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/routes.rb b/config/routes.rb index 0af58080..b59266fb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -76,5 +76,6 @@ Rails.application.routes.draw do resources :stats, only: [:index] get :'stats/host', to: 'stats#host' + get :'stats/resources', to: 'stats#resources' end end From 034245595587990cd73ca3a34e945d2127471c9d Mon Sep 17 00:00:00 2001 From: f Date: Fri, 8 Oct 2021 18:42:34 -0300 Subject: [PATCH 43/99] =?UTF-8?q?encontrar=20p=C3=A1ginas=20y=20distinguir?= =?UTF-8?q?=20si=20fueron=20cyborgs=20o=20no?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/access_log.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/access_log.rb b/app/models/access_log.rb index 0dceb7d7..3a066b33 100644 --- a/app/models/access_log.rb +++ b/app/models/access_log.rb @@ -6,4 +6,7 @@ class AccessLog < ApplicationRecord # # @see {https://en.wikipedia.org/wiki/List_of_HTTP_status_codes} scope :completed_requests, -> { where(request_method: 'GET', request_completion: 'OK', status: [200, 304]) } + scope :non_robots, -> { where(crawler: false) } + scope :robots, -> { where(crawler: true) } + scope :pages, -> { where(sent_http_content_type: ['text/html', 'text/html; charset=utf-8', 'text/html; charset=UTF-8']) } end From 306d1ed983f69456a219a6c5fae47ea5e98ff8b1 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 14:45:34 -0300 Subject: [PATCH 44/99] =?UTF-8?q?recolectar=20estad=C3=ADsticas=20una=20ve?= =?UTF-8?q?z=20por=20hora?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/stat_collection_job.rb | 66 +++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 app/jobs/stat_collection_job.rb diff --git a/app/jobs/stat_collection_job.rb b/app/jobs/stat_collection_job.rb new file mode 100644 index 00000000..c36d036c --- /dev/null +++ b/app/jobs/stat_collection_job.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +# Genera resúmenes de información para poder mostrar estadísticas y se +# corre regularmente a sí misma. +class StatCollectionJob < ApplicationJob + class CrontabException < StandardError; end + + # Descartar y notificar si pasó algo más. + # + # XXX: En realidad deberíamos seguir reintentando? + discard_on(Exception) do |_, error| + ExceptionNotifier.notify_exception error + end + + # Correr indefinidamente una vez por hora. + # + # XXX: El orden importa, si el descarte viene después, nunca se va a + # reintentar. + retry_on(StatCollectionJob::CrontabException, wait: 1.hour, attempts: Float::INFINITY) + + COLUMNS = %i[uri].freeze + + def perform(once: false) + Stat::INTERVALS.each do |interval| + options = { interval: interval } + + # Visitas por hostname + AccessLog.completed_requests.group(:host).rollup('host', **options) + + combined_columns **options + stats_by_site **options + end + + # Registrar que se hicieron todas las recolecciones + Stat.create! + + raise CrontabException unless once + end + + private + + # Combinación de columnas + def combined_columns(**options) + COLUMNS.each do |column| + AccessLog.completed_requests.group(:host, column).rollup("hostname|#{column}", **options) + end + end + + # Uso de recursos por cada sitio. + # + # XXX: En realidad se agrupan por el deploy_id, que siempre será el + # del DeployLocal. + def stats_by_site(**options) + Site.find_each do |site| + site.build_stats.jekyll.group(:deploy_id).rollup('builds', **options) + + site.build_stats.jekyll.group(:deploy_id).rollup('space_used', **options) do |rollup| + rollup.average(:bytes) + end + + site.build_stats.jekyll.group(:deploy_id).rollup('build_time', **options) do |rollup| + rollup.average(:seconds) + end + end + end +end From e35cbe79eb53f3dceb082865360e060c827a237c Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 14:46:58 -0300 Subject: [PATCH 45/99] =?UTF-8?q?recolectar=20visitas=20a=20p=C3=A1ginas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/stat_collection_job.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/jobs/stat_collection_job.rb b/app/jobs/stat_collection_job.rb index c36d036c..04f62b8a 100644 --- a/app/jobs/stat_collection_job.rb +++ b/app/jobs/stat_collection_job.rb @@ -25,10 +25,10 @@ class StatCollectionJob < ApplicationJob options = { interval: interval } # Visitas por hostname - AccessLog.completed_requests.group(:host).rollup('host', **options) + AccessLog.completed_requests.non_robots.pages.group(:host).rollup('host', **options) - combined_columns **options - stats_by_site **options + combined_columns(**options) + stats_by_site(**options) end # Registrar que se hicieron todas las recolecciones @@ -42,7 +42,7 @@ class StatCollectionJob < ApplicationJob # Combinación de columnas def combined_columns(**options) COLUMNS.each do |column| - AccessLog.completed_requests.group(:host, column).rollup("hostname|#{column}", **options) + AccessLog.completed_requests.non_robots.pages.group(:host, column).rollup("host|#{column}", **options) end end From 11568e6ce8e8471077278590cbd7de5a67b6003d Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 15:36:14 -0300 Subject: [PATCH 46/99] no distinguir entre todas las uris MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit para poder buscar descargas de archivos binarios después --- app/jobs/stat_collection_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/stat_collection_job.rb b/app/jobs/stat_collection_job.rb index 04f62b8a..5b7da160 100644 --- a/app/jobs/stat_collection_job.rb +++ b/app/jobs/stat_collection_job.rb @@ -42,7 +42,7 @@ class StatCollectionJob < ApplicationJob # Combinación de columnas def combined_columns(**options) COLUMNS.each do |column| - AccessLog.completed_requests.non_robots.pages.group(:host, column).rollup("host|#{column}", **options) + AccessLog.completed_requests.non_robots.group(:host, column).rollup("host|#{column}", **options) end end From c927a56befb1128deb3e631774e1084361c93744 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 15:47:42 -0300 Subject: [PATCH 47/99] ejecutar una vez por hora exacto --- app/jobs/stat_collection_job.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/jobs/stat_collection_job.rb b/app/jobs/stat_collection_job.rb index 5b7da160..6f8470b8 100644 --- a/app/jobs/stat_collection_job.rb +++ b/app/jobs/stat_collection_job.rb @@ -16,7 +16,7 @@ class StatCollectionJob < ApplicationJob # # XXX: El orden importa, si el descarte viene después, nunca se va a # reintentar. - retry_on(StatCollectionJob::CrontabException, wait: 1.hour, attempts: Float::INFINITY) + retry_on(StatCollectionJob::CrontabException, wait: 1.hour, attempts: Float::INFINITY, jitter: 0) COLUMNS = %i[uri].freeze From f36ea9629de280b7ef110d8d66d3f05097ce7520 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 15:50:38 -0300 Subject: [PATCH 48/99] centralizar valores --- app/controllers/stats_controller.rb | 9 +++------ app/models/stat.rb | 5 ++++- app/views/stats/index.haml | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 8045a653..093fbe93 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -8,15 +8,12 @@ class StatsController < ApplicationController before_action :authenticate_usuarie! before_action :authorize_stats - INTERVALS = %i[hour day week month year].freeze - RESOURCES = %i[builds space_used build_time].freeze EXTRA_OPTIONS = { builds: {}, space_used: { bytes: true }, build_time: {} }.freeze - # XXX: Permitir a Chart.js inyectar su propio CSS content_security_policy only: :index do |policy| policy.style_src :self, :unsafe_inline @@ -85,7 +82,7 @@ class StatsController < ApplicationController # toma de estadísticas y restando el tiempo que pasó desde ese # momento. def chart_options - time = last_stat.created_at + (1.send(interval)) + time = last_stat.created_at + 1.try(interval) please_return_at = { please_return_at: distance_of_time_in_words(Time.now, time) } @chart_options ||= { @@ -102,14 +99,14 @@ class StatsController < ApplicationController def interval @interval ||= begin i = params[:interval].to_sym - INTERVALS.include?(i) ? i : :day + Stat::INTERVALS.include?(i) ? i : :day end end def resource @resource ||= begin r = params[:resource].to_sym - RESOURCES.include?(r) ? r : :builds + Stat::RESOURCES.include?(r) ? r : :builds end end diff --git a/app/models/stat.rb b/app/models/stat.rb index cf717b05..1e3af9e9 100644 --- a/app/models/stat.rb +++ b/app/models/stat.rb @@ -1,3 +1,6 @@ # frozen_string_literal: true -class Stat < ApplicationRecord; end +class Stat < ApplicationRecord + INTERVALS = %i[hour day week month year].freeze + RESOURCES = %i[builds space_used build_time].freeze +end diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index 101dee1e..992200a4 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -9,7 +9,7 @@ "#{time_ago_in_words @last_stat.created_at}." .mb-3 - - StatsController::INTERVALS.each do |interval| + - Stat::INTERVALS.each do |interval| = link_to t(".#{interval}"), site_stats_path(interval: interval), class: "btn #{'btn-primary active' if params[:interval].to_sym == interval}" .mb-3 @@ -17,7 +17,7 @@ %p.lead= t('.host.description') = line_chart site_stats_host_path(@chart_params), **@chart_options - - StatsController::RESOURCES.each do |resource| + - Stat::RESOURCES.each do |resource| .mb-3 %h2= t(".resources.#{resource}.title") %p.lead= t(".resources.#{resource}.description") From 5ca8e3c923e88bc696f5644f1053a50ddd345e0d Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 15:52:18 -0300 Subject: [PATCH 49/99] usar guards --- app/controllers/stats_controller.rb | 36 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 093fbe93..1dc468bb 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -29,31 +29,31 @@ class StatsController < ApplicationController # Genera un gráfico de visitas por dominio asociado a este sitio def host - if stale? [last_stat, hostnames, interval] - stats = Rollup.where_dimensions(host: hostnames).multi_series('host', interval: interval).tap do |series| - series.each do |serie| - serie[:name] = serie.dig(:dimensions, 'host') - serie[:data].transform_values! do |value| - value * nodes - end + return unless stale? [last_stat, hostnames, interval] + + stats = Rollup.where_dimensions(host: hostnames).multi_series('host', interval: interval).tap do |series| + series.each do |serie| + serie[:name] = serie.dig(:dimensions, 'host') + serie[:data].transform_values! do |value| + value * nodes end end - - render json: stats end + + render json: stats end def resources - if stale? [last_stat, interval, resource] - options = { - interval: interval, - dimensions: { - deploy_id: @site.deploys.where(type: 'DeployLocal').pluck(:id).first - } - } + return unless stale? [last_stat, interval, resource] - render json: Rollup.series(resource, **options) - end + options = { + interval: interval, + dimensions: { + deploy_id: @site.deploys.where(type: 'DeployLocal').pluck(:id).first + } + } + + render json: Rollup.series(resource, **options) end private From 6c485e5e18abf29d3b3cea0de584503417006c6e Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 17:27:45 -0300 Subject: [PATCH 50/99] =?UTF-8?q?obtener=20estad=C3=ADsticas=20de=20cualqu?= =?UTF-8?q?ier=20link?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/stats_controller.rb | 39 +++++++++++++++++++++++++++++ app/policies/site_stat_policy.rb | 4 +++ app/views/stats/index.haml | 18 ++++++++++++- config/locales/en.yml | 6 +++++ config/locales/es.yml | 10 +++++--- config/routes.rb | 1 + 6 files changed, 73 insertions(+), 5 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 1dc468bb..ca834ebd 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -25,6 +25,7 @@ class StatsController < ApplicationController hostnames last_stat chart_options + normalized_urls end # Genera un gráfico de visitas por dominio asociado a este sitio @@ -56,6 +57,22 @@ class StatsController < ApplicationController render json: Rollup.series(resource, **options) end + def uris + return unless stale? [last_stat, hostnames, interval, normalized_urls] + + options = { host: hostnames, uri: normalized_paths } + stats = Rollup.where_dimensions(**options).multi_series('host|uri', interval: interval).tap do |series| + series.each do |serie| + serie[:name] = serie.dig(:dimensions).slice('host', 'uri').values.join.sub('/index.html', '/') + serie[:data].transform_values! do |value| + value * nodes + end + end + end + + render json: stats + end + private def last_stat @@ -72,6 +89,28 @@ class StatsController < ApplicationController @hostnames ||= [@site.hostname, @site.alternative_hostnames].flatten end + # Normalizar las URLs + # + # @return [Array] + def normalized_urls + @normalized_urls ||= params.permit(:urls).try(:[], + :urls)&.split("\n")&.map(&:strip)&.select(&:present?)&.select do |uri| + uri.start_with? 'https://' + end&.map do |u| + # XXX: Eliminar + # @see {https://0xacab.org/sutty/containers/nginx/-/merge_requests/1} + next u unless u.end_with? '/' + + "#{u}index.html" + end&.uniq || [] + end + + def normalized_paths + @normalized_paths ||= normalized_urls.map do |u| + "/#{u.split('/', 4).last}" + end + end + # Opciones por defecto para los gráficos. # # La invitación a volver dentro de X tiempo es para dar un estimado de diff --git a/app/policies/site_stat_policy.rb b/app/policies/site_stat_policy.rb index 6c98c775..cb62b507 100644 --- a/app/policies/site_stat_policy.rb +++ b/app/policies/site_stat_policy.rb @@ -20,4 +20,8 @@ class SiteStatPolicy def resources? index? end + + def uris? + index? + end end diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index 992200a4..1ce61a98 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -10,13 +10,29 @@ .mb-3 - Stat::INTERVALS.each do |interval| - = link_to t(".#{interval}"), site_stats_path(interval: interval), class: "btn #{'btn-primary active' if params[:interval].to_sym == interval}" + = link_to t(".#{interval}"), site_stats_path(interval: interval, urls: params[:urls]), class: "btn #{'btn-primary active' if params[:interval].to_sym == interval}" .mb-3 %h2= t('.host.title', count: @hostnames.size) %p.lead= t('.host.description') = line_chart site_stats_host_path(@chart_params), **@chart_options + .mb-3 + - original_urls = params[:urls]&.split("\n")&.map(&:strip) + - rows = original_urls.size.zero? ? 3 : original_urls.size + %h2= t('.urls.title') + %p.lead= t('.urls.description') + %form + %input{ type: 'hidden', name: 'interval', value: @interval } + .form-group + %label{ for: 'urls' }= t('.urls.label') + %textarea#urls.form-control{ name: 'urls', autocomplete: 'on', required: true, rows: rows, aria_describedby: 'help-urls' }= params[:urls] + %small#help-urls.feedback.form-text.text-muted= t('.urls.help') + .form-group + %button.btn{ type: 'submit' }= t('.urls.submit') + - if @normalized_urls.present? + = line_chart site_stats_uris_path(urls: params[:urls], **@chart_params), **@chart_options + - Stat::RESOURCES.each do |resource| .mb-3 %h2= t(".resources.#{resource}.title") diff --git a/config/locales/en.yml b/config/locales/en.yml index 08313a03..af864e7b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -266,6 +266,12 @@ en: one: 'Site visits' other: 'Visits by site name' description: 'Counts visited pages on your site, grouped by domain names in use.' + urls: + title: 'Visits by URL' + description: 'Counts visits or downloads on any URL.' + label: 'URLs ("links")' + help: 'Copy and paste a single URL per line' + submit: 'Get stats' resources: builds: title: 'Site publication' diff --git a/config/locales/es.yml b/config/locales/es.yml index b1161287..7d0fe2bb 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -271,6 +271,12 @@ es: one: 'Visitas del sitio' other: 'Visitas por nombre del sitio' description: 'Cuenta la cantidad de páginas visitadas en tu sitio, dividida por los nombres de dominio en uso.' + urls: + title: 'Visitas por dirección' + description: 'Cantidad de visitas o descargas por dirección.' + label: 'Direcciones web ("links", vínculos)' + help: 'Copia y pega una dirección por línea.' + submit: 'Obtener estadísticas' resources: builds: title: 'Publicaciones del sitio' @@ -605,7 +611,3 @@ es: edit: 'Editando' usuaries: index: 'Usuaries' - day: 'Día' - week: 'Semana' - month: 'Mes' - year: 'Año' diff --git a/config/routes.rb b/config/routes.rb index b59266fb..1b0f9e0b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -76,6 +76,7 @@ Rails.application.routes.draw do resources :stats, only: [:index] get :'stats/host', to: 'stats#host' + get :'stats/uris', to: 'stats#uris' get :'stats/resources', to: 'stats#resources' end end From 7ab2ec5933613ce23cff5ab17e9141e0cf65c7ac Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 17:28:26 -0300 Subject: [PATCH 51/99] =?UTF-8?q?no=20fallar=20si=20el=20intervalo=20est?= =?UTF-8?q?=C3=A1=20vac=C3=ADo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/stats_controller.rb | 2 +- app/views/stats/index.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index ca834ebd..a5ca04e1 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -137,7 +137,7 @@ class StatsController < ApplicationController # @return [Symbol] def interval @interval ||= begin - i = params[:interval].to_sym + i = params[:interval]&.to_sym Stat::INTERVALS.include?(i) ? i : :day end end diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index 1ce61a98..d437aac1 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -10,7 +10,7 @@ .mb-3 - Stat::INTERVALS.each do |interval| - = link_to t(".#{interval}"), site_stats_path(interval: interval, urls: params[:urls]), class: "btn #{'btn-primary active' if params[:interval].to_sym == interval}" + = link_to t(".#{interval}"), site_stats_path(interval: interval, urls: params[:urls]), class: "btn #{'btn-primary active' if @interval == interval}" .mb-3 %h2= t('.host.title', count: @hostnames.size) From 5dad13bc3c4ff384ae44dc82ea9c9d5435d49832 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 17:28:56 -0300 Subject: [PATCH 52/99] =?UTF-8?q?m=C3=A1s=20espacio=20entre=20los=20gr?= =?UTF-8?q?=C3=A1ficos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/stats/index.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index d437aac1..e4ef5f61 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -8,16 +8,16 @@ %time{ datetime: @last_stat.created_at } "#{time_ago_in_words @last_stat.created_at}." - .mb-3 + .mb-5 - Stat::INTERVALS.each do |interval| = link_to t(".#{interval}"), site_stats_path(interval: interval, urls: params[:urls]), class: "btn #{'btn-primary active' if @interval == interval}" - .mb-3 + .mb-5 %h2= t('.host.title', count: @hostnames.size) %p.lead= t('.host.description') = line_chart site_stats_host_path(@chart_params), **@chart_options - .mb-3 + .mb-5 - original_urls = params[:urls]&.split("\n")&.map(&:strip) - rows = original_urls.size.zero? ? 3 : original_urls.size %h2= t('.urls.title') @@ -34,7 +34,7 @@ = line_chart site_stats_uris_path(urls: params[:urls], **@chart_params), **@chart_options - Stat::RESOURCES.each do |resource| - .mb-3 + .mb-5 %h2= t(".resources.#{resource}.title") %p.lead= t(".resources.#{resource}.description") = line_chart site_stats_resources_path(resource: resource, **@chart_params), **@chart_options.merge(StatsController::EXTRA_OPTIONS[resource]) From fd2e2509d0e5f681c8866cf1c4eecdd51aac2275 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 17:29:09 -0300 Subject: [PATCH 53/99] sin comillas --- app/views/stats/index.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index e4ef5f61..4119f8ae 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -6,7 +6,7 @@ %small = t('.last_update') %time{ datetime: @last_stat.created_at } - "#{time_ago_in_words @last_stat.created_at}." + #{time_ago_in_words @last_stat.created_at}. .mb-5 - Stat::INTERVALS.each do |interval| From 810f71e9c1348825303b990299ed7ad03e767bd7 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 18:25:43 -0300 Subject: [PATCH 54/99] =?UTF-8?q?contar=20por=20qu=C3=A9=20mostramos=20los?= =?UTF-8?q?=20recursos=20usados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/stats/index.haml | 6 +++++- config/locales/en.yml | 6 ++++-- config/locales/es.yml | 10 ++++++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index 4119f8ae..e69c2546 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -33,8 +33,12 @@ - if @normalized_urls.present? = line_chart site_stats_uris_path(urls: params[:urls], **@chart_params), **@chart_options + .mb-5 + %h2= t('.resources.title') + %p.lead= t('.resources.description') + - Stat::RESOURCES.each do |resource| .mb-5 - %h2= t(".resources.#{resource}.title") + %h3= t(".resources.#{resource}.title") %p.lead= t(".resources.#{resource}.description") = line_chart site_stats_resources_path(resource: resource, **@chart_params), **@chart_options.merge(StatsController::EXTRA_OPTIONS[resource]) diff --git a/config/locales/en.yml b/config/locales/en.yml index af864e7b..be327035 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -264,15 +264,17 @@ en: title: zero: 'Site visits' one: 'Site visits' - other: 'Visits by site name' + other: 'Visits by domain name' description: 'Counts visited pages on your site, grouped by domain names in use.' urls: title: 'Visits by URL' description: 'Counts visits or downloads on any URL.' label: 'URLs ("links")' help: 'Copy and paste a single URL per line' - submit: 'Get stats' + submit: 'Update graph' resources: + title: 'Resource usage' + description: "In this section you can find statistics on your site's use of Sutty's shared resources" builds: title: 'Site publication' description: 'Times you published your site.' diff --git a/config/locales/es.yml b/config/locales/es.yml index 7d0fe2bb..774a8cfd 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -269,15 +269,17 @@ es: title: zero: 'Visitas del sitio' one: 'Visitas del sitio' - other: 'Visitas por nombre del sitio' - description: 'Cuenta la cantidad de páginas visitadas en tu sitio, dividida por los nombres de dominio en uso.' + other: 'Visitas agrupadas por nombre de dominio del sitio' + description: 'Cuenta la cantidad de páginas visitadas en tu sitio.' urls: title: 'Visitas por dirección' description: 'Cantidad de visitas o descargas por dirección.' - label: 'Direcciones web ("links", vínculos)' + label: 'Direcciones web (URL, "links", vínculos)' help: 'Copia y pega una dirección por línea.' - submit: 'Obtener estadísticas' + submit: 'Actualizar gráfico' resources: + title: 'Uso de recursos' + description: 'En esta sección podrás acceder a estadísticas del uso de recursos compartidos con otros sitios alojados en Sutty.' builds: title: 'Publicaciones del sitio' description: 'Cantidad de veces que publicaste tu sitio.' From ec775847b9dd8b446ee2947826452c6b5782d3d1 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 18:27:42 -0300 Subject: [PATCH 55/99] sugerir algunas URLs --- app/controllers/stats_controller.rb | 2 +- app/views/stats/index.haml | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index a5ca04e1..3606f37e 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -102,7 +102,7 @@ class StatsController < ApplicationController next u unless u.end_with? '/' "#{u}index.html" - end&.uniq || [] + end&.uniq || [@site.url, @site.urls].flatten.uniq end def normalized_paths diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index e69c2546..fb5c0d52 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -18,15 +18,13 @@ = line_chart site_stats_host_path(@chart_params), **@chart_options .mb-5 - - original_urls = params[:urls]&.split("\n")&.map(&:strip) - - rows = original_urls.size.zero? ? 3 : original_urls.size %h2= t('.urls.title') %p.lead= t('.urls.description') %form %input{ type: 'hidden', name: 'interval', value: @interval } .form-group %label{ for: 'urls' }= t('.urls.label') - %textarea#urls.form-control{ name: 'urls', autocomplete: 'on', required: true, rows: rows, aria_describedby: 'help-urls' }= params[:urls] + %textarea#urls.form-control{ name: 'urls', autocomplete: 'on', required: true, rows: @normalized_urls.size, aria_describedby: 'help-urls' }= @normalized_urls.join("\n") %small#help-urls.feedback.form-text.text-muted= t('.urls.help') .form-group %button.btn{ type: 'submit' }= t('.urls.submit') From 356db8546522ac581254f11d2dcdd4419dfc6595 Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 18:28:38 -0300 Subject: [PATCH 56/99] =?UTF-8?q?empezar=20a=20recolectar=20estad=C3=ADsti?= =?UTF-8?q?cas=20cuando=20se=20inicia=20el=20panel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/application.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/application.rb b/config/application.rb index 7326ae0f..4922b74f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -48,6 +48,11 @@ module Sutty EmailAddress::Config.error_messages translations.transform_keys(&:to_s), locale.to_s end + + # Empezar el recolector de datos en la próxima hora + now = Time.now + next_hour = now.at_beginning_of_hour + 1.hour + 1.minute + StatCollectionJob.perform_in(next_hour - now, once: false) end end end From aa86ead1124a6cfd865956d2a4d5bd8ace4f81de Mon Sep 17 00:00:00 2001 From: f Date: Sat, 9 Oct 2021 18:29:53 -0300 Subject: [PATCH 57/99] ruboyuta --- app/controllers/stats_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 3606f37e..3fe821ac 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -63,7 +63,7 @@ class StatsController < ApplicationController options = { host: hostnames, uri: normalized_paths } stats = Rollup.where_dimensions(**options).multi_series('host|uri', interval: interval).tap do |series| series.each do |serie| - serie[:name] = serie.dig(:dimensions).slice('host', 'uri').values.join.sub('/index.html', '/') + serie[:name] = serie[:dimensions].slice('host', 'uri').values.join.sub('/index.html', '/') serie[:data].transform_values! do |value| value * nodes end From d06edc2f62ce1e2e499684e3446d1a39c90d81f3 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Oct 2021 12:52:31 -0300 Subject: [PATCH 58/99] usar rollups desde git para poder hacer un rollup recursivo --- Gemfile | 2 +- Gemfile.lock | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index b5e8664b..a04353b2 100644 --- a/Gemfile +++ b/Gemfile @@ -59,7 +59,7 @@ gem 'rails-i18n' gem 'rails_warden' gem 'redis', require: %w[redis redis/connection/hiredis] gem 'redis-rails' -gem 'rollups' +gem 'rollups', git: 'https://github.com/ankane/rollup.git', branch: 'master' gem 'rubyzip' gem 'rugged' gem 'concurrent-ruby-ext' diff --git a/Gemfile.lock b/Gemfile.lock index 9d1f512b..c1f6925c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,6 +6,15 @@ GIT rails (>= 3.0) rake (>= 0.8.7) +GIT + remote: https://github.com/ankane/rollup.git + revision: 94ca777d54180c23e96ac4b4285cc9b405ccbd1a + branch: master + specs: + rollups (0.1.2) + activesupport (>= 5.1) + groupdate (>= 5.2) + GIT remote: https://github.com/fauno/email_address revision: 536b51f7071b68a55140c0c1726b4cd401d1c04d @@ -483,9 +492,6 @@ GEM actionpack (>= 5.0) railties (>= 5.0) rexml (3.2.5) - rollups (0.1.2) - activesupport (>= 5.1) - groupdate (>= 5.2) rouge (3.26.0) rubocop (1.18.3) parallel (~> 1.10) @@ -700,7 +706,7 @@ DEPENDENCIES recursero-jekyll-theme redis redis-rails - rollups + rollups! rubocop-rails rubyzip rugged From 245973b5196d478e64d7f3f14ae73fda72cd0e82 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Oct 2021 12:53:42 -0300 Subject: [PATCH 59/99] =?UTF-8?q?no=20fallar=20si=20todav=C3=ADa=20no=20ha?= =?UTF-8?q?y=20stats?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/stats/index.haml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/views/stats/index.haml b/app/views/stats/index.haml index fb5c0d52..bfcf33ef 100644 --- a/app/views/stats/index.haml +++ b/app/views/stats/index.haml @@ -2,11 +2,12 @@ .col %h1= t('.title') %p.lead= t('.help') - %p - %small - = t('.last_update') - %time{ datetime: @last_stat.created_at } - #{time_ago_in_words @last_stat.created_at}. + - if @last_stat + %p + %small + = t('.last_update') + %time{ datetime: @last_stat.created_at } + #{time_ago_in_words @last_stat.created_at}. .mb-5 - Stat::INTERVALS.each do |interval| From cc3535097e4924ed4d1ba87da04be769ba9b1b9e Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Oct 2021 12:57:11 -0300 Subject: [PATCH 60/99] =?UTF-8?q?todav=C3=ADa=20no=20empezar=20la=20recole?= =?UTF-8?q?cci=C3=B3n=20autom=C3=A1tica?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/application.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config/application.rb b/config/application.rb index 4922b74f..7326ae0f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -48,11 +48,6 @@ module Sutty EmailAddress::Config.error_messages translations.transform_keys(&:to_s), locale.to_s end - - # Empezar el recolector de datos en la próxima hora - now = Time.now - next_hour = now.at_beginning_of_hour + 1.hour + 1.minute - StatCollectionJob.perform_in(next_hour - now, once: false) end end end From 1497113f73a8f3cd5cb243b41236445f1667dfdc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Oct 2021 12:58:19 -0300 Subject: [PATCH 61/99] usar menos intervalos las horas y semanas generan demasiados rollups --- app/models/stat.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/stat.rb b/app/models/stat.rb index 1e3af9e9..c986ba4b 100644 --- a/app/models/stat.rb +++ b/app/models/stat.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class Stat < ApplicationRecord - INTERVALS = %i[hour day week month year].freeze + INTERVALS = %i[year month day].freeze RESOURCES = %i[builds space_used build_time].freeze end From 849ee4491c0579133f8134719510f079cff10b66 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Oct 2021 12:58:51 -0300 Subject: [PATCH 62/99] =?UTF-8?q?instalar=20las=20librer=C3=ADas=20en=20pr?= =?UTF-8?q?oducci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 184f7ebb..d520c8f5 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "@rails/ujs": "^6.1.3-1", "@rails/webpacker": "5.2.1", "babel-loader": "^8.2.2", + "chart.js": "^3.5.1", + "chartkick": "^4.0.5", "circular-dependency-plugin": "^5.2.2", "commonmark": "^0.29.0", "fork-awesome": "^1.1.7", @@ -30,8 +32,6 @@ "zepto": "^1.2.0" }, "devDependencies": { - "@types/rails__activestorage": "^6.0.0", - "chart.js": "^3.5.1", - "chartkick": "^4.0.5" + "@types/rails__activestorage": "^6.0.0" } } From 9cf7c6286169ee4f5ee1cac1ea4f3f1ad8106a3d Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Oct 2021 13:08:21 -0300 Subject: [PATCH 63/99] procesar uris a demanda --- app/jobs/uri_collection_job.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 app/jobs/uri_collection_job.rb diff --git a/app/jobs/uri_collection_job.rb b/app/jobs/uri_collection_job.rb new file mode 100644 index 00000000..79b83644 --- /dev/null +++ b/app/jobs/uri_collection_job.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +# Procesar una lista de URIs para una lista de dominios. Esto nos +# permite procesar estadísticas a demanada. +class UriCollectionJob < ApplicationJob + def perform(hostnames:, file:) + uris = File.read(file).split("\n") + + hostnames.each do |hostname| + uris.each do |uri| + break if File.exist? Rails.root.join('tmp', 'uri_collection_job_stop') + + AccessLog.where(host: hostname, uri: uri).completed_requests.non_robots.group(:host, :uri).rollup('host|uri', interval: 'day') + end + end + end +end From 8d38d0d2aedca550e5d8815f6d4b45c70138cfdc Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Oct 2021 13:14:19 -0300 Subject: [PATCH 64/99] =?UTF-8?q?recolecci=C3=B3n=20de=20estad=C3=ADsticas?= =?UTF-8?q?=20con=20mejor=20performance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/stat_collection_job.rb | 42 ++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/app/jobs/stat_collection_job.rb b/app/jobs/stat_collection_job.rb index 6f8470b8..a49a1635 100644 --- a/app/jobs/stat_collection_job.rb +++ b/app/jobs/stat_collection_job.rb @@ -21,14 +21,20 @@ class StatCollectionJob < ApplicationJob COLUMNS = %i[uri].freeze def perform(once: false) - Stat::INTERVALS.each do |interval| - options = { interval: interval } + Site.find_each do |site| + hostnames = [site.hostname, site.alternative_hostnames].flatten + + # Usamos el primero porque luego podemos hacer un rollup recursivo + options = { interval: Stat::INTERVALS.first } # Visitas por hostname - AccessLog.completed_requests.non_robots.pages.group(:host).rollup('host', **options) + hostnames.each do |hostname| + AccessLog.where(host: hostname).completed_requests.non_robots.pages.group(:host).rollup('host', **options) - combined_columns(**options) - stats_by_site(**options) + combined_columns(hostname, **options) + end + + stats_by_site(site, **options) end # Registrar que se hicieron todas las recolecciones @@ -40,9 +46,15 @@ class StatCollectionJob < ApplicationJob private # Combinación de columnas - def combined_columns(**options) + def combined_columns(hostname, **options) + where = { host: hostname } + COLUMNS.each do |column| - AccessLog.completed_requests.non_robots.group(:host, column).rollup("host|#{column}", **options) + AccessLog.where(host: hostname).pluck(Arel.sql("distinct #{column}")).each do |value| + where[column] = value + + AccessLog.where(**where).completed_requests.non_robots.group(:host, column).rollup("host|#{column}", **options) + end end end @@ -50,17 +62,15 @@ class StatCollectionJob < ApplicationJob # # XXX: En realidad se agrupan por el deploy_id, que siempre será el # del DeployLocal. - def stats_by_site(**options) - Site.find_each do |site| - site.build_stats.jekyll.group(:deploy_id).rollup('builds', **options) + def stats_by_site(site, **options) + site.build_stats.jekyll.group(:deploy_id).rollup('builds', **options) - site.build_stats.jekyll.group(:deploy_id).rollup('space_used', **options) do |rollup| - rollup.average(:bytes) - end + site.build_stats.jekyll.group(:deploy_id).rollup('space_used', **options) do |rollup| + rollup.average(:bytes) + end - site.build_stats.jekyll.group(:deploy_id).rollup('build_time', **options) do |rollup| - rollup.average(:seconds) - end + site.build_stats.jekyll.group(:deploy_id).rollup('build_time', **options) do |rollup| + rollup.average(:seconds) end end end From 7e1696204183e73afa307e27d77ecbfd87f7c5b8 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 20 Oct 2021 17:36:30 -0300 Subject: [PATCH 65/99] no fallar si no hay stat closes #3228 --- app/controllers/stats_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index 3fe821ac..b9b93e9f 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -121,7 +121,7 @@ class StatsController < ApplicationController # toma de estadísticas y restando el tiempo que pasó desde ese # momento. def chart_options - time = last_stat.created_at + 1.try(interval) + time = (last_stat&.created_at || Time.now) + 1.try(interval) please_return_at = { please_return_at: distance_of_time_in_words(Time.now, time) } @chart_options ||= { From 090b6305251ecb068620eb0558659c4551d97d52 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 10:47:32 -0300 Subject: [PATCH 66/99] =?UTF-8?q?la=20l=C3=B3gica=20estaba=20invertida=20y?= =?UTF-8?q?=20los=20valores=20nunca=20llegaban=20al=20archivo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_boolean.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_boolean.rb b/app/models/metadata_boolean.rb index 53a763fd..ed27ea92 100644 --- a/app/models/metadata_boolean.rb +++ b/app/models/metadata_boolean.rb @@ -33,7 +33,7 @@ class MetadataBoolean < MetadataTemplate # Siempre guardar el valor de este campo a menos que sea nulo def empty? - !value.nil? + value.nil? end private From d67d43ff1ea19f5acfb31d615cd4e0db97f98b5f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 10:48:34 -0300 Subject: [PATCH 67/99] =?UTF-8?q?hacer=20m=C3=A1s=20claro=20el=20c=C3=B3di?= =?UTF-8?q?go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/metadata_boolean.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/models/metadata_boolean.rb b/app/models/metadata_boolean.rb index ed27ea92..90c002a7 100644 --- a/app/models/metadata_boolean.rb +++ b/app/models/metadata_boolean.rb @@ -25,10 +25,14 @@ class MetadataBoolean < MetadataTemplate # * false # * true def value - return document.data.fetch(name.to_s, default_value) if self[:value].nil? - return self[:value] unless self[:value].is_a? String - - self[:value] = true_values.include? self[:value] + case self[:value] + when NilClass + document.data.fetch(name.to_s, default_value) + when String + true_values.include? self[:value] + else + self[:value] + end end # Siempre guardar el valor de este campo a menos que sea nulo From 08e0a0ca9d7fe9ca76332e5ad895f155c7103803 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 10:49:02 -0300 Subject: [PATCH 68/99] traducir correctamente --- config/locales/en.yml | 4 ++-- config/locales/es.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/locales/en.yml b/config/locales/en.yml index 5f224ab6..43ab0d0a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -19,8 +19,8 @@ en: remember_me: 'Keeps session open for %{remember_for}' actions: sr-help: "After this form you'll find links to recover your account and other actions." - _true: Yes - _false: No + _true: 'Yes' + _false: 'No' svg: sutty: title: Sutty diff --git a/config/locales/es.yml b/config/locales/es.yml index ebf4da62..880b9e7c 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -19,8 +19,8 @@ es: remember_me: 'Mantiene la sesión abierta por %{remember_for}' actions: sr-help: 'Después del formulario encontrarás vínculos para recuperar tu cuenta, entre otras acciones.' - _true: Sí - _false: No + _true: 'Sí' + _false: 'No' svg: sutty: title: Sutty From 6349fd7b407a3f4c260ba061d8cbaf4bf63743cd Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 13:23:35 -0300 Subject: [PATCH 69/99] los url helpers necesitan hashes o params y params.to_h devuelve un hashwithindifferentaccess, lo que rompia las urls con locale --- 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 05ae2736..6b69fd6a 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -154,7 +154,7 @@ class PostsController < ApplicationController # # @return [Hash] def filter_params - @filter_params ||= params.permit(:q, :category, :layout, :page).to_h.select { |_, v| v.present? } + @filter_params ||= params.permit(:q, :category, :layout, :page).to_hash.select { |_, v| v.present? } end def site From 3335d0d9eb3c75f20b48c427c2dd7a59b52c22dd Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 13:25:05 -0300 Subject: [PATCH 70/99] usar una guard como sugiere rubocop --- app/controllers/posts_controller.rb | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 6b69fd6a..9d0ff8a8 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -22,21 +22,21 @@ class PostsController < ApplicationController # XXX: Cada vez que cambiamos un Post tocamos el sitio con lo que es # más simple saber si hubo cambios. - if stale?([current_usuarie, site, filter_params]) - # Todos los artículos de este sitio para el idioma actual - @posts = site.indexed_posts.where(locale: locale).page(filter_params.delete(:page)) - # De este tipo - @posts = @posts.where(layout: filter_params[:layout]) if filter_params[:layout] - # Que estén dentro de la categoría - @posts = @posts.in_category(filter_params[:category]) if filter_params[:category] - # Aplicar los parámetros de búsqueda - @posts = @posts.search(locale, filter_params[:q]) if filter_params[:q].present? - # A los que este usuarie tiene acceso - @posts = PostPolicy::Scope.new(current_usuarie, @posts).resolve + return unless stale?([current_usuarie, site, filter_params]) - # Filtrar los posts que les invitades no pueden ver - @usuarie = site.usuarie? current_usuarie - end + # Todos los artículos de este sitio para el idioma actual + @posts = site.indexed_posts.where(locale: locale).page(filter_params.delete(:page)) + # De este tipo + @posts = @posts.where(layout: filter_params[:layout]) if filter_params[:layout] + # Que estén dentro de la categoría + @posts = @posts.in_category(filter_params[:category]) if filter_params[:category] + # Aplicar los parámetros de búsqueda + @posts = @posts.search(locale, filter_params[:q]) if filter_params[:q].present? + # A los que este usuarie tiene acceso + @posts = PostPolicy::Scope.new(current_usuarie, @posts).resolve + + # Filtrar los posts que les invitades no pueden ver + @usuarie = site.usuarie? current_usuarie end def show From e3d2213afc0f97852df6ee40c42d70f47596f34f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 13:44:34 -0300 Subject: [PATCH 71/99] especificar el idioma de un post nuevo --- 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 9d0ff8a8..9820d71d 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -54,7 +54,7 @@ class PostsController < ApplicationController def new authorize Post - @post = site.posts.build(lang: locale, layout: params[:layout]) + @post = site.posts(lang: locale).build(layout: params[:layout]) breadcrumb I18n.t('loaf.breadcrumbs.posts.new', layout: @post.layout.humanized_name.downcase), '' end From 883182ffe2413b76c9f9756ddc8ad29cfca0c9ba Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 13:45:34 -0300 Subject: [PATCH 72/99] =?UTF-8?q?rutas=20m=C3=A1s=20espec=C3=ADficas?= 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 15ee4150..5e172cda 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)' do + scope '/(:locale)', constraint: /[a-z]{2}/ do post :'posts/reorder', to: 'posts#reorder' resources :posts do get 'p/:page', action: :index, on: :collection From 69ef571bdb4a4768c37865907fb07629fc017487 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 14:25:05 -0300 Subject: [PATCH 73/99] garantizar que sea una hash de simbolos --- app/controllers/posts_controller.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 9820d71d..f3bc8aac 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -154,7 +154,9 @@ class PostsController < ApplicationController # # @return [Hash] def filter_params - @filter_params ||= params.permit(:q, :category, :layout, :page).to_hash.select { |_, v| v.present? } + @filter_params ||= params.permit(:q, :category, :layout, :page).to_hash.select do |_, v| + v.present? + end.transform_keys(&:to_sym) end def site From 9c4a0a86f3eeec8f578e3872096896a710e01632 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 14:40:55 -0300 Subject: [PATCH 74/99] deshabilitar el paginado temporalmente no permite mover posts entre paginas! --- app/controllers/posts_controller.rb | 4 ++-- app/views/posts/index.haml | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index f3bc8aac..dbdd4d0a 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -25,7 +25,7 @@ class PostsController < ApplicationController return unless stale?([current_usuarie, site, filter_params]) # Todos los artículos de este sitio para el idioma actual - @posts = site.indexed_posts.where(locale: locale).page(filter_params.delete(:page)) + @posts = site.indexed_posts.where(locale: locale) # De este tipo @posts = @posts.where(layout: filter_params[:layout]) if filter_params[:layout] # Que estén dentro de la categoría @@ -154,7 +154,7 @@ class PostsController < ApplicationController # # @return [Hash] def filter_params - @filter_params ||= params.permit(:q, :category, :layout, :page).to_hash.select do |_, v| + @filter_params ||= params.permit(:q, :category, :layout).to_hash.select do |_, v| v.present? end.transform_keys(&:to_sym) end diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 90e30966..5f613e3a 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -84,8 +84,6 @@ %button.btn{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom') %div - = link_to_prev_page @posts, t('posts.prev'), class: 'btn' - = link_to_next_page @posts, t('posts.next'), class: 'btn' %tbody - dir = t("locales.#{@locale}.dir") - size = @posts.size From 4456deff9c8eef185f370a57dac519ad0d8801b6 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 15:02:07 -0300 Subject: [PATCH 75/99] =?UTF-8?q?usar=20la=20traducci=C3=B3n=20del=20idiom?= =?UTF-8?q?a=20que=20viene=20del=20sitio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/posts/index.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index 5f613e3a..ad07b9dc 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -51,7 +51,7 @@ - if @site.locales.size > 1 %nav#locales - @site.locales.each do |locale| - = link_to t("locales.#{locale}.name"), site_posts_path(@site, **@filter_params.merge(locale: locale)), + = link_to @site.data.dig(locale.to_s, 'locale') || locale, site_posts_path(@site, **@filter_params.merge(locale: locale)), class: "mr-2 mt-2 mb-2 #{locale == @locale ? 'active font-weight-bold' : ''}" .pl-2-plus - @filter_params.each do |param, value| From 7227ecfe2a1bfb99c19e5af8998b2253c323f348 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 20:53:25 -0300 Subject: [PATCH 76/99] solo instalar las gemas de assets en desarrollo --- .env.example | 1 + Gemfile | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.env.example b/.env.example index a62e2b0a..f79ff3a4 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,4 @@ +RAILS_GROUPS=assets DELEGATE=athshe.sutty.nl HAINISH=../haini.sh/haini.sh DATABASE= diff --git a/Gemfile b/Gemfile index db06827d..01167fa1 100644 --- a/Gemfile +++ b/Gemfile @@ -11,13 +11,16 @@ gem 'dotenv-rails', require: 'dotenv/rails-now' gem 'rails', '~> 6' # Use Puma as the app server gem 'puma' -# See https://github.com/rails/execjs#readme for more supported runtimes -# gem 'therubyracer', platforms: :ruby -# Use SCSS for stylesheets -gem 'sassc-rails' -# Use Uglifier as compressor for JavaScript assets -gem 'uglifier', '>= 1.3.0' -gem 'bootstrap', '~> 4' + +# Solo incluir las gemas cuando estemos en desarrollo o compilando los +# assets. No es necesario instalarlas en producción. +# +# XXX: Supuestamente Rails ya soporta RAILS_GROUPS, pero Bundler no. +if ENV['RAILS_GROUPS']&.include? 'assets' + gem 'sassc-rails' + gem 'uglifier', '>= 1.3.0' + gem 'bootstrap', '~> 4' +end # Turbolinks makes navigating your web application faster. Read more: # https://github.com/turbolinks/turbolinks From fd784919df49d8703713b0f741521079de37fdc4 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 20:54:12 -0300 Subject: [PATCH 77/99] rails ya corre yarn antes de compilar --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 36139d7a..5aca94f8 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ help: always ## Ayuda @echo -e "\nArgumentos:\n" @grep -E "^[a-z\-]+ \?=.*##" Makefile | sed -re "s/(.*) \?=.*##(.*)/\1;\2/" | column -s ";" -t | sed -re "s/^([^ ]+) /\x1B[38;5;197m\1\x1B[0m/" -assets: node_modules public/packs/manifest.json.br ## Compilar los assets +assets: public/packs/manifest.json.br ## Compilar los assets test: always ## Ejecutar los tests $(MAKE) rake args="test RAILS_ENV=test $(args)" From 084bf8547f0202d5409d1c36a0cab71a40e7322f Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 20:54:50 -0300 Subject: [PATCH 78/99] ya no es necesario hacer limpieza en docker --- Dockerfile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0b3253b4..07322903 100644 --- a/Dockerfile +++ b/Dockerfile @@ -60,10 +60,6 @@ RUN mv ../sutty/.bundle ./.bundle # Instalar secretos COPY --chown=app:root ./config/credentials.yml.enc ./config/ -# Eliminar la necesidad de un runtime JS en producción, porque los -# assets ya están pre-compilados. -RUN sed -re "/(sassc|uglifier|bootstrap|coffee-rails)/d" -i Gemfile -RUN bundle clean RUN rm -rf ./node_modules ./tmp/cache ./.git ./test ./doc # Eliminar archivos innecesarios USER root From 570761fab5efe47f0bbdf389550424c726dacc12 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 21 Oct 2021 20:55:40 -0300 Subject: [PATCH 79/99] =?UTF-8?q?actualizar=20contenedor=20con=20una=20ver?= =?UTF-8?q?si=C3=B3n=20espec=C3=ADfica=20de=20bundler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 07322903..ee6ba871 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # el mismo repositorio de trabajo. Cuando tengamos CI/CD algunas cosas # como el tarball van a tener que cambiar porque ya vamos a haber hecho # un clone/pull limpio. -FROM alpine:3.13.5 AS build +FROM alpine:3.13.6 AS build MAINTAINER "f " ARG RAILS_MASTER_KEY @@ -14,10 +14,10 @@ ENV SECRET_KEY_BASE solo_es_necesaria_para_correr_rake ENV RAILS_ENV production ENV RAILS_MASTER_KEY=$RAILS_MASTER_KEY -RUN apk add --no-cache libxslt libxml2 tzdata ruby ruby-bundler ruby-json ruby-bigdecimal ruby-rake +RUN apk add --no-cache libxslt libxml2 tzdata ruby ruby-json ruby-bigdecimal ruby-rake RUN apk add --no-cache postgresql-libs git yarn brotli libssh2 python3 -RUN test "2.7.3" = `ruby -e 'puts RUBY_VERSION'` +RUN test "2.7.4" = `ruby -e 'puts RUBY_VERSION'` # https://github.com/rubygems/rubygems/issues/2918 # https://gitlab.alpinelinux.org/alpine/aports/issues/10808 @@ -29,7 +29,7 @@ RUN cd /usr/lib/ruby/2.7.0 && patch -Np 0 -i /tmp/rubygems-platform-musl.patch RUN addgroup -g 82 -S www-data RUN adduser -s /bin/sh -G www-data -h /home/app -D app RUN install -dm750 -o app -g www-data /home/app/sutty -RUN gem install --no-document bundler +RUN gem install --no-document bundler:2.1.4 # Empezamos con la usuaria app USER app @@ -39,7 +39,8 @@ WORKDIR /home/app/sutty # Copiamos solo el Gemfile para poder instalar las gemas necesarias COPY --chown=app:www-data ./Gemfile . COPY --chown=app:www-data ./Gemfile.lock . -RUN bundle config set no-cache 'true' +RUN bundle config set no-cache true +RUN bundle config set specific_platform true RUN bundle install --path=./vendor --without='test development' # Vaciar la caché RUN rm vendor/ruby/2.7.0/cache/*.gem @@ -67,7 +68,7 @@ RUN apk add --no-cache findutils RUN find /home/app/checkout/vendor/ruby/2.7.0 -maxdepth 3 -type d -name test -o -name spec -o -name rubocop | xargs -r rm -rf # Contenedor final -FROM sutty/monit:latest +FROM registry.nulo.in/sutty/monit:3.13.6 ENV RAILS_ENV production # Pandoc @@ -75,13 +76,13 @@ RUN echo 'http://dl-cdn.alpinelinux.org/alpine/edge/testing' >> /etc/apk/reposit # Instalar las dependencias, separamos la librería de base de datos para # poder reutilizar este primer paso desde otros contenedores -RUN apk add --no-cache libxslt libxml2 tzdata ruby ruby-bundler ruby-json ruby-bigdecimal ruby-rake ruby-irb +RUN apk add --no-cache libxslt libxml2 tzdata ruby ruby-json ruby-bigdecimal ruby-rake ruby-irb ruby-io-console ruby-etc RUN apk add --no-cache postgresql-libs libssh2 file rsync git jpegoptim vips RUN apk add --no-cache ffmpeg imagemagick pandoc tectonic oxipng jemalloc RUN apk add --no-cache git-lfs openssh-client patch # Chequear que la versión de ruby sea la correcta -RUN test "2.7.3" = `ruby -e 'puts RUBY_VERSION'` +RUN test "2.7.4" = `ruby -e 'puts RUBY_VERSION'` # https://github.com/rubygems/rubygems/issues/2918 # https://gitlab.alpinelinux.org/alpine/aports/issues/10808 @@ -93,7 +94,7 @@ RUN apk add --no-cache patch && cd /usr/lib/ruby/2.7.0 && patch -Np 0 -i /tmp/ru # principal RUN apk add --no-cache yarn # Instalar foreman para poder correr los servicios -RUN gem install --no-document --no-user-install bundler foreman +RUN gem install --no-document --no-user-install bundler:2.1.4 foreman # Agregar el grupo del servidor web y la usuaria RUN addgroup -g 82 -S www-data From 8bebe155f4bd355087fb6685b47f55709a2df48b Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Oct 2021 17:06:34 -0300 Subject: [PATCH 80/99] no hace falta subir los parches dos veces --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index 36139d7a..592592bd 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,6 @@ ota-js: assets ## Actualizar Javascript en el nodo delegado ota: ## Actualizar Rails en el nodo delegado umask 022; git format-patch $(commit) - scp ./0*.patch $(delegate):/tmp/ ssh $(delegate) mkdir -p /tmp/patches-$(commit)/ scp ./0*.patch $(delegate):/tmp/patches-$(commit)/ scp ./ota.sh $(delegate):/tmp/ From 84e543ac078abfd77ecb8662a791ae67ba1eda01 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Oct 2021 17:13:26 -0300 Subject: [PATCH 81/99] ignorar los cambios de licencia en idiomas no soportados --- 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 389549c3..5e2fc706 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -122,6 +122,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # la búsqueda. def change_licencias site.locales.each do |locale| + next unless I18n.available_locales.include? locale + Mobility.with_locale(locale) do permalink = "#{I18n.t('activerecord.models.licencia').downcase}/" post = site.posts(lang: locale).find_by(permalink: permalink) From 21bf478af700b79806e133e7c698fd3ccbdf8c0e Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Oct 2021 17:36:00 -0300 Subject: [PATCH 82/99] actualizacion de cuidados --- Gemfile.lock | 65 ++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d8dd4fb4..67698998 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -93,9 +93,9 @@ GEM execjs (~> 2) bcrypt (3.1.16-x86_64-linux-musl) bcrypt_pbkdf (1.1.0-x86_64-linux-musl) - benchmark-ips (2.9.1) + benchmark-ips (2.9.2) bindex (0.8.1-x86_64-linux-musl) - blazer (2.4.3) + blazer (2.4.7) activerecord (>= 5) chartkick (>= 3.2) railties (>= 5) @@ -114,7 +114,7 @@ GEM rack-test (>= 0.5.4) xpath (>= 2.0, < 4.0) chartkick (4.0.5) - childprocess (3.0.0) + childprocess (4.1.0) coderay (1.1.3) colorator (1.1.0) commonmarker (0.21.2-x86_64-linux-musl) @@ -129,7 +129,7 @@ GEM activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - dead_end (1.1.7) + dead_end (2.0.1) derailed_benchmarks (2.1.1) benchmark-ips (~> 2) dead_end @@ -157,7 +157,7 @@ GEM dotenv-rails (2.7.6) dotenv (= 2.7.6) railties (>= 3.2) - down (5.2.3) + down (5.2.4) addressable (~> 2.8) ed25519 (1.2.4-x86_64-linux-musl) editorial-autogestiva-jekyll-theme (0.3.4) @@ -240,7 +240,7 @@ GEM concurrent-ruby (~> 1.0) icalendar (2.7.1) ice_cube (~> 0.16) - ice_cube (0.16.3) + ice_cube (0.16.4) image_processing (1.12.1) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) @@ -249,7 +249,7 @@ GEM nokogiri (>= 1.6) jbuilder (2.11.2) activesupport (>= 5.0.0) - jekyll (4.2.0) + jekyll (4.2.1) addressable (~> 2.4) colorator (~> 1.0) em-websocket (~> 0.5) @@ -306,7 +306,7 @@ GEM jekyll (~> 4) jekyll-watch (2.2.1) listen (~> 3.0) - jekyll-write-and-commit-changes (0.2.0) + jekyll-write-and-commit-changes (0.2.1) jekyll (~> 4) rugged (~> 1) kaminari (1.2.1) @@ -336,7 +336,7 @@ GEM ruby_dep (~> 1.2) loaf (0.10.0) railties (>= 3.2) - lockbox (0.6.5) + lockbox (0.6.6) lograge (0.11.2) actionpack (>= 4) activesupport (>= 4) @@ -347,7 +347,7 @@ GEM nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (1.0.1) + marcel (1.0.2) memory_profiler (1.0.0) mercenary (0.4.0) method_source (1.0.0) @@ -356,25 +356,25 @@ GEM mime-types-data (3.2021.0901) mini_histogram (0.3.1) mini_magick (4.11.0) - mini_mime (1.1.1) - mini_portile2 (2.5.3) + mini_mime (1.1.2) + mini_portile2 (2.6.1) minima (2.5.1) jekyll (>= 3.5, < 5.0) jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) minitest (5.14.4) - mobility (1.1.3) + mobility (1.2.2) i18n (>= 0.6.10, < 2) request_store (~> 1.0) multi_xml (0.6.0) net-ssh (6.1.0) - netaddr (2.0.4) + netaddr (2.0.5) nio4r (2.5.8-x86_64-linux-musl) - nokogiri (1.11.7-x86_64-linux-musl) - mini_portile2 (~> 2.5.0) + nokogiri (1.12.5-x86_64-linux-musl) + mini_portile2 (~> 2.6.1) racc (~> 1.4) orm_adapter (0.5.0) - parallel (1.20.1) + parallel (1.21.0) parser (3.0.2.0) ast (~> 2.4.1) pathutil (0.16.2) @@ -390,11 +390,11 @@ GEM coderay (~> 1.1) method_source (~> 1.0) public_suffix (4.0.6) - puma (5.4.0-x86_64-linux-musl) + puma (5.5.2-x86_64-linux-musl) nio4r (~> 2.0) pundit (2.1.1) activesupport (>= 3.0.0) - racc (1.5.2-x86_64-linux-musl) + racc (1.6.0-x86_64-linux-musl) rack (2.2.3) rack-cors (1.1.1) rack (>= 2.0.0) @@ -469,7 +469,7 @@ GEM jekyll-unique-urls (~> 0.1) sutty-archives (~> 2.2) sutty-liquid (~> 0) - redis (4.4.0) + redis (4.5.1) redis-actionpack (5.2.0) actionpack (>= 5, < 7) redis-rack (>= 2.1.0, < 3) @@ -493,19 +493,19 @@ GEM actionpack (>= 5.0) railties (>= 5.0) rexml (3.2.5) - rouge (3.26.0) - rubocop (1.20.0) + rouge (3.26.1) + rubocop (1.22.2) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml - rubocop-ast (>= 1.9.1, < 2.0) + rubocop-ast (>= 1.12.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.11.0) + rubocop-ast (1.12.0) parser (>= 3.0.1.1) - rubocop-rails (2.12.2) + rubocop-rails (2.12.4) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.7.0, < 2.0) @@ -513,7 +513,7 @@ GEM i18n ruby-filemagic (0.7.2-x86_64-linux-musl) ruby-progressbar (1.11.0) - ruby-statistics (2.1.3) + ruby-statistics (3.0.0) ruby-vips (2.1.3) ffi (~> 1.12) ruby2ruby (2.4.4) @@ -535,8 +535,9 @@ GEM sprockets (> 3.0) sprockets-rails tilt - selenium-webdriver (3.142.7) - childprocess (>= 0.5, < 4.0) + selenium-webdriver (4.0.3) + childprocess (>= 0.5, < 5.0) + rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2) semantic_range (3.0.0) sexp_processor (4.15.3) @@ -612,8 +613,8 @@ GEM execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext - unf_ext (0.0.7.7-x86_64-linux-musl) - unicode-display_width (1.7.0) + unf_ext (0.0.8-x86_64-linux-musl) + unicode-display_width (1.8.0) validates_hostname (1.0.11) activerecord (>= 3.0) activesupport (>= 3.0) @@ -624,7 +625,7 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webpacker (5.4.2) + webpacker (5.4.3) activesupport (>= 5.2) rack-proxy (>= 0.6.1) railties (>= 5.2) @@ -635,7 +636,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.4.2) + zeitwerk (2.5.1) PLATFORMS ruby From ab004fae700db1f3b72cd1a44ec403fdabb8c452 Mon Sep 17 00:00:00 2001 From: f Date: Fri, 22 Oct 2021 18:21:47 -0300 Subject: [PATCH 83/99] decodificar las urls para poder buscarlas en el log --- app/controllers/stats_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb index b9b93e9f..44073c1f 100644 --- a/app/controllers/stats_controller.rb +++ b/app/controllers/stats_controller.rb @@ -108,6 +108,8 @@ class StatsController < ApplicationController def normalized_paths @normalized_paths ||= normalized_urls.map do |u| "/#{u.split('/', 4).last}" + end.map do |u| + URI.decode_www_form_component u end end From c84462c4a8342ac9331718335c529d636ebb9298 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Oct 2021 11:33:15 -0300 Subject: [PATCH 84/99] =?UTF-8?q?recolectar=20estad=C3=ADsticas=20usando?= =?UTF-8?q?=20menos=20recursos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/jobs/periodic_job.rb | 55 +++++++++++++++++ app/jobs/stat_collection_job.rb | 93 +++++++++++++---------------- app/jobs/uri_collection_job.rb | 101 ++++++++++++++++++++++++++++++-- app/models/site.rb | 1 + app/models/stat.rb | 6 +- 5 files changed, 198 insertions(+), 58 deletions(-) create mode 100644 app/jobs/periodic_job.rb diff --git a/app/jobs/periodic_job.rb b/app/jobs/periodic_job.rb new file mode 100644 index 00000000..8d9453a3 --- /dev/null +++ b/app/jobs/periodic_job.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +# Una tarea que se corre periódicamente +class PeriodicJob < ApplicationJob + class RunAgainException < StandardError; end + + STARTING_INTERVAL = Stat::INTERVALS.first + + # Tener el sitio a mano + attr_reader :site + + # Descartar y notificar si pasó algo más. + # + # XXX: En realidad deberíamos seguir reintentando? + discard_on(StandardError) do |_, error| + ExceptionNotifier.notify_exception(error) + end + + # Correr indefinidamente una vez por hora. + # + # XXX: El orden importa, si el descarte viene después, nunca se va a + # reintentar. + retry_on(PeriodicJob::RunAgainException, wait: 1.try(STARTING_INTERVAL), attempts: Float::INFINITY, jitter: 0) + + private + + # Las clases que implementen esta tienen que usar este método al + # terminar. + def run_again! + raise PeriodicJob::RunAgainException, 'Reintentando' + end + + # El intervalo de inicio + # + # @return [Symbol] + def starting_interval + STARTING_INTERVAL + end + + # La última recolección de estadísticas o empezar desde el principio + # de los tiempos. + # + # @return [Stat] + def last_stat + @last_stat ||= site.stats.where(name: stat_name).last || + site.stats.build(created_at: Time.new(1970, 1, 1)) + end + + # Devuelve el comienzo del intervalo + # + # @return [Time] + def beginning_of_interval + @beginning_of_interval ||= last_stat.created_at.try(:"beginning_of_#{starting_interval}") + end +end diff --git a/app/jobs/stat_collection_job.rb b/app/jobs/stat_collection_job.rb index a49a1635..2aa8d702 100644 --- a/app/jobs/stat_collection_job.rb +++ b/app/jobs/stat_collection_job.rb @@ -3,74 +3,65 @@ # Genera resúmenes de información para poder mostrar estadísticas y se # corre regularmente a sí misma. class StatCollectionJob < ApplicationJob - class CrontabException < StandardError; end + STAT_NAME = 'stat_collection_job' - # Descartar y notificar si pasó algo más. - # - # XXX: En realidad deberíamos seguir reintentando? - discard_on(Exception) do |_, error| - ExceptionNotifier.notify_exception error - end + def perform(site_id:, once: true) + @site = Site.find site_id - # Correr indefinidamente una vez por hora. - # - # XXX: El orden importa, si el descarte viene después, nunca se va a - # reintentar. - retry_on(StatCollectionJob::CrontabException, wait: 1.hour, attempts: Float::INFINITY, jitter: 0) + scope.rollup('builds', **options) - COLUMNS = %i[uri].freeze + scope.rollup('space_used', **options) do |rollup| + rollup.average(:bytes) + end - def perform(once: false) - Site.find_each do |site| - hostnames = [site.hostname, site.alternative_hostnames].flatten + scope.rollup('build_time', **options) do |rollup| + rollup.average(:seconds) + end - # Usamos el primero porque luego podemos hacer un rollup recursivo - options = { interval: Stat::INTERVALS.first } + # XXX: Es correcto promediar promedios? + Stat::INTERVALS.reduce do |previous, current| + rollup(name: 'builds', interval_previous: previous, interval: current) + rollup(name: 'space_used', interval_previous: previous, interval: current, operation: :average) + rollup(name: 'build_time', interval_previous: previous, interval: current, operation: :average) - # Visitas por hostname - hostnames.each do |hostname| - AccessLog.where(host: hostname).completed_requests.non_robots.pages.group(:host).rollup('host', **options) - - combined_columns(hostname, **options) - end - - stats_by_site(site, **options) + current end # Registrar que se hicieron todas las recolecciones - Stat.create! + site.stats.create! name: STAT_NAME - raise CrontabException unless once + run_again! unless once end private - # Combinación de columnas - def combined_columns(hostname, **options) - where = { host: hostname } - - COLUMNS.each do |column| - AccessLog.where(host: hostname).pluck(Arel.sql("distinct #{column}")).each do |value| - where[column] = value - - AccessLog.where(**where).completed_requests.non_robots.group(:host, column).rollup("host|#{column}", **options) - end - end + # Genera un rollup recursivo en base al período anterior y aplica una + # operación. + # + # @return [NilClass] + def rollup(name:, interval_previous:, interval:, operation: :sum) + Rollup.where(name: name, interval: interval_previous) + .where_dimensions(site_id: site.id) + .group("dimensions->'site_id'") + .rollup(name, interval: interval, update: true) do |rollup| + rollup.try(:operation, :value) + end end - # Uso de recursos por cada sitio. + # Los registros a procesar # - # XXX: En realidad se agrupan por el deploy_id, que siempre será el - # del DeployLocal. - def stats_by_site(site, **options) - site.build_stats.jekyll.group(:deploy_id).rollup('builds', **options) + # @return [ActiveRecord::Relation] + def scope + @scope ||= site.build_stats + .jekyll + .where('created_at => ?', beginning_of_interval) + .group(:site_id) + end - site.build_stats.jekyll.group(:deploy_id).rollup('space_used', **options) do |rollup| - rollup.average(:bytes) - end - - site.build_stats.jekyll.group(:deploy_id).rollup('build_time', **options) do |rollup| - rollup.average(:seconds) - end + # Las opciones por defecto + # + # @return [Hash] + def options + @options ||= { interval: starting_interval, update: true } end end diff --git a/app/jobs/uri_collection_job.rb b/app/jobs/uri_collection_job.rb index 79b83644..9ec333cd 100644 --- a/app/jobs/uri_collection_job.rb +++ b/app/jobs/uri_collection_job.rb @@ -1,16 +1,105 @@ # frozen_string_literal: true # Procesar una lista de URIs para una lista de dominios. Esto nos -# permite procesar estadísticas a demanada. -class UriCollectionJob < ApplicationJob - def perform(hostnames:, file:) - uris = File.read(file).split("\n") +# permite procesar estadísticas a demanda. +# +# Hay varias cosas acá que van a convertirse en métodos propios, como la +# detección de URIs de un sitio (aunque la versión actual detecta todas +# las páginas y no solo las de posts como tenemos planeado, hay que +# resolver eso). +# +# Los hostnames de un sitio van a poder obtenerse a partir de +# Site#hostnames con la garantía de que son únicos. +class UriCollectionJob < PeriodicJob + # Ignoramos imágenes porque suelen ser demasiadas y no aportan a las + # estadísticas. + IMAGES = %w[.png .jpg .jpeg .gif .webp].freeze + STAT_NAME = 'uri_collection_job' + + def perform(site_id:, once: true) + @site = Site.find site_id hostnames.each do |hostname| uris.each do |uri| - break if File.exist? Rails.root.join('tmp', 'uri_collection_job_stop') + return if File.exist? Rails.root.join('tmp', 'uri_collection_job_stop') - AccessLog.where(host: hostname, uri: uri).completed_requests.non_robots.group(:host, :uri).rollup('host|uri', interval: 'day') + AccessLog.where(host: hostname, uri: uri) + .where('created_at >= ?', beginning_of_interval) + .completed_requests + .non_robots + .group(:host, :uri) + .rollup('host|uri', interval: starting_interval, update: true) + + # Reducir las estadísticas calculadas aplicando un rollup sobre el + # intervalo más amplio. + Stat::INTERVALS.reduce do |previous, current| + Rollup.where(name: 'host|uri', interval: previous) + .where_dimensions(host: hostname, uri: uri) + .group("dimensions->'host'", "dimensions->'uri'") + .rollup('host|uri', interval: current, update: true) do |rollup| + rollup.sum(:value) + end + + # Devolver el intervalo actual + current + end + end + end + + # Recordar la última vez que se corrió la tarea + site.stats.create! name: STAT_NAME + + run_again! unless once + end + + private + + def stat_name + STAT_NAME + end + + # @return [String] + # + # TODO: Cambiar al mergear origin-referer + def destination + @destination ||= site.deploys.find_by(type: 'DeployLocal').destination + end + + # TODO: Cambiar al mergear origin-referer + # + # @return [Array] + def hostnames + @hostnames ||= site.deploys.map do |deploy| + case deploy + when DeployLocal + site.hostname + when DeployWww + deploy.fqdn + when DeployAlternativeDomain + deploy.hostname.dup.tap do |h| + h.replace(h.end_with?('.') ? h[0..-2] : "#{h}.#{Site.domain}") + end + when DeployHiddenService + deploy.onion + end + end.compact + end + + # Recolecta todas las URIs menos imágenes + # + # @return [Array] + def uris + @uris ||= Dir.chdir destination do + (Dir.glob('**/*.html') + Dir.glob('public/**/*').reject do |p| + File.directory? p + end.reject do |p| + p = p.downcase + + IMAGES.any? do |i| + p.end_with? i + end + end).map do |uri| + "/#{uri}" end end end diff --git a/app/models/site.rb b/app/models/site.rb index ddfe2bc9..df92264a 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -37,6 +37,7 @@ class Site < ApplicationRecord belongs_to :design belongs_to :licencia + has_many :stats has_many :log_entries, dependent: :destroy has_many :deploys, dependent: :destroy has_many :build_stats, through: :deploys diff --git a/app/models/stat.rb b/app/models/stat.rb index c986ba4b..5f72ccd0 100644 --- a/app/models/stat.rb +++ b/app/models/stat.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true +# Registran cuándo fue la última recolección de datos. class Stat < ApplicationRecord - INTERVALS = %i[year month day].freeze + # XXX: Los intervalos van en orden de mayor especificidad a menor + INTERVALS = %i[day month year].freeze RESOURCES = %i[builds space_used build_time].freeze + + belongs_to :site end From 7a780188e4f85030d619014061e3ce09ef060b85 Mon Sep 17 00:00:00 2001 From: f Date: Tue, 26 Oct 2021 16:19:42 -0300 Subject: [PATCH 85/99] asegurarse que siempre buscamos assets --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 01167fa1..981ce7fd 100644 --- a/Gemfile +++ b/Gemfile @@ -16,7 +16,7 @@ gem 'puma' # assets. No es necesario instalarlas en producción. # # XXX: Supuestamente Rails ya soporta RAILS_GROUPS, pero Bundler no. -if ENV['RAILS_GROUPS']&.include? 'assets' +if ENV['RAILS_GROUPS']&.split(',')&.include? 'assets' gem 'sassc-rails' gem 'uglifier', '>= 1.3.0' gem 'bootstrap', '~> 4' From 25fe41bfa258d167c978152939bc65c9eb4c03b7 Mon Sep 17 00:00:00 2001 From: f Date: Wed, 27 Oct 2021 10:12:28 -0300 Subject: [PATCH 86/99] enviar el idioma al reordenar! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit los tests envían el idioma pero no el panel --- app/views/posts/index.haml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index ad07b9dc..90d65670 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -67,6 +67,7 @@ %h2= t('posts.empty') - else = form_tag site_posts_reorder_path, method: :post do + %input{ type: 'hidden', name: 'post[lang]', value: @locale } %table.table{ data: { controller: 'reorder' } } %caption.sr-only= t('posts.caption') %thead From 09f5583d313801d42f5b930fd5eac28699302148 Mon Sep 17 00:00:00 2001 From: Nulo Date: Thu, 28 Oct 2021 15:32:13 -0300 Subject: [PATCH 87/99] Makefile: setear ENV_FILE en hain Requiere de https://0xacab.org/sutty/haini.sh/-/merge_requests/33. Pasa RAILS_GROUPS y otras variables. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 18914f43..1f0ca914 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ commit ?= origin/rails## Commit desde el que actualizar env ?= staging## Entorno del nodo delegado sutty ?= $(SUTTY)## Dirección local delegate ?= $(DELEGATE)## Cambia el nodo delegado -hain ?= $(HAINISH)## Ubicación de Hainish +hain ?= ENV_FILE=.env $(HAINISH)## Ubicación de Hainish # El nodo delegado tiene dos entornos, production y staging. # Dependiendo del entorno que elijamos, se van a generar los assets y el From 2844ca9f5f08c0d307734e5d52b2c7e63b989ec7 Mon Sep 17 00:00:00 2001 From: Nulo Date: Thu, 28 Oct 2021 16:06:31 -0300 Subject: [PATCH 88/99] .env.example: setear RAILS_ENV=development --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index f79ff3a4..fb086224 100644 --- a/.env.example +++ b/.env.example @@ -2,7 +2,7 @@ RAILS_GROUPS=assets DELEGATE=athshe.sutty.nl HAINISH=../haini.sh/haini.sh DATABASE= -RAILS_ENV= +RAILS_ENV=development IMAP_SERVER= DEFAULT_FROM= EXCEPTION_TO= From 21f650fc575656e174a22d36d3f89f6ea0e33f7f Mon Sep 17 00:00:00 2001 From: Nulo Date: Thu, 28 Oct 2021 16:13:39 -0300 Subject: [PATCH 89/99] Editor: forzar modo claro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Esto hace que sea legible y más usable cuando el modo oscuro está activado. https://0xacab.org/sutty/sutty/-/issues/2135 Idealmente, me gustaría tener modo oscuro real en el editor. --- app/assets/stylesheets/editor.scss | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/assets/stylesheets/editor.scss b/app/assets/stylesheets/editor.scss index 5d218c7e..e0886533 100644 --- a/app/assets/stylesheets/editor.scss +++ b/app/assets/stylesheets/editor.scss @@ -2,6 +2,13 @@ box-sizing: border-box; *, *::before, *::after { box-sizing: inherit; } + // Arreglo temporal para que las cosas sean legibles en modo oscuro + --foreground: black; + --background: white; + --color: #f206f9; + background: var(--background); + color: var(--foreground); + h1, h2, h3, h4, h5, h6, p, li { min-height: 1.5rem; } From 66ec5269378c908f83975295d052fe07fd0a4203 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 4 Nov 2021 10:42:57 -0300 Subject: [PATCH 90/99] permitir descripciones mas cortas --- app/models/site.rb | 2 +- app/views/sites/_form.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/site.rb b/app/models/site.rb index df92264a..5b78d625 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -26,7 +26,7 @@ class Site < ApplicationRecord validates :design_id, presence: true validates_inclusion_of :status, in: %w[waiting enqueued building] validates_presence_of :title - validates :description, length: { in: 50..160 } + validates :description, length: { in: 10..160 } validate :deploy_local_presence validate :compatible_layouts, on: :update diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index d26eeebf..6f15d570 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -39,7 +39,7 @@ %h2= f.label :description %p.lead= t('.help.description') = f.text_area :description, class: form_control(site, :description), - maxlength: 160, minlength: 50, required: true + maxlength: 160, minlength: 10, required: true - if invalid? site, :description .invalid-feedback= site.errors.messages[:description].join(', ') %hr/ From 6dcbe97ac6273fdf637f6143ecc1f88cb0255193 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 4 Nov 2021 10:58:49 -0300 Subject: [PATCH 91/99] permalinks relativos --- app/models/metadata_permalink.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/metadata_permalink.rb b/app/models/metadata_permalink.rb index dc65aa86..59b68461 100644 --- a/app/models/metadata_permalink.rb +++ b/app/models/metadata_permalink.rb @@ -5,7 +5,7 @@ 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 unless post.new? + document.url.sub(%r{\A/}, '') unless post.new? end # Los permalinks nunca pueden ser privados From d85f21c3ca08161255c13ead2c756414b7122f50 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 25 Nov 2021 09:42:58 -0300 Subject: [PATCH 92/99] =?UTF-8?q?actualizaci=C3=B3n=20de=20cuidados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile | 2 +- Gemfile.lock | 68 ++++++++++++++++++++++++++-------------------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/Gemfile b/Gemfile index 88dde566..2b304ee0 100644 --- a/Gemfile +++ b/Gemfile @@ -22,7 +22,7 @@ if ENV['RAILS_GROUPS']&.split(',')&.include? 'assets' gem 'bootstrap', '~> 4' end -gem 'nokogiri', '~>1.11.0' +gem 'nokogiri' # Turbolinks makes navigating your web application faster. Read more: # https://github.com/turbolinks/turbolinks diff --git a/Gemfile.lock b/Gemfile.lock index 814175f0..9f0b56c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,10 +8,10 @@ GIT GIT remote: https://github.com/ankane/rollup.git - revision: 94ca777d54180c23e96ac4b4285cc9b405ccbd1a + revision: 0ab6c603450175eb1004f7793e86486943cb9f72 branch: master specs: - rollups (0.1.2) + rollups (0.1.3) activesupport (>= 5.1) groupdate (>= 5.2) @@ -113,7 +113,7 @@ GEM autoprefixer-rails (>= 9.1.0) popper_js (>= 1.14.3, < 2) sassc-rails (>= 2.0.0) - brakeman (5.1.1) + brakeman (5.1.2) builder (3.2.4) capybara (2.18.0) addressable @@ -122,7 +122,7 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) xpath (>= 2.0, < 4.0) - chartkick (4.0.5) + chartkick (4.1.2) childprocess (4.1.0) coderay (1.1.3) colorator (1.1.0) @@ -138,7 +138,7 @@ GEM activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - dead_end (2.0.1) + dead_end (3.1.0) derailed_benchmarks (2.1.1) benchmark-ips (~> 2) dead_end @@ -157,7 +157,7 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-i18n (1.10.0) + devise-i18n (1.10.1) devise (>= 4.8.0) devise_invitable (2.0.5) actionmailer (>= 5.0) @@ -188,9 +188,9 @@ GEM jekyll-unique-urls (~> 0) jekyll-write-and-commit-changes (~> 0) sutty-liquid (~> 0) - em-websocket (0.5.2) + em-websocket (0.5.3) eventmachine (>= 0.12.9) - http_parser.rb (~> 0.6.0) + http_parser.rb (~> 0) errbase (0.2.1) erubi (1.10.0) eventmachine (1.2.7-x86_64-linux-musl) @@ -212,7 +212,7 @@ GEM activerecord (>= 4.0.0) get_process_mem (0.2.7) ffi (~> 1.0) - globalid (0.5.2) + globalid (0.6.0) activesupport (>= 5.0) groupdate (5.2.2) activesupport (>= 5) @@ -243,11 +243,11 @@ GEM heapy (0.2.0) thor hiredis (0.6.3-x86_64-linux-musl) - http_parser.rb (0.6.0-x86_64-linux-musl) + http_parser.rb (0.8.0-x86_64-linux-musl) httparty (0.18.1) mime-types (~> 3.0) multi_xml (>= 0.5.2) - i18n (1.8.10) + i18n (1.8.11) concurrent-ruby (~> 1.0) icalendar (2.7.1) ice_cube (~> 0.16) @@ -258,7 +258,7 @@ GEM inline_svg (1.7.2) activesupport (>= 3.0) nokogiri (>= 1.6) - jbuilder (2.11.2) + jbuilder (2.11.3) activesupport (>= 5.0.0) jekyll (4.2.1) addressable (~> 2.4) @@ -289,7 +289,7 @@ GEM jekyll (~> 4) jekyll-ignore-layouts (0.1.2) jekyll (~> 4) - jekyll-images (0.2.7) + jekyll-images (0.3.0) jekyll (~> 4) ruby-filemagic (~> 0.7) ruby-vips (~> 2) @@ -297,7 +297,7 @@ GEM jekyll (>= 3.7, < 5.0) jekyll-linked-posts (0.4.2) jekyll (~> 4) - jekyll-locales (0.1.12) + jekyll-locales (0.1.13) jekyll-lunr (0.3.0) loofah (~> 2.4) jekyll-order (0.1.4) @@ -307,9 +307,9 @@ GEM sassc (> 2.0.1, < 3.0) jekyll-seo-tag (2.7.1) jekyll (>= 3.8, < 5.0) - jekyll-spree-client (0.1.18) + jekyll-spree-client (0.1.19) fast_blank (~> 1) - spree-api-client (>= 0.2.3) + spree-api-client (>= 0.2.4) jekyll-turbolinks (0.0.5) jekyll (~> 4) turbolinks-source (~> 5) @@ -362,9 +362,9 @@ GEM memory_profiler (1.0.0) mercenary (0.4.0) method_source (1.0.0) - mime-types (3.3.1) + mime-types (3.4.1) mime-types-data (~> 3.2015) - mime-types-data (3.2021.0901) + mime-types-data (3.2021.1115) mini_histogram (0.3.1) mini_magick (4.11.0) mini_mime (1.1.2) @@ -374,7 +374,7 @@ GEM jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) minitest (5.14.4) - mobility (1.2.2) + mobility (1.2.3) i18n (>= 0.6.10, < 2) request_store (~> 1.0) multi_xml (0.6.0) @@ -395,7 +395,7 @@ GEM activerecord (>= 5.2) activesupport (>= 5.2) popper_js (1.16.0) - prometheus_exporter (0.8.1) + prometheus_exporter (1.0.0) webrick pry (0.14.1) coderay (~> 1.1) @@ -505,7 +505,7 @@ GEM railties (>= 5.0) rexml (3.2.5) rouge (3.26.1) - rubocop (1.22.2) + rubocop (1.23.0) parallel (~> 1.10) parser (>= 3.0.0.0) rainbow (>= 2.2.2, < 4.0) @@ -514,7 +514,7 @@ GEM rubocop-ast (>= 1.12.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.12.0) + rubocop-ast (1.13.0) parser (>= 3.0.1.1) rubocop-rails (2.12.4) activesupport (>= 4.2.0) @@ -525,14 +525,14 @@ GEM ruby-filemagic (0.7.2-x86_64-linux-musl) ruby-progressbar (1.11.0) ruby-statistics (3.0.0) - ruby-vips (2.1.3) + ruby-vips (2.1.4) ffi (~> 1.12) ruby2ruby (2.4.4) ruby_parser (~> 3.1) sexp_processor (~> 4.6) ruby_dep (1.5.0) - ruby_parser (3.17.0) - sexp_processor (~> 4.15, >= 4.15.1) + ruby_parser (3.18.1) + sexp_processor (~> 4.16) rubyzip (2.3.2) rugged (1.2.0-x86_64-linux-musl) safe_yaml (1.0.6) @@ -546,12 +546,12 @@ GEM sprockets (> 3.0) sprockets-rails tilt - selenium-webdriver (4.0.3) + selenium-webdriver (4.1.0) childprocess (>= 0.5, < 5.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2) semantic_range (3.0.0) - sexp_processor (4.15.3) + sexp_processor (4.16.0) share-to-fediverse-jekyll-theme (0.1.4) jekyll (~> 4.0) jekyll-data (~> 1.1) @@ -563,7 +563,7 @@ GEM simpleidn (0.2.1) unf (~> 0.1.4) sourcemap (0.1.1) - spree-api-client (0.2.3) + spree-api-client (0.2.4) fast_blank (~> 1) httparty (~> 0.18.0) spring (2.1.1) @@ -573,9 +573,9 @@ GEM sprockets (4.0.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.2) - actionpack (>= 4.0) - activesupport (>= 4.0) + sprockets-rails (3.4.1) + actionpack (>= 5.2) + activesupport (>= 5.2) sprockets (>= 3.0.0) sqlite3 (1.4.2-x86_64-linux-musl) stackprof (0.2.17-x86_64-linux-musl) @@ -600,7 +600,7 @@ GEM jekyll-include-cache (~> 0) jekyll-relative-urls (~> 0.0) jekyll-seo-tag (~> 2.1) - sutty-liquid (0.7.3) + sutty-liquid (0.7.4) fast_blank (~> 1.0) jekyll (~> 4) sutty-minima (2.5.0) @@ -631,7 +631,7 @@ GEM activesupport (>= 3.0) warden (1.2.9) rack (>= 2.0.9) - web-console (4.1.0) + web-console (4.2.0) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) @@ -705,7 +705,7 @@ DEPENDENCIES minima mobility net-ssh - nokogiri (~> 1.11.0) + nokogiri pg pg_search prometheus_exporter From 1fa97854a6858cfe90491b3b69814a360a92b1ff Mon Sep 17 00:00:00 2001 From: f Date: Mon, 29 Nov 2021 11:30:55 -0300 Subject: [PATCH 93/99] actualizar mobility para recuperar performance --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9f0b56c5..8df2d77e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -374,7 +374,7 @@ GEM jekyll-feed (~> 0.9) jekyll-seo-tag (~> 2.1) minitest (5.14.4) - mobility (1.2.3) + mobility (1.2.4) i18n (>= 0.6.10, < 2) request_store (~> 1.0) multi_xml (0.6.0) From f2a0654ebcb2fd63992a7c146d48b36f45d8a832 Mon Sep 17 00:00:00 2001 From: Nulo Date: Tue, 30 Nov 2021 16:45:19 +0000 Subject: [PATCH 94/99] =?UTF-8?q?Permitir=20clickear=20en=20el=20p=C3=A1rr?= =?UTF-8?q?afo=20de=20ejemplo=20para=20subir=20multimedia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/assets/stylesheets/editor.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/assets/stylesheets/editor.scss b/app/assets/stylesheets/editor.scss index e0886533..30fab60a 100644 --- a/app/assets/stylesheets/editor.scss +++ b/app/assets/stylesheets/editor.scss @@ -71,6 +71,10 @@ strong, em, del, u, sub, sup, small { background: #0002; } a { background: #13fefe50; } [data-editor-selected] { outline: #f206f9 solid thick; } + p[data-multimedia-inner] { + // Ignorar clicks en el párrafo placeholder + pointer-events: none; + } } *[data-editor-loading] { From 380d80ded4d3ffd4291d3d98d5f0d9ad0c6cef03 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 6 Dec 2021 14:55:46 -0300 Subject: [PATCH 95/99] =?UTF-8?q?solo=20instalar=20paquetes=20de=20producc?= =?UTF-8?q?i=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #3892 --- 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 c063b7bc..fb1142b2 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -82,7 +82,7 @@ class DeployLocal < Deploy def yarn return true unless yarn_lock? - run 'yarn' + run 'yarn install --production' end def bundle From 4e461e7af6f648fc4b5d91437160ec363e5cdc8b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 9 Dec 2021 10:42:03 -0300 Subject: [PATCH 96/99] =?UTF-8?q?usar=20una=20cach=C3=A9=20com=C3=BAn=20pa?= =?UTF-8?q?ra=20yarn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/deploy_local.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/models/deploy_local.rb b/app/models/deploy_local.rb index fb1142b2..f9225f39 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -62,10 +62,15 @@ class DeployLocal < Deploy 'AIRBRAKE_PROJECT_ID' => site.id.to_s, 'AIRBRAKE_PROJECT_KEY' => site.airbrake_api_key, 'JEKYLL_ENV' => Rails.env, - 'LANG' => ENV['LANG'] + 'LANG' => ENV['LANG'], + 'YARN_CACHE_FOLDER' => yarn_cache_dir } end + def yarn_cache_dir + Rails.root.join('_yarn_cache') + end + def yarn_lock File.join(site.path, 'yarn.lock') end From 36cf199548805b498b810cb8789b84254c76443b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Dec 2021 22:47:15 -0300 Subject: [PATCH 97/99] devolver una string --- 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 f9225f39..4fa588f5 100644 --- a/app/models/deploy_local.rb +++ b/app/models/deploy_local.rb @@ -68,7 +68,7 @@ class DeployLocal < Deploy end def yarn_cache_dir - Rails.root.join('_yarn_cache') + Rails.root.join('_yarn_cache').to_s end def yarn_lock From 87c94e95484e0765fbdb8a5094af47c0895d8eb2 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 7 Mar 2022 11:47:37 -0300 Subject: [PATCH 98/99] mostrar el html --- app/views/posts/show.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/posts/show.haml b/app/views/posts/show.haml index da6ac9db..e46114af 100644 --- a/app/views/posts/show.haml +++ b/app/views/posts/show.haml @@ -38,4 +38,4 @@ - cache [metadata, I18n.locale] do %section.editor{ id: attr, dir: dir } - = @post.public_send(attr).to_s.html_safe + = @post.public_send(attr).value.html_safe From c9edc86be34d8728d5a15f599553a90977893efc Mon Sep 17 00:00:00 2001 From: f Date: Mon, 7 Mar 2022 11:48:46 -0300 Subject: [PATCH 99/99] =?UTF-8?q?copiar=20una=20tabla=20desde=20producci?= =?UTF-8?q?=C3=B3n=20a=20desarrollo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1f0ca914..5a9ad7a8 100644 --- a/Makefile +++ b/Makefile @@ -71,6 +71,15 @@ rake: ## Corre rake dentro del entorno de desarrollo (pasar argumentos con args= bundle: ## Corre bundle dentro del entorno de desarrollo (pasar argumentos con args=). $(hain) 'bundle $(args)' +psql := psql -h $(PG_HOST) -U $(PG_USER) -p $(PG_PORT) -d sutty +copy-table: + test -n "$(table)" + echo "truncate $(table) $(cascade);" | $(psql) + ssh $(delegate) docker exec postgresql pg_dump -U sutty -d sutty -t $(table) | $(psql) + +psql: + $(psql) + rubocop: ## Yutea el código que está por ser commiteado git status --porcelain \ | grep -E "^(A|M)" \ @@ -102,8 +111,7 @@ save: ## Subir la imagen Docker al nodo delegado @echo -e "\a" ota-js: assets ## Actualizar Javascript en el nodo delegado - sudo chgrp -R 82 public/ - rsync -avi --delete-after public/ root@$(delegate):/srv/sutty/srv/http/data/_$(public)/ + rsync -avi --delete-after --chown 1000:82 public/ root@$(delegate):/srv/sutty/srv/http/data/_$(public)/ ssh root@$(delegate) docker exec $(container) sh -c "cat /srv/http/tmp/puma.pid | xargs -r kill -USR2" ota: ## Actualizar Rails en el nodo delegado