mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-17 00:26:22 +00:00
Merge branch 'rails' into production.panel.sutty.nl
This commit is contained in:
commit
cf77514bb6
123 changed files with 2249 additions and 1599 deletions
|
@ -1,8 +1,8 @@
|
|||
NODE_OPTIONS=--openssl-legacy-provider
|
||||
# pwgen -1 32
|
||||
RAILS_MASTER_KEY=11111111111111111111111111111111
|
||||
RAILS_GROUPS=assets
|
||||
DELEGATE=athshe.sutty.nl
|
||||
HAINISH=../haini.sh/haini.sh
|
||||
DELEGATE=panel.sutty.nl
|
||||
DATABASE_URL=postgres://suttier@postgresql.sutty.local/sutty
|
||||
RAILS_ENV=development
|
||||
IMAP_SERVER=
|
||||
|
@ -37,3 +37,5 @@ AIRBRAKE_API_KEY=
|
|||
GITLAB_URI=https://0xacab.org
|
||||
GITLAB_PROJECT=
|
||||
GITLAB_TOKEN=
|
||||
PGVER=15
|
||||
PGPID=/run/postgresql.pid
|
1
.env.development
Normal file
1
.env.development
Normal file
|
@ -0,0 +1 @@
|
|||
HAINISH=../haini.sh/haini.sh
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -28,7 +28,7 @@
|
|||
/data/*
|
||||
/_storage/*
|
||||
|
||||
.env*
|
||||
.env.*
|
||||
|
||||
# Ignore master key for decrypting credentials and more.
|
||||
/config/master.key
|
||||
|
@ -48,3 +48,7 @@ yarn-debug.log*
|
|||
/yarn-error.log
|
||||
yarn-debug.log*
|
||||
.yarn-integrity
|
||||
|
||||
/.task
|
||||
/.yardoc
|
||||
/public/doc/
|
||||
|
|
106
.gitlab-ci.yml
106
.gitlab-ci.yml
|
@ -1,33 +1,99 @@
|
|||
image: "gitea.nulo.in/sutty/panel:3.14.10-2.7.8-panel.sutty.nl"
|
||||
.apk-add: &apk-add
|
||||
- "apk add go-task diffutils"
|
||||
.disable-hainish: &disable-hainish
|
||||
- "rm -f .env.development"
|
||||
.cache-ruby: &cache-ruby
|
||||
- paths:
|
||||
- "vendor/ruby"
|
||||
- ".bundle"
|
||||
.cache-node: &cache-node
|
||||
- paths:
|
||||
- "node_modules"
|
||||
.cache-task: &cache-task
|
||||
- paths:
|
||||
- ".task"
|
||||
image: "registry.0xacab.org/sutty/sutty:3.17.3-3.1.4-rails"
|
||||
variables:
|
||||
RAILS_ENV: "production"
|
||||
LC_ALL: "C.UTF-8"
|
||||
HAINISH: ""
|
||||
cache:
|
||||
paths:
|
||||
- "vendor/ruby"
|
||||
assets:
|
||||
stage: "build"
|
||||
rules:
|
||||
- if: "$CI_COMMIT_BRANCH == \"panel.sutty.nl\""
|
||||
- if: "$CI_COMMIT_BRANCH"
|
||||
changes:
|
||||
compare_to: "refs/heads/rails"
|
||||
paths:
|
||||
- "package.json"
|
||||
- "app/javascript/**/*"
|
||||
- "app/assets/**/*"
|
||||
stage: "deploy"
|
||||
only:
|
||||
- "rails"
|
||||
- "17.3.alpine.panel.sutty.nl"
|
||||
except:
|
||||
- "schedules"
|
||||
cache:
|
||||
- *cache-ruby
|
||||
- *cache-node
|
||||
- *cache-task
|
||||
before_script:
|
||||
- "git config --global user.email \"${GIT_USER_EMAIL:-$GITLAB_USER_EMAIL}\""
|
||||
- "git config --global user.name \"${GIT_USER_NAME:-$GITLAB_USER_NAME}\""
|
||||
- "git remote set-url --push origin \"https://${GITLAB_USERNAME}:${GITLAB_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git\""
|
||||
- "apk add python2 dotenv brotli"
|
||||
- "mv config/credentials.yml.enc.ci config/credentials.yml.enc"
|
||||
- "cp .env.example .env"
|
||||
- "dotenv bundle install --path=vendor"
|
||||
- "apk add brotli"
|
||||
- *apk-add
|
||||
- *disable-hainish
|
||||
script:
|
||||
- "dotenv RAILS_ENV=production bundle exec rails webpacker:clobber"
|
||||
- "dotenv RAILS_ENV=production bundle exec rails assets:precompile"
|
||||
- "dotenv RAILS_ENV=production bundle exec rails assets:clean"
|
||||
- "go-task assets"
|
||||
after_script:
|
||||
- "git add public && git commit -m \"ci: assets [skip ci]\""
|
||||
- "git push -o ci.skip"
|
||||
gem-audit:
|
||||
stage: "test"
|
||||
only:
|
||||
- "schedules"
|
||||
cache:
|
||||
- *cache-ruby
|
||||
before_script:
|
||||
- *apk-add
|
||||
- *disable-hainish
|
||||
script:
|
||||
- "go-task gem-audit"
|
||||
node-audit:
|
||||
stage: "test"
|
||||
only:
|
||||
- "schedules"
|
||||
cache:
|
||||
- *cache-node
|
||||
before_script:
|
||||
- *apk-add
|
||||
- *disable-hainish
|
||||
script:
|
||||
- "apk add go-task"
|
||||
- "go-task node-audit"
|
||||
brakeman:
|
||||
stage: "test"
|
||||
cache:
|
||||
- *cache-ruby
|
||||
rules:
|
||||
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
||||
before_script:
|
||||
- *apk-add
|
||||
- *disable-hainish
|
||||
script:
|
||||
- "go-task bundle -- exec brakeman"
|
||||
rubocop:
|
||||
stage: "test"
|
||||
cache:
|
||||
- *cache-ruby
|
||||
rules:
|
||||
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
||||
before_script:
|
||||
- *apk-add
|
||||
- *disable-hainish
|
||||
script:
|
||||
- "./bin/modified_files | ./bin/with_extension rb | xargs -r go-task bundle -- exec rubocop"
|
||||
haml:
|
||||
stage: "test"
|
||||
cache:
|
||||
- *cache-ruby
|
||||
rules:
|
||||
- if: "$CI_PIPELINE_SOURCE == 'merge_request_event'"
|
||||
before_script:
|
||||
- *apk-add
|
||||
- *disable-hainish
|
||||
script:
|
||||
- "./bin/modified_files | ./bin/with_extension haml | xargs -r go-task bundle -- exec haml-lint"
|
||||
|
|
|
@ -19,7 +19,6 @@ pipeline:
|
|||
when:
|
||||
branch:
|
||||
- "rails"
|
||||
- "panel.sutty.nl"
|
||||
- "17.3.alpine.panel.sutty.nl"
|
||||
event: "push"
|
||||
path:
|
||||
|
@ -27,55 +26,8 @@ pipeline:
|
|||
- "Dockerfile"
|
||||
- ".dockerignore"
|
||||
- ".woodpecker.yml"
|
||||
assets:
|
||||
image: "gitea.nulo.in/sutty/panel:3.14.10-2.7.8"
|
||||
commands:
|
||||
- "apk add python2 dotenv openssh-client brotli"
|
||||
- "install -d -m 700 ~/.ssh/"
|
||||
- "echo \"$${KNOWN_HOSTS}\" | base64 -d >> ~/.ssh/known_hosts"
|
||||
- "chmod 600 ~/.ssh/known_hosts"
|
||||
- "eval $(ssh-agent -s)"
|
||||
- "echo \"$${SSH_KEY}\" | base64 -d | ssh-add -"
|
||||
- "ssh $${ORIGIN%:*}"
|
||||
- "git config user.name Woodpecker"
|
||||
- "git config user.email ci@sutty.coop.ar"
|
||||
- "git remote add upstream $${ORIGIN}"
|
||||
- "git checkout -B ${CI_COMMIT_BRANCH}"
|
||||
- "mv config/credentials.yml.enc.ci config/credentials.yml.enc"
|
||||
- "yarn"
|
||||
- "cp .env.example .env"
|
||||
- "dotenv bundle install --path=vendor"
|
||||
- "dotenv RAILS_ENV=production bundle exec rails webpacker:clobber"
|
||||
- "dotenv RAILS_ENV=production bundle exec rails assets:precompile"
|
||||
- "dotenv RAILS_ENV=production bundle exec rails assets:clean"
|
||||
- "git add public && git commit -m \"ci: assets [skip ci]\""
|
||||
- "git push upstream ${CI_COMMIT_BRANCH}"
|
||||
environment:
|
||||
- "RUBY_VERSION=${RUBY_VERSION}"
|
||||
- "GEMS_SOURCE=https://14.3.alpine.gems.sutty.nl"
|
||||
secrets:
|
||||
- "SSH_KEY"
|
||||
- "KNOWN_HOSTS"
|
||||
- "ORIGIN"
|
||||
when:
|
||||
branch:
|
||||
- "rails"
|
||||
- "panel.sutty.nl"
|
||||
path:
|
||||
include:
|
||||
- "app/assets/**/*"
|
||||
- "app/javascript/**/*"
|
||||
- "package.json"
|
||||
- "yarn.lock"
|
||||
matrix:
|
||||
ALPINE_VERSION: "3.14.10"
|
||||
RUBY_VERSION: "2.7"
|
||||
RUBY_PATCH: "8"
|
||||
matrix:
|
||||
include:
|
||||
- ALPINE_VERSION: "3.17.3"
|
||||
RUBY_VERSION: "3.1"
|
||||
RUBY_PATCH: "4"
|
||||
- ALPINE_VERSION: "3.14.10"
|
||||
RUBY_VERSION: "2.7"
|
||||
RUBY_PATCH: "8"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
ARG RUBY_VERSION=2.7
|
||||
ARG RUBY_PATCH=8
|
||||
ARG ALPINE_VERSION=3.14.10
|
||||
ARG RUBY_VERSION=3.1
|
||||
ARG RUBY_PATCH=4
|
||||
ARG ALPINE_VERSION=3.17.3
|
||||
ARG BASE_IMAGE=registry.nulo.in/sutty/rails
|
||||
FROM ${BASE_IMAGE}:${ALPINE_VERSION}-${RUBY_VERSION}.${RUBY_PATCH}
|
||||
ARG PANDOC_VERSION=2.18
|
||||
|
|
10
Gemfile
10
Gemfile
|
@ -1,15 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
if ENV['RAILS_ENV'] != 'production' && ENV['HAIN_ENV'].nil?
|
||||
puts 'Usa haini.sh para generar un entorno de trabajo reproducible'
|
||||
end
|
||||
|
||||
source ENV.fetch('GEMS_SOURCE', 'https://17.3.alpine.gems.sutty.nl')
|
||||
|
||||
ruby "~> #{ENV.fetch('RUBY_VERSION', '3.1')}"
|
||||
|
||||
gem 'dotenv-rails', require: 'dotenv/rails-now'
|
||||
|
||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
||||
gem 'rails', '~> 6.1.0'
|
||||
# Use Puma as the app server
|
||||
|
@ -112,6 +106,7 @@ end
|
|||
|
||||
group :development, :test do
|
||||
gem 'derailed_benchmarks'
|
||||
gem 'dotenv-rails'
|
||||
gem 'pry'
|
||||
gem 'capybara'
|
||||
gem 'selenium-webdriver'
|
||||
|
@ -119,8 +114,9 @@ group :development, :test do
|
|||
end
|
||||
|
||||
group :development do
|
||||
gem 'reek'
|
||||
gem 'yard'
|
||||
gem 'brakeman'
|
||||
gem 'bundler-audit'
|
||||
gem 'haml-lint', require: false
|
||||
gem 'letter_opener'
|
||||
gem 'listen'
|
||||
|
|
36
Gemfile.lock
36
Gemfile.lock
|
@ -25,7 +25,7 @@ GIT
|
|||
groupdate (>= 5.2)
|
||||
|
||||
GEM
|
||||
remote: https://gems.sutty.nl/
|
||||
remote: https://17.3.alpine.gems.sutty.nl/
|
||||
specs:
|
||||
actioncable (6.1.7.3)
|
||||
actionpack (= 6.1.7.3)
|
||||
|
@ -89,6 +89,8 @@ GEM
|
|||
addressable (2.8.4)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
ast (2.4.2)
|
||||
autoprefixer-rails (10.4.13.0)
|
||||
execjs (~> 2)
|
||||
bcrypt (3.1.19-x86_64-linux-musl)
|
||||
bcrypt_pbkdf (1.1.0-x86_64-linux-musl)
|
||||
benchmark-ips (2.12.0)
|
||||
|
@ -98,8 +100,15 @@ GEM
|
|||
chartkick (>= 3.2)
|
||||
railties (>= 5)
|
||||
safely_block (>= 0.1.1)
|
||||
bootstrap (4.6.2)
|
||||
autoprefixer-rails (>= 9.1.0)
|
||||
popper_js (>= 1.16.1, < 2)
|
||||
sassc-rails (>= 2.0.0)
|
||||
brakeman (5.4.1)
|
||||
builder (3.2.4)
|
||||
bundler-audit (0.9.1)
|
||||
bundler (>= 1.2.0, < 3)
|
||||
thor (~> 1.0)
|
||||
capybara (2.18.0)
|
||||
addressable
|
||||
mini_mime (>= 0.1.3)
|
||||
|
@ -198,6 +207,7 @@ GEM
|
|||
exception_notification (4.5.0)
|
||||
actionmailer (>= 5.2, < 8)
|
||||
activesupport (>= 5.2, < 8)
|
||||
execjs (2.8.1)
|
||||
factory_bot (6.2.1)
|
||||
activesupport (>= 5.0.0)
|
||||
factory_bot_rails (6.2.0)
|
||||
|
@ -309,7 +319,6 @@ GEM
|
|||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
kwalify (0.7.2)
|
||||
launchy (2.5.2)
|
||||
addressable (~> 2.8)
|
||||
letter_opener (1.8.1)
|
||||
|
@ -373,6 +382,7 @@ GEM
|
|||
pg_search (2.3.6)
|
||||
activerecord (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
popper_js (1.16.1)
|
||||
prometheus_exporter (2.0.8)
|
||||
webrick
|
||||
pry (0.14.2)
|
||||
|
@ -447,10 +457,6 @@ GEM
|
|||
redis-store (>= 1.2, < 2)
|
||||
redis-store (1.9.2)
|
||||
redis (>= 4, < 6)
|
||||
reek (6.1.4)
|
||||
kwalify (~> 0.7.0)
|
||||
parser (~> 3.2.0)
|
||||
rainbow (>= 2.0, < 4.0)
|
||||
regexp_parser (2.8.0)
|
||||
request_store (1.5.1)
|
||||
rack (>= 1.4)
|
||||
|
@ -496,6 +502,12 @@ GEM
|
|||
errbase (>= 0.1.1)
|
||||
sassc (2.4.0-x86_64-linux-musl)
|
||||
ffi (~> 1.9)
|
||||
sassc-rails (2.1.2)
|
||||
railties (>= 4.0.0)
|
||||
sassc (>= 2.0)
|
||||
sprockets (> 3.0)
|
||||
sprockets-rails
|
||||
tilt
|
||||
selenium-webdriver (4.9.1)
|
||||
rexml (~> 3.2, >= 3.2.5)
|
||||
rubyzip (>= 1.2.2, < 3.0)
|
||||
|
@ -528,7 +540,7 @@ GEM
|
|||
temple (0.10.1)
|
||||
terminal-table (2.0.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
thor (1.2.2)
|
||||
thor (1.3.0)
|
||||
tilt (2.1.0)
|
||||
timecop (0.9.6)
|
||||
timeout (0.3.2)
|
||||
|
@ -537,6 +549,8 @@ GEM
|
|||
turbolinks-source (5.2.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
uglifier (4.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2-x86_64-linux-musl)
|
||||
|
@ -564,6 +578,7 @@ GEM
|
|||
websocket-extensions (0.1.5)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
yard (0.9.34)
|
||||
zeitwerk (2.6.8)
|
||||
|
||||
PLATFORMS
|
||||
|
@ -573,7 +588,9 @@ DEPENDENCIES
|
|||
bcrypt (~> 3.1.7)
|
||||
bcrypt_pbkdf
|
||||
blazer
|
||||
bootstrap (~> 4)
|
||||
brakeman
|
||||
bundler-audit
|
||||
capybara
|
||||
chartkick
|
||||
commonmarker
|
||||
|
@ -607,7 +624,6 @@ DEPENDENCIES
|
|||
jbuilder (~> 2.5)
|
||||
jekyll (~> 4.2.0)
|
||||
jekyll-commonmark (~> 1.4.0)
|
||||
jekyll-data
|
||||
jekyll-images
|
||||
jekyll-include-cache
|
||||
kaminari
|
||||
|
@ -635,7 +651,6 @@ DEPENDENCIES
|
|||
rails_warden
|
||||
redis (~> 4.0)
|
||||
redis-rails
|
||||
reek
|
||||
rgl
|
||||
rollups!
|
||||
rubocop-rails
|
||||
|
@ -643,6 +658,7 @@ DEPENDENCIES
|
|||
rugged (= 1.5.0.1)
|
||||
safe_yaml
|
||||
safely_block (~> 0.3.0)
|
||||
sassc-rails
|
||||
selenium-webdriver
|
||||
sourcemap
|
||||
spring
|
||||
|
@ -654,10 +670,12 @@ DEPENDENCIES
|
|||
terminal-table
|
||||
timecop
|
||||
turbolinks (~> 5)
|
||||
uglifier (>= 1.3.0)
|
||||
validates_hostname
|
||||
web-console
|
||||
webpacker
|
||||
yaml_db!
|
||||
yard
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.1.4p223
|
||||
|
|
143
Makefile
143
Makefile
|
@ -1,143 +0,0 @@
|
|||
SHELL := /bin/bash
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
# 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 $@ $<
|
||||
|
||||
include .env
|
||||
|
||||
export
|
||||
|
||||
# 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 ?= 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
|
||||
# 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 ?= panel
|
||||
## 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
|
||||
|
||||
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/"
|
||||
|
||||
assets: public/packs/manifest.json.br ## Compilar los assets
|
||||
git add public/assets/ public/packs/ && NADA=true git commit -m "assets [skip ci]" ; true
|
||||
|
||||
test: always ## Ejecutar los tests
|
||||
$(MAKE) rake args="test RAILS_ENV=test $(args)"
|
||||
|
||||
postgresql: /etc/hosts ## Iniciar la base de datos
|
||||
pgrep postgres >/dev/null || $(hain) 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
|
||||
|
||||
rails: ## Corre rails dentro del entorno de desarrollo (pasar argumentos con args=).
|
||||
$(MAKE) bundle args="exec rails $(args)"
|
||||
|
||||
rake: ## Corre rake dentro del entorno de desarrollo (pasar argumentos con args=).
|
||||
$(MAKE) bundle args="exec rake $(args)"
|
||||
|
||||
bundle: ## Corre bundle dentro del entorno de desarrollo (pasar argumentos con args=).
|
||||
$(hain) 'bundle $(args)'
|
||||
|
||||
psql := haini.sh 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)" \
|
||||
| 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)'
|
||||
|
||||
clean: ## Limpieza
|
||||
rm -rf _sites/test-* _deploy/test-* log/*.log tmp/cache tmp/letter_opener tmp/miniprofiler tmp/storage
|
||||
|
||||
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: ## 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"
|
||||
|
||||
ota: ## Actualizar Rails en el nodo delegado
|
||||
git push
|
||||
ssh $(delegate) git -C /srv/sutty/srv/http/panel.sutty.nl pull
|
||||
ssh $(delegate) git -C /srv/sutty/srv/http/panel.sutty.nl lfs prune
|
||||
ssh $(delegate) chown -R 1000:82 /srv/sutty/srv/http/panel.sutty.nl
|
||||
ssh $(delegate) docker exec $(container) rails reload
|
||||
|
||||
# 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 $@
|
||||
@grep -q " api.$(SUTTY)$$" $@ || echo -e "127.0.0.1 api.$(SUTTY)\n::1 api.$(SUTTY)" | sudo tee -a $@
|
||||
@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
|
4
Procfile
4
Procfile
|
@ -1,5 +1,5 @@
|
|||
cleanup: bundle exec rake cleanup:everything
|
||||
stats: bundle exec rake stats:process_all
|
||||
distributed_press_tokens_renew: bundle exec rake distributed_press:tokens:renew
|
||||
que: daemonize -c /srv/ -p /srv/tmp/que.pid -u rails /usr/local/bin/syslogize bundle exec que
|
||||
emergency_cleanup: bundle exec rake cleanup:everything BEFORE=7
|
||||
que: daemonize -c /srv/ -p /srv/tmp/que.pid -u rails /usr/local/bin/syslogize bundle exec que
|
||||
stats: bundle exec rake stats:process_all
|
||||
|
|
51
README.md
51
README.md
|
@ -17,14 +17,32 @@ 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.
|
||||
Para facilitar la gestión de dependencias y entorno de desarrollo,
|
||||
instala [haini.sh](https://0xacab.org/sutty/haini.sh)
|
||||
|
||||
|
||||
Todas las tareas se gestionan con `go-task`. [Instrucciones de
|
||||
instalación (en inglés)](https://taskfile.dev/installation/)
|
||||
|
||||
```bash
|
||||
make help
|
||||
go-task
|
||||
```
|
||||
|
||||
[Leer la documentación](https://docs.sutty.nl/)
|
||||
### Variables de entorno
|
||||
|
||||
Las variables de entorno por defecto se encuentran en el archivo `.env`.
|
||||
Para modificar las opciones, crear o modificar el archivo `.env.local`
|
||||
con valores distintos.
|
||||
|
||||
### Documentación
|
||||
|
||||
Para navegar la documentación del código usando YARD:
|
||||
|
||||
```bash
|
||||
go-task doc serve
|
||||
```
|
||||
|
||||
Y luego navegar a <https://panel.sutty.local:3000/doc/>
|
||||
|
||||
## English
|
||||
|
||||
|
@ -39,10 +57,29 @@ For more information, visit [Sutty's website](https://sutty.nl/en/).
|
|||
|
||||
### Development
|
||||
|
||||
Every task is run via `make`, please install GNU Make before developing.
|
||||
|
||||
To facilitate dependencies and dev environment, install
|
||||
[haini.sh](https://0xacab.org/sutty/haini.sh)
|
||||
|
||||
Every task is run via `go-task`. [Installation
|
||||
instructions](https://taskfile.dev/installation/).
|
||||
|
||||
```bash
|
||||
make help
|
||||
go-task
|
||||
```
|
||||
|
||||
[Read the documentation](https://docs.sutty.nl/en/)
|
||||
### Environment variables
|
||||
|
||||
Default env vars are store on `.env`. For local options, copy them to
|
||||
`.env.local`.
|
||||
|
||||
### Documentation
|
||||
|
||||
To browse documentation using YARD:
|
||||
|
||||
```bash
|
||||
go-task doc serve
|
||||
```
|
||||
|
||||
And then open <https://panel.sutty.local:3000/doc/>
|
||||
|
||||
|
|
185
Taskfile.yaml
Normal file
185
Taskfile.yaml
Normal file
|
@ -0,0 +1,185 @@
|
|||
---
|
||||
version: "3"
|
||||
vars:
|
||||
CURRENT_BRANCH:
|
||||
sh: "git rev-parse --abbrev-ref HEAD"
|
||||
shopt:
|
||||
- "globstar"
|
||||
dotenv:
|
||||
- ".env.development"
|
||||
- ".env"
|
||||
- ".env.local"
|
||||
- ".env.development.local"
|
||||
tasks:
|
||||
credentials:
|
||||
desc: "Generate credentials file"
|
||||
cmds:
|
||||
- "cp --no-clobber config/credentials.yml.enc.ci config/credentials.yml.enc"
|
||||
sources:
|
||||
- "config/credentials.yml.enc.ci"
|
||||
generates:
|
||||
- "config/credentials.yml.enc"
|
||||
gems:
|
||||
desc: "Install gems"
|
||||
deps:
|
||||
- "credentials"
|
||||
cmds:
|
||||
- "{{.HAINISH}} bundle config set --local path './vendor'"
|
||||
- "{{.HAINISH}} bundle install"
|
||||
sources:
|
||||
- "Gemfile"
|
||||
generates:
|
||||
- "Gemfile.lock"
|
||||
status:
|
||||
- "test -d vendor/ruby"
|
||||
clean:
|
||||
desc: "Clean"
|
||||
cmds:
|
||||
- "rm -rf _sites/test-* _deploy/test-* log/*.log tmp/cache tmp/letter_opener tmp/miniprofiler tmp/storage"
|
||||
node-modules:
|
||||
desc: "Install Node modules"
|
||||
cmds:
|
||||
- "{{.HAINISH}} yarn"
|
||||
sources:
|
||||
- "package.json"
|
||||
- "yarn.lock"
|
||||
status:
|
||||
- "test -d node_modules"
|
||||
assets:
|
||||
desc: "Generate assets"
|
||||
deps:
|
||||
- "node-modules"
|
||||
- "gems"
|
||||
cmds:
|
||||
- "git lfs fetch"
|
||||
- "git lfs checkout"
|
||||
- task: "rails"
|
||||
vars:
|
||||
CLI_ARGS: "webpacker:clobber RAILS_ENV=production"
|
||||
- task: "rails"
|
||||
vars:
|
||||
CLI_ARGS: "assets:precompile RAILS_ENV=production"
|
||||
- task: "rails"
|
||||
vars:
|
||||
CLI_ARGS: "assets:clean RAILS_ENV=production"
|
||||
sources:
|
||||
- "package.json"
|
||||
- "yarn.lock"
|
||||
- "app/assets/**/*"
|
||||
- "app/javascript/**/*"
|
||||
generates:
|
||||
- "public/packs/manifest.json"
|
||||
hosts:
|
||||
desc: "Local DNS resolution for hostnames"
|
||||
interactive: true
|
||||
cmds:
|
||||
- "echo -e \"127.0.0.1 panel.{{.SUTTY}} api.{{.SUTTY}} postgresql.{{.SUTTY}}\" | sudo tee -a /etc/hosts"
|
||||
- "echo -e \"::1 panel.{{.SUTTY}} api.{{.SUTTY}} postgresql.{{.SUTTY}}\" | sudo tee -a /etc/hosts"
|
||||
status:
|
||||
- "grep -q \" panel.{{.SUTTY}} \" /etc/hosts"
|
||||
database-init:
|
||||
desc: "Database install"
|
||||
cmds:
|
||||
- "{{.HAINISH}} /usr/bin/initdb --locale en_US.utf8 -E UTF8 -D /var/lib/postgresql/{{.PGVER}}/data"
|
||||
- "echo \"host all all samenet trust\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/pg_hba.conf"
|
||||
- "echo \"listen_addresses = '*'\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf"
|
||||
- "echo \"external_pid_file = '{{.PGPID}}'\" >> ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf"
|
||||
- "install -dm755 ../hain/run/postgresql"
|
||||
status:
|
||||
- "test -d ../hain/var/lib/postgresql/{{.PGVER}}/data"
|
||||
- "test -f ../hain/var/lib/postgresql/{{.PGVER}}/data/postgresql.conf"
|
||||
database:
|
||||
desc: "Database"
|
||||
deps:
|
||||
- "database-init"
|
||||
cmds:
|
||||
- "{{.HAINISH}} daemonize -c /var/lib/postgresql/{{.PGVER}}/data /usr/bin/postgres -D /var/lib/postgresql/{{.PGVER}}/data"
|
||||
status:
|
||||
- "test -f ../hain{{.PGPID}}"
|
||||
- "pgrep -F ../hain{{.PGPID}}"
|
||||
prepare:
|
||||
desc: "Create database or run pending migrations"
|
||||
deps:
|
||||
- "database"
|
||||
cmds:
|
||||
- task: "rails"
|
||||
vars:
|
||||
CLI_ARGS: "db:prepare"
|
||||
serve:
|
||||
desc: "Run Rails development server"
|
||||
deps:
|
||||
- "prepare"
|
||||
- "gems"
|
||||
cmds:
|
||||
- ": == Development server running at https://panel.{{.SUTTY_WITH_PORT}} =="
|
||||
- task: "rails"
|
||||
vars:
|
||||
CLI_ARGS: "server"
|
||||
status:
|
||||
- "test -f tmp/pids/server.pid"
|
||||
- "pgrep -F tmp/pids/server.pid"
|
||||
yarn:
|
||||
desc: "Yarn. Call with: go-task yarn -- arguments"
|
||||
deps:
|
||||
- "node-modules"
|
||||
cmds:
|
||||
- "{{.HAINISH}} yarn {{.CLI_ARGS}}"
|
||||
- defer:
|
||||
task: "notify"
|
||||
bundle:
|
||||
desc: "Bundle. Call with: go-task bundle -- arguments"
|
||||
interactive: true
|
||||
deps:
|
||||
- "gems"
|
||||
cmds:
|
||||
- "{{.HAINISH}} bundle {{.CLI_ARGS}}"
|
||||
- defer:
|
||||
task: "notify"
|
||||
rails:
|
||||
desc: "Rails. Call with: go-task rails -- arguments"
|
||||
cmds:
|
||||
- task: "bundle"
|
||||
vars:
|
||||
CLI_ARGS: "exec rails {{.CLI_ARGS}}"
|
||||
console:
|
||||
desc: "Rails console"
|
||||
interactive: true
|
||||
cmds:
|
||||
- task: "rails"
|
||||
vars:
|
||||
CLI_ARGS: "console"
|
||||
doc:
|
||||
desc: "Build documentation"
|
||||
deps:
|
||||
- "gems"
|
||||
cmds:
|
||||
- task: "bundle"
|
||||
vars:
|
||||
CLI_ARGS: "exec yardoc -o public/doc app lib config db"
|
||||
gem-audit:
|
||||
desc: "Audit Gem dependencies"
|
||||
deps:
|
||||
- "gems"
|
||||
- "bundler-audit"
|
||||
cmds:
|
||||
- task: "bundle"
|
||||
vars:
|
||||
CLI_ARGS: "audit --update"
|
||||
node-audit:
|
||||
desc: "Audit Node dependencies"
|
||||
deps:
|
||||
- "node-modules"
|
||||
cmds:
|
||||
- task: "yarn"
|
||||
vars:
|
||||
CLI_ARGS: "audit"
|
||||
notify:
|
||||
internal: true
|
||||
cmds:
|
||||
- "echo -e \"\a\""
|
||||
bundler-audit:
|
||||
internal: true
|
||||
cmds:
|
||||
- "{{.HAINISH}} gem install bundler-audit"
|
||||
status:
|
||||
- "test -f ../hain/usr/bin/bundler-audit"
|
|
@ -196,7 +196,7 @@ fieldset {
|
|||
|
||||
&[type=button] {
|
||||
@extend .btn;
|
||||
@extend .btn-info;
|
||||
@extend .btn-secondary;
|
||||
@extend .m-0;
|
||||
}
|
||||
}
|
||||
|
@ -210,10 +210,6 @@ svg {
|
|||
}
|
||||
|
||||
.btn {
|
||||
background-color: var(--foreground);
|
||||
color: var(--background);
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
margin-right: 0.3rem;
|
||||
margin-bottom: 0.3rem;
|
||||
|
||||
|
@ -253,7 +249,7 @@ svg {
|
|||
color: $magenta;
|
||||
}
|
||||
|
||||
.btn {
|
||||
.btn-secondary {
|
||||
background-color: $white;
|
||||
color: $black;
|
||||
border: none;
|
||||
|
|
|
@ -7,3 +7,22 @@ $cyan: #13fefe;
|
|||
--background: #{$black};
|
||||
--color: #{$cyan};
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: $white;
|
||||
color: $black;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
color: $black;
|
||||
background-color: $cyan;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: $cyan;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 0.2rem $cyan;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,14 @@ module ActiveStorage
|
|||
end
|
||||
end
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :page_not_found
|
||||
|
||||
# Asociar el archivo subido al sitio correspondiente. Cada sitio
|
||||
# tiene su propio servicio de subida de archivos.
|
||||
def update
|
||||
if (token = decode_verified_token)
|
||||
if acceptable_content?(token)
|
||||
blob = ActiveStorage::Blob.find_by_key token[:key]
|
||||
blob = ActiveStorage::Blob.find_by_key! token[:key]
|
||||
site = Site.find_by_name token[:service_name]
|
||||
|
||||
if remote_file?(token)
|
||||
|
@ -59,6 +61,11 @@ module ActiveStorage
|
|||
def remote_file?(token)
|
||||
token[:content_type] == 'sutty/download-from-url'
|
||||
end
|
||||
|
||||
def page_not_found(exception)
|
||||
head :not_found
|
||||
ExceptionNotifier.notify_exception(exception, data: {params: params.to_hash})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -68,7 +68,7 @@ module Api
|
|||
|
||||
# respuesta de error a plataformas
|
||||
def platforms_answer(exception)
|
||||
ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h }
|
||||
ExceptionNotifier.notify_exception(exception, data: { headers: request.headers.to_h })
|
||||
|
||||
head :forbidden
|
||||
end
|
||||
|
|
|
@ -110,27 +110,6 @@ class SitesController < ApplicationController
|
|||
redirect_to sites_path
|
||||
end
|
||||
|
||||
# Obtiene y streamea archivos estáticos desde el repositorio mismo,
|
||||
# pero sólo los públicos (es decir los archivos subidos desde Sutty).
|
||||
def static_file
|
||||
authorize site
|
||||
|
||||
file = params.require(:file) + '.' + params.require(:format)
|
||||
|
||||
raise ActionController::RoutingError.new(nil, nil) unless file.start_with? 'public/'
|
||||
|
||||
path = site.relative_path file
|
||||
|
||||
raise ActionController::RoutingError.new(nil, nil) unless File.exist? path
|
||||
|
||||
# TODO: Hacer esto usa recursos, pero menos que generar el sitio
|
||||
# cada vez. Para poder usar X-Accel tendríamos que montar los
|
||||
# repositorios en el servidor web, cosa que no queremos, o hacer
|
||||
# links simbólicos desde todos los public, o usar un servidor web
|
||||
# local que soporte sendfile mejor que Rails (nghttpd?)
|
||||
send_file path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def site
|
||||
|
|
|
@ -96,7 +96,7 @@ module ActiveStorage
|
|||
end
|
||||
|
||||
def blob_for(key)
|
||||
ActiveStorage::Blob.find_by(key: key, service_name: name)
|
||||
ActiveStorage::Blob.find_by!(key: key, service_name: name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -55,20 +55,9 @@ class Deploy < ApplicationRecord
|
|||
site.path
|
||||
end
|
||||
|
||||
# Un entorno que solo tiene lo que necesitamos
|
||||
#
|
||||
# @return [Hash]
|
||||
def env
|
||||
# XXX: This doesn't support Windows paths :B
|
||||
paths = [File.dirname(`which bundle`), '/usr/local/bin', '/usr/bin', '/bin']
|
||||
|
||||
# Las variables de entorno extra no pueden superponerse al local.
|
||||
extra_env.merge({
|
||||
'HOME' => home_dir,
|
||||
'PATH' => paths.join(':'),
|
||||
'JEKYLL_ENV' => Rails.env,
|
||||
'LANG' => ENV['LANG'],
|
||||
})
|
||||
# XXX: Ver DeployLocal#bundle
|
||||
def gems_dir
|
||||
@gems_dir ||= Rails.root.join('_storage', 'gems', site.name)
|
||||
end
|
||||
|
||||
# Un entorno que solo tiene lo que necesitamos
|
||||
|
|
|
@ -7,11 +7,6 @@ class DeployLocal < Deploy
|
|||
|
||||
before_destroy :remove_destination!
|
||||
|
||||
def git_lfs(output: false)
|
||||
run %(git lfs fetch), output: output
|
||||
run %(git lfs checkout), output: output
|
||||
end
|
||||
|
||||
def bundle(output: false)
|
||||
run %(bundle config set --local clean 'true'), output: output
|
||||
run %(bundle config set --local deployment 'true'), output: output if site.gemfile_lock_path?
|
||||
|
@ -21,6 +16,11 @@ class DeployLocal < Deploy
|
|||
run %(bundle install), output: output
|
||||
end
|
||||
|
||||
def git_lfs(output: false)
|
||||
run %(git lfs fetch), output: output
|
||||
run %(git lfs checkout), output: output
|
||||
end
|
||||
|
||||
# Realizamos la construcción del sitio usando Jekyll y un entorno
|
||||
# limpio para no pasarle secretos
|
||||
#
|
||||
|
|
|
@ -107,8 +107,10 @@ class Post
|
|||
src = element.attributes['src']
|
||||
|
||||
next unless src&.value&.start_with? 'public/'
|
||||
file = MetadataFile.new(site: site, post: self, document: document, layout: layout)
|
||||
file.value['path'] = src.value
|
||||
|
||||
src.value = Rails.application.routes.url_helpers.site_static_file_url(site, file: src.value)
|
||||
src.value = Rails.application.routes.url_helpers.url_for(file.static_file)
|
||||
end
|
||||
|
||||
# Notificar a les usuaries que están viendo una previsualización
|
||||
|
|
|
@ -158,19 +158,19 @@ class Site < ApplicationRecord
|
|||
|
||||
# Traer la ruta del sitio
|
||||
def path
|
||||
File.join(Site.site_path, name)
|
||||
::File.join(Site.site_path, name)
|
||||
end
|
||||
|
||||
# La ruta anterior
|
||||
def path_was
|
||||
File.join(Site.site_path, name_was)
|
||||
::File.join(Site.site_path, name_was)
|
||||
end
|
||||
|
||||
# Limpiar la ruta y unirla con el separador de directorios del
|
||||
# sistema operativo. Como si algún día fuera a cambiar o
|
||||
# soportáramos Windows :P
|
||||
def relative_path(suspicious_path)
|
||||
File.join(path, *suspicious_path.gsub('..', '/').gsub('./', '').squeeze('/').split('/'))
|
||||
::File.join(path, *suspicious_path.gsub('..', '/').gsub('./', '').squeeze('/').split('/'))
|
||||
end
|
||||
|
||||
# Obtiene la lista de traducciones actuales
|
||||
|
@ -359,7 +359,7 @@ class Site < ApplicationRecord
|
|||
end
|
||||
|
||||
def jekyll?
|
||||
File.directory? path
|
||||
::File.directory? path
|
||||
end
|
||||
|
||||
def jekyll
|
||||
|
@ -377,7 +377,7 @@ class Site < ApplicationRecord
|
|||
# documentos de Jekyll hacia Sutty para que podamos leer los datos que
|
||||
# necesitamos.
|
||||
def load_jekyll
|
||||
return unless name.present? && File.directory?(path)
|
||||
return unless name.present? && ::File.directory?(path)
|
||||
|
||||
reload_jekyll!
|
||||
end
|
||||
|
@ -405,7 +405,7 @@ class Site < ApplicationRecord
|
|||
# metadatos de Document
|
||||
@configuration =
|
||||
::Jekyll.configuration('source' => path,
|
||||
'destination' => File.join(path, '_site'),
|
||||
'destination' => ::File.join(path, '_site'),
|
||||
'safe' => true, 'watch' => false,
|
||||
'quiet' => true, 'excerpt_separator' => '')
|
||||
|
||||
|
@ -430,7 +430,7 @@ class Site < ApplicationRecord
|
|||
|
||||
# El directorio donde se almacenan los sitios
|
||||
def self.site_path
|
||||
@site_path ||= File.realpath(ENV.fetch('SITE_PATH', Rails.root.join('_sites')))
|
||||
@site_path ||= ::File.realpath(ENV.fetch('SITE_PATH', Rails.root.join('_sites')))
|
||||
end
|
||||
|
||||
def self.default
|
||||
|
@ -461,7 +461,7 @@ class Site < ApplicationRecord
|
|||
end
|
||||
|
||||
def gemfile_lock_path?
|
||||
File.exist? gemfile_lock_path
|
||||
::File.exist? gemfile_lock_path
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -552,6 +552,12 @@ class Site < ApplicationRecord
|
|||
I18n.t('activerecord.errors.models.site.attributes.design_id.layout_incompatible.error'))
|
||||
end
|
||||
|
||||
def run_in_path(&block)
|
||||
Site.one_at_a_time.synchronize do
|
||||
Dir.chdir path, &block
|
||||
end
|
||||
end
|
||||
|
||||
# Instala las gemas cuando es necesario:
|
||||
#
|
||||
# * El sitio existe
|
||||
|
@ -567,6 +573,7 @@ class Site < ApplicationRecord
|
|||
if !gems_installed? || gemfile_updated? || gemfile_lock_updated?
|
||||
deploy_local.bundle
|
||||
touch
|
||||
::File.touch(gemfile_path)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -587,12 +594,16 @@ class Site < ApplicationRecord
|
|||
|
||||
# Detecta si el Gemfile fue modificado
|
||||
def gemfile_updated?
|
||||
updated_at < File.mtime(File.join(path, 'Gemfile'))
|
||||
updated_at < ::File.mtime(gemfile_path)
|
||||
end
|
||||
|
||||
def gemfile_path
|
||||
@gemfile_path ||= ::File.join(path, 'Gemfile')
|
||||
end
|
||||
|
||||
# @return [String]
|
||||
def gemfile_lock_path
|
||||
@gemfile_lock_path ||= File.join(path, 'Gemfile.lock')
|
||||
@gemfile_lock_path ||= ::File.join(path, 'Gemfile.lock')
|
||||
end
|
||||
|
||||
# Detecta si el Gemfile.lock fue modificado con respecto al sitio o al
|
||||
|
@ -600,8 +611,8 @@ class Site < ApplicationRecord
|
|||
def gemfile_lock_updated?
|
||||
return false unless gemfile_lock_path?
|
||||
|
||||
[updated_at, File.mtime(File.join(path, 'Gemfile'))].any? do |compare|
|
||||
compare < File.mtime(gemfile_lock_path)
|
||||
[updated_at, ::File.mtime(::File.join(path, 'Gemfile'))].any? do |compare|
|
||||
compare < ::File.mtime(gemfile_lock_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ class Site
|
|||
# Leer el archivo de configuración y setear los atributos en el
|
||||
# objeto actual, creando los metodos de ostruct
|
||||
def read
|
||||
data = YAML.safe_load(File.read(path))
|
||||
data = YAML.safe_load(File.read(path), permitted_classes: [Time])
|
||||
@hash = data.hash
|
||||
|
||||
data.each do |key, value|
|
||||
|
|
|
@ -16,7 +16,7 @@ class Site
|
|||
#
|
||||
# @return [nil]
|
||||
def generate_private_key_pem!
|
||||
self.private_key_pem ||= DistributedPress::V1::Social::Client.new(public_key_url: nil, key_size: 2048).private_key.export
|
||||
self.private_key_pem ||= ::DistributedPress::V1::Social::Client.new(public_key_url: nil, key_size: 2048).private_key.export
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,7 @@ class CleanupService
|
|||
site.deploys.find_each(&:cleanup!)
|
||||
|
||||
site.repository.gc
|
||||
lfs_cleanup
|
||||
site.touch
|
||||
end
|
||||
end
|
||||
|
@ -45,7 +46,14 @@ class CleanupService
|
|||
Rails.logger.info "Limpiando repositorio git de #{site.name}"
|
||||
|
||||
site.repository.gc
|
||||
lfs_cleanup
|
||||
site.touch
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def lfs_cleanup
|
||||
site.repository.git_sh("git", "lfs", "prune")
|
||||
site.repository.git_sh("git", "lfs", "dedup")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,4 +25,4 @@
|
|||
class: 'form-control'
|
||||
|
||||
.form-group
|
||||
= f.submit t('.submit'), class: 'btn btn-lg btn-block'
|
||||
= f.submit t('.submit'), class: 'btn btn-secondary btn-lg btn-block'
|
||||
|
|
|
@ -30,5 +30,5 @@
|
|||
placeholder: t('activerecord.attributes.usuarie.email')
|
||||
.actions
|
||||
= f.submit t('.resend_confirmation_instructions'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
= render 'devise/shared/links'
|
||||
|
|
|
@ -32,4 +32,4 @@
|
|||
placeholder: t('activerecord.attributes.usuarie.password')
|
||||
.actions
|
||||
= f.submit t('devise.invitations.edit.submit_button'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
|
|
|
@ -16,4 +16,4 @@
|
|||
= f.text_field field, class: 'form-control'
|
||||
.actions
|
||||
= f.submit t('devise.invitations.new.submit_button'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
|
|
|
@ -39,6 +39,6 @@
|
|||
|
||||
.actions
|
||||
= f.submit t('.change_my_password'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
|
||||
= render 'devise/shared/links'
|
||||
|
|
|
@ -20,5 +20,5 @@
|
|||
placeholder: t('activerecord.attributes.usuarie.email')
|
||||
.actions
|
||||
= f.submit t('.send_me_reset_password_instructions'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
= render 'devise/shared/links'
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
= t('.we_need_your_current_password_to_confirm_your_changes')
|
||||
.actions
|
||||
= f.submit t('.update'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
%hr/
|
||||
|
||||
.sr-only
|
||||
|
@ -63,4 +63,4 @@
|
|||
= button_to t('.cancel_my_account'),
|
||||
registration_path(resource_name),
|
||||
data: { confirm: t('.are_you_sure') },
|
||||
method: :delete, class: 'btn btn-block'
|
||||
method: :delete, class: 'btn btn-secondary btn-block'
|
||||
|
|
|
@ -56,6 +56,6 @@
|
|||
|
||||
.actions
|
||||
= f.submit t('.sign_up'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
|
||||
= render 'devise/shared/links'
|
||||
|
|
|
@ -32,5 +32,5 @@
|
|||
= t('login.remember_me', remember_for: distance_of_time_in_words(Usuarie.remember_for))
|
||||
.actions
|
||||
= f.submit t('.sign_in'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
= render 'devise/shared/links'
|
||||
|
|
|
@ -4,12 +4,12 @@
|
|||
|
||||
- if controller_name != 'sessions'
|
||||
= link_to t('.sign_in'), new_session_path(resource_name, params: locale),
|
||||
class: 'btn btn-lg btn-block btn-success'
|
||||
class: 'btn btn-lg btn-block btn-secondary'
|
||||
%br/
|
||||
|
||||
- if devise_mapping.registerable? && controller_name != 'registrations'
|
||||
= link_to t('.sign_up'), new_registration_path(resource_name, params: locale),
|
||||
class: 'btn btn-lg btn-block btn-success'
|
||||
class: 'btn btn-lg btn-block btn-secondary'
|
||||
%br/
|
||||
|
||||
- if devise_mapping.recoverable?
|
||||
|
|
|
@ -20,5 +20,5 @@
|
|||
placeholder: t('activerecord.attributes.usuarie.email')
|
||||
.actions
|
||||
= f.submit t('.resend_unlock_instructions'),
|
||||
class: 'btn btn-lg btn-block'
|
||||
class: 'btn btn-secondary btn-lg btn-block'
|
||||
= render 'devise/shared/links'
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
= select_tag 'to',
|
||||
options_for_select(@options, @lang_to),
|
||||
class: 'form-control'
|
||||
= submit_tag t('i18n.translate'), class: 'btn', name: nil
|
||||
= submit_tag t('i18n.translate'), class: 'btn btn-secondary', name: nil
|
||||
- else
|
||||
= t('i18n.translating.from')
|
||||
= select_tag 'from',
|
||||
|
@ -21,7 +21,7 @@
|
|||
= select_tag 'to',
|
||||
options_for_select(@options, @lang_to),
|
||||
class: 'form-control'
|
||||
= submit_tag t('i18n.change'), class: 'btn', name: nil
|
||||
= submit_tag t('i18n.change'), class: 'btn btn-secondary', name: nil
|
||||
|
||||
= render 'layouts/help', help: t('help.i18n.index')
|
||||
|
||||
|
@ -33,16 +33,16 @@
|
|||
= hidden_field 'i18n', 'lang_to', value: @lang_to
|
||||
.form-group
|
||||
.dropdown.inline
|
||||
%button.btn.dropdown-toggle{type: 'button',
|
||||
%button.btn.btn-secondary.dropdown-toggle{type: 'button',
|
||||
data: { toggle: 'dropdown' },
|
||||
aria: { haspopup: 'true', expanded: 'false' }}
|
||||
= t('i18n.jump')
|
||||
.dropdown-menu{aria: { labelledby: t('i18n.jump') }}
|
||||
- @site.data.dig(@lang_from).each_pair do |section, content|
|
||||
%a.dropdown-item{href: "##{section}"}= t("help.i18n.#{section}")
|
||||
= submit_tag t('i18n.save'), class: 'btn'
|
||||
= submit_tag t('i18n.save'), class: 'btn btn-secondary'
|
||||
|
||||
= render 'i18n/recursive', data: @site.data.dig(@lang_from), superkeys: []
|
||||
|
||||
.form-group
|
||||
= submit_tag t('i18n.save'), class: 'btn'
|
||||
= submit_tag t('i18n.save'), class: 'btn btn-secondary'
|
||||
|
|
|
@ -18,15 +18,15 @@
|
|||
- if @site&.tienda?
|
||||
%li.nav-item
|
||||
= link_to t('.tienda'), @site.tienda_url,
|
||||
role: 'button', class: 'btn'
|
||||
role: 'button', class: 'btn btn-secondary'
|
||||
|
||||
%li.nav-item
|
||||
= link_to t('.contact_us'), t('.contact_us_href'),
|
||||
class: 'btn', rel: 'me', target: '_blank'
|
||||
class: 'btn btn-secondary', rel: 'me', target: '_blank'
|
||||
|
||||
%li.nav-item
|
||||
= link_to t('.logout'), main_app.destroy_usuarie_session_path,
|
||||
method: :delete, role: 'button', class: 'btn'
|
||||
method: :delete, role: 'button', class: 'btn btn-secondary'
|
||||
- else
|
||||
- params.permit!
|
||||
- I18n.available_locales.each do |locale|
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
= link_to text, link, class: 'btn',
|
||||
= link_to text, link, class: 'btn btn-secondary',
|
||||
data: { toggle: 'tooltip' }, 'aria-role': 'button', title: tooltip
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
- invalid_help = site.config.fetch('invalid_help', t('.invalid_help'))
|
||||
- sending_help = site.config.fetch('sending_help', t('.sending_help'))
|
||||
.form-group
|
||||
= submit_tag t('.save'), class: 'btn submit-post'
|
||||
= submit_tag t('.save'), class: 'btn btn-secondary submit-post'
|
||||
= render 'bootstrap/alert', class: 'invalid-help d-none' do
|
||||
= invalid_help
|
||||
= render 'bootstrap/alert', class: 'sending-help d-none' do
|
||||
|
|
|
@ -20,82 +20,82 @@
|
|||
TODO: Eliminar todo el espacio en blanco para minificar HTML
|
||||
.editor-toolbar{ style: 'z-index: 1' }
|
||||
.editor-primary-toolbar.scrollbar-black
|
||||
%button.btn{ type: 'button', title: t('editor.multimedia'), data: { editor_button: 'multimedia' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.multimedia'), data: { editor_button: 'multimedia' } }>
|
||||
%i.fa.fa-fw.fa-upload>
|
||||
%span.sr-only>= t('editor.multimedia')
|
||||
%button.btn{ type: 'button', title: t('editor.bold'), data: { editor_button: 'mark-bold' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.bold'), data: { editor_button: 'mark-bold' } }>
|
||||
%i.fa.fa-fw.fa-bold>
|
||||
%span.sr-only>= t('editor.bold')
|
||||
%button.btn{ type: 'button', title: t('editor.italic'), data: { editor_button: 'mark-italic' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.italic'), data: { editor_button: 'mark-italic' } }>
|
||||
%i.fa.fa-fw.fa-italic>
|
||||
%span.sr-only>= t('editor.italic')
|
||||
%button.btn{ type: 'button', title: t('editor.mark'), data: { editor_button: 'mark-mark' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.mark'), data: { editor_button: 'mark-mark' } }>
|
||||
%i.fa.fa-fw.fa-tint>
|
||||
%span.sr-only>= t('editor.mark')
|
||||
%button.btn{ type: 'button', title: t('editor.link'), data: { editor_button: 'mark-link' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.link'), data: { editor_button: 'mark-link' } }>
|
||||
%i.fa.fa-fw.fa-link>
|
||||
%span.sr-only>= t('editor.link')
|
||||
%button.btn{ type: 'button', title: t('editor.deleted'), data: { editor_button: 'mark-deleted' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.deleted'), data: { editor_button: 'mark-deleted' } }>
|
||||
%i.fa.fa-fw.fa-strikethrough>
|
||||
%span.sr-only>= t('editor.deleted')
|
||||
%button.btn{ type: 'button', title: t('editor.underline'), data: { editor_button: 'mark-underline' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.underline'), data: { editor_button: 'mark-underline' } }>
|
||||
%i.fa.fa-fw.fa-underline>
|
||||
%span.sr-only>= t('editor.underline')
|
||||
%button.btn{ type: 'button', title: t('editor.super'), data: { editor_button: 'mark-super' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.super'), data: { editor_button: 'mark-super' } }>
|
||||
%i.fa.fa-fw.fa-superscript>
|
||||
%span.sr-only>= t('editor.super')
|
||||
%button.btn{ type: 'button', title: t('editor.sub'), data: { editor_button: 'mark-sub' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.sub'), data: { editor_button: 'mark-sub' } }>
|
||||
%i.fa.fa-fw.fa-subscript>
|
||||
%span.sr-only>= t('editor.sub')
|
||||
%button.btn{ type: 'button', title: t('editor.small'), data: { editor_button: 'mark-small' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.small'), data: { editor_button: 'mark-small' } }>
|
||||
%i.fa.fa-fw.fa-subscript>
|
||||
%span.sr-only>= t('editor.small')
|
||||
%button.btn.mr-0{ type: 'button', title: t('editor.h1'), data: { editor_button: 'block-h1' } }>
|
||||
%button.btn.btn-secondary.mr-0{ type: 'button', title: t('editor.h1'), data: { editor_button: 'block-h1' } }>
|
||||
%i.fa.fa-fw.fa-heading>
|
||||
1
|
||||
%span.sr-only>= t('editor.h1')
|
||||
%details.d-inline>
|
||||
%summary.d-inline>
|
||||
%span.btn.ml-0{ role: 'button', title: t('editor.more') }>
|
||||
%span.btn.btn-secondary.ml-0{ role: 'button', title: t('editor.more') }>
|
||||
%i.fa.fa-caret-right>
|
||||
%span.sr-only= t('editor.more')
|
||||
.d-inline>
|
||||
%button.btn{ type: 'button', title: t('editor.h2'), data: { editor_button: 'block-h2' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.h2'), data: { editor_button: 'block-h2' } }>
|
||||
%i.fa.fa-fw.fa-heading>
|
||||
2
|
||||
%span.sr-only>= t('editor.h2')
|
||||
%button.btn{ type: 'button', title: t('editor.h3'), data: { editor_button: 'block-h3' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.h3'), data: { editor_button: 'block-h3' } }>
|
||||
%i.fa.fa-fw.fa-heading>
|
||||
3
|
||||
%span.sr-only>= t('editor.h3')
|
||||
%button.btn{ type: 'button', title: t('editor.h4'), data: { editor_button: 'block-h4' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.h4'), data: { editor_button: 'block-h4' } }>
|
||||
%i.fa.fa-fw.fa-heading>
|
||||
4
|
||||
%span.sr-only>= t('editor.h4')
|
||||
%button.btn{ type: 'button', title: t('editor.h5'), data: { editor_button: 'block-h5' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.h5'), data: { editor_button: 'block-h5' } }>
|
||||
%i.fa.fa-fw.fa-heading>
|
||||
5
|
||||
%span.sr-only>= t('editor.h5')
|
||||
%button.btn{ type: 'button', title: t('editor.h6'), data: { editor_button: 'block-h6' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.h6'), data: { editor_button: 'block-h6' } }>
|
||||
%i.fa.fa-fw.fa-heading>
|
||||
6
|
||||
%span.sr-only>= t('editor.h6')
|
||||
%button.btn{ type: 'button', title: t('editor.ul'), data: { editor_button: 'block-unordered_list' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.ul'), data: { editor_button: 'block-unordered_list' } }>
|
||||
%i.fa.fa-fw.fa-list-ul>
|
||||
%span.sr-only>= t('editor.ul')
|
||||
%button.btn{ type: 'button', title: t('editor.ol'), data: { editor_button: 'block-ordered_list' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.ol'), data: { editor_button: 'block-ordered_list' } }>
|
||||
%i.fa.fa-fw.fa-list-ol>
|
||||
%span.sr-only>= t('editor.ol')
|
||||
%button.btn{ type: 'button', title: t('editor.left'), data: { editor_button: 'parentBlock-left' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.left'), data: { editor_button: 'parentBlock-left' } }>
|
||||
%i.fa.fa-fw.fa-align-left>
|
||||
%span.sr-only>= t('editor.left')
|
||||
%button.btn{ type: 'button', title: t('editor.center'), data: { editor_button: 'parentBlock-center' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.center'), data: { editor_button: 'parentBlock-center' } }>
|
||||
%i.fa.fa-fw.fa-align-center>
|
||||
%span.sr-only>= t('editor.center')
|
||||
%button.btn{ type: 'button', title: t('editor.right'), data: { editor_button: 'parentBlock-right' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.right'), data: { editor_button: 'parentBlock-right' } }>
|
||||
%i.fa.fa-fw.fa-align-right>
|
||||
%span.sr-only>= t('editor.right')
|
||||
%button.btn{ type: 'button', title: t('editor.blockquote'), data: { editor_button: 'block-blockquote' } }>
|
||||
%button.btn.btn-secondary{ type: 'button', title: t('editor.blockquote'), data: { editor_button: 'block-blockquote' } }>
|
||||
%i.fa.fa-fw.fa-quote-left>
|
||||
%span.sr-only>= t('editor.blockquote')
|
||||
|
||||
|
@ -116,8 +116,8 @@
|
|||
%label{ for: 'multimedia-alt' }= t('editor.description')
|
||||
%input.form-control{ type: 'text', id: 'multimedia-alt', name: 'multimedia-alt' }/
|
||||
.form-group
|
||||
%button.btn{ type: 'button', id: 'multimedia-file-upload', name: 'multimedia-file-upload' }= t('editor.multimedia-upload')
|
||||
%button.btn{ type: 'button', id: 'multimedia-remove', name: 'multimedia-remove' }= t('editor.multimedia-remove')
|
||||
%button.btn.btn-secondary{ type: 'button', id: 'multimedia-file-upload', name: 'multimedia-file-upload' }= t('editor.multimedia-upload')
|
||||
%button.btn.btn-secondary{ type: 'button', id: 'multimedia-remove', name: 'multimedia-remove' }= t('editor.multimedia-remove')
|
||||
|
||||
.form-group{ data: { editor_auxiliary: 'link' } }
|
||||
%label{ for: 'link-url' }= t('editor.url')
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
= render 'schemas/row', site: @site, schema: schema, filter: @filter_params
|
||||
|
||||
- if policy(@site_stat).index?
|
||||
= link_to t('stats.index.title'), site_stats_path(@site), class: 'btn'
|
||||
= link_to t('stats.index.title'), site_stats_path(@site), class: 'btn btn-secondary'
|
||||
|
||||
- if policy(@site).edit?
|
||||
= link_to t('sites.edit.btn', site: @site.title), edit_site_path(@site), class: 'btn'
|
||||
= link_to t('sites.edit.btn', site: @site.title), edit_site_path(@site), class: 'btn btn-secondary'
|
||||
|
||||
- if policy(@site).private?
|
||||
= link_to t('sites.private'), '../private/' + @site.name, class: 'btn', target: '_blank', rel: 'noopener'
|
||||
= link_to t('sites.private'), '../private/' + @site.name, class: 'btn btn-secondary', target: '_blank', rel: 'noopener'
|
||||
|
||||
- if policy(SiteUsuarie.new(@site, current_usuarie)).index?
|
||||
= render 'layouts/btn_with_tooltip',
|
||||
|
@ -40,9 +40,9 @@
|
|||
- if @site.design.credits
|
||||
= render 'bootstrap/alert' do
|
||||
= sanitize_markdown @site.design.credits
|
||||
= link_to t('sites.donations.text'), t('sites.donations.url'), class: 'btn'
|
||||
= link_to t('sites.donations.text'), t('sites.donations.url'), class: 'btn btn-secondary'
|
||||
- if @site.design.designer_url
|
||||
= link_to t('sites.designer_url'), @site.design.designer_url, class: 'btn'
|
||||
= link_to t('sites.designer_url'), @site.design.designer_url, class: 'btn btn-secondary'
|
||||
|
||||
%section.col
|
||||
.d-flex.justify-content-between.align-items-center.pl-2-plus.pr-2-plus.mb-2
|
||||
|
@ -83,19 +83,19 @@
|
|||
%div
|
||||
- if reorder_allowed
|
||||
= submit_tag t('posts.reorder.submit'), class: 'btn'
|
||||
%button.btn{ data: { action: 'reorder#unselect' } }
|
||||
%button.btn.btn-secondary{ 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')
|
||||
%button.btn.btn-secondary{ data: { action: 'reorder#up' } }= t('posts.reorder.up')
|
||||
%button.btn.btn-secondary{ data: { action: 'reorder#down' } }= t('posts.reorder.down')
|
||||
%button.btn.btn-secondary{ data: { action: 'reorder#top' } }= t('posts.reorder.top')
|
||||
%button.btn.btn-secondary{ data: { action: 'reorder#bottom' } }= t('posts.reorder.bottom')
|
||||
%input{ type: 'hidden', name: 'post[lang]', value: @locale }
|
||||
|
||||
- if @site.pagination
|
||||
%div
|
||||
= link_to_prev_page @posts, t('posts.prev'), class: 'btn'
|
||||
= link_to_next_page @posts, t('posts.next'), class: 'btn'
|
||||
= link_to_prev_page @posts, t('posts.prev'), class: 'btn btn-secondary'
|
||||
= link_to_next_page @posts, t('posts.next'), class: 'btn btn-secondary'
|
||||
%tbody
|
||||
- dir = @site.data.dig(params[:locale], 'dir')
|
||||
- size = @posts.size
|
||||
|
@ -136,9 +136,9 @@
|
|||
= post.order
|
||||
%td.text-nowrap
|
||||
- if @usuarie || policy(post).edit?
|
||||
= link_to t('posts.edit'), edit_site_post_path(@site, post.path), class: 'btn btn-block'
|
||||
= link_to t('posts.edit'), edit_site_post_path(@site, post.path), class: 'btn btn-secondary btn-block'
|
||||
- if @usuarie || policy(post).destroy?
|
||||
= link_to t('posts.destroy'), site_post_path(@site, post.path), class: 'btn btn-block', method: :delete, data: { confirm: t('posts.confirm_destroy') }
|
||||
= link_to t('posts.destroy'), site_post_path(@site, post.path), class: 'btn btn-secondary btn-block', method: :delete, data: { confirm: t('posts.confirm_destroy') }
|
||||
-#
|
||||
Rescatar cualquier error en un post, notificarlo e
|
||||
ignorar su renderización.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
%article.content.table-responsive-md
|
||||
= link_to t('posts.edit'),
|
||||
edit_site_post_path(@site, @post.id),
|
||||
class: 'btn btn-block'
|
||||
class: 'btn btn-secondary btn-block'
|
||||
|
||||
%table.table.table-condensed
|
||||
%thead
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
method: :post,
|
||||
class: 'form-inline inline' do
|
||||
= submit_tag site.enqueued? ? t('sites.enqueued') : t('sites.enqueue'),
|
||||
class: "btn no-border-radius #{local_assigns[:class]}",
|
||||
class: "btn btn-secondary #{local_assigns[:class]}",
|
||||
title: site.enqueued? ? t('help.sites.enqueued') : t('help.sites.enqueue'),
|
||||
data: { disable_with: t('sites.enqueued') },
|
||||
disabled: site.enqueued?
|
||||
|
|
|
@ -72,10 +72,10 @@
|
|||
.btn-group{ role: 'group', 'aria-label': t('.design.actions') }
|
||||
- if design.url
|
||||
= link_to t('.design.url'), design.url,
|
||||
target: '_blank', class: 'btn'
|
||||
target: '_blank', class: 'btn btn-secondary'
|
||||
- if design.license
|
||||
= link_to t('.design.license'), design.license,
|
||||
target: '_blank', class: 'btn'
|
||||
target: '_blank', class: 'btn btn-secondary'
|
||||
%hr/
|
||||
|
||||
.form-group.licenses#license_id
|
||||
|
@ -99,7 +99,7 @@
|
|||
tags: %w[p a strong em ul ol li h1 h2 h3 h4 h5 h6]
|
||||
|
||||
- unless licencia.custom?
|
||||
= link_to t('.licencia.url'), licencia.url, target: '_blank', class: 'btn', rel: 'noopener'
|
||||
= link_to t('.licencia.url'), licencia.url, target: '_blank', class: 'btn btn-secondary', rel: 'noopener'
|
||||
|
||||
%hr/
|
||||
|
||||
|
@ -164,4 +164,4 @@
|
|||
deploy: deploy_fields, site: site
|
||||
|
||||
.form-group
|
||||
= f.submit submit, class: 'btn btn-lg btn-block'
|
||||
= f.submit submit, class: 'btn btn-secondary btn-lg btn-block'
|
||||
|
|
|
@ -27,4 +27,4 @@
|
|||
.row.justify-content-center
|
||||
.col-12.col-lg-8
|
||||
= link_to t('.merge.request'), site_pull_path(@site),
|
||||
method: 'post', class: 'btn btn-lg'
|
||||
method: 'post', class: 'btn btn-secondary btn-lg'
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
%p.lead= t('.help')
|
||||
- if policy(Site).new?
|
||||
= link_to t('sites.new.title'), new_site_path,
|
||||
class: 'btn'
|
||||
class: 'btn btn-secondary'
|
||||
|
||||
%section.col
|
||||
- if @sites.empty?
|
||||
|
@ -29,18 +29,18 @@
|
|||
= site.title
|
||||
%p.lead= site.description
|
||||
%br
|
||||
= link_to t('.visit'), site.url, class: 'btn'
|
||||
= link_to t('.visit'), site.url, class: 'btn btn-secondary'
|
||||
- if rol.temporal
|
||||
= button_to t('sites.invitations.accept'),
|
||||
site_usuaries_accept_invitation_path(site),
|
||||
method: :patch,
|
||||
title: t('help.sites.invitations.accept'),
|
||||
class: 'btn'
|
||||
class: 'btn btn-secondary'
|
||||
= button_to t('sites.invitations.reject'),
|
||||
site_usuaries_reject_invitation_path(site),
|
||||
method: :patch,
|
||||
title: t('help.sites.invitations.reject'),
|
||||
class: 'btn'
|
||||
class: 'btn btn-secondary'
|
||||
- else
|
||||
- if policy(site).show?
|
||||
= render 'layouts/btn_with_tooltip',
|
||||
|
|
|
@ -11,11 +11,11 @@
|
|||
|
||||
%form.mb-5.form-inline{ method: 'get' }
|
||||
- Stat::INTERVALS.each do |interval|
|
||||
= link_to t(".#{interval}"), site_stats_path(interval: interval, urls: params[:urls], period_start: params[:period_start].to_date.try(:"beginning_of_#{interval}").to_date, period_end: params[:period_end]), class: "mb-0 btn #{'btn-primary active' if @interval == interval}"
|
||||
= link_to t(".#{interval}"), site_stats_path(interval: interval, urls: params[:urls], period_start: params[:period_start].to_date.try(:"beginning_of_#{interval}").to_date, period_end: params[:period_end]), class: "mb-0 btn #{@interval == interval ? 'btn-primary active' : 'btn-secondary' }"
|
||||
|
||||
%input.form-control{ type: 'date', name: :period_start, value: params[:period_start] }
|
||||
%input.form-control{ type: 'date', name: :period_end, value: params[:period_end] }
|
||||
%button.btn.mb-0{ type: 'submit' }= t('.filter')
|
||||
%button.btn.btn-secondary.mb-0{ type: 'submit' }= t('.filter')
|
||||
|
||||
.mb-5
|
||||
%h2= t('.host.title', count: @hostnames.size)
|
||||
|
@ -34,7 +34,7 @@
|
|||
%textarea#urls.form-control{ name: 'urls', autocomplete: 'on', required: true, rows: @normalized_urls.size + 1, 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')
|
||||
%button.btn.btn-secondary{ type: 'submit' }= t('.urls.submit')
|
||||
- if @normalized_urls.present?
|
||||
= line_chart site_stats_uris_path(urls: @normalized_urls, **@chart_params), **@chart_options
|
||||
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
- if @policy.invite?
|
||||
= link_to t('.invite'),
|
||||
site_usuaries_invite_path(@site, invite_as: u.to_s),
|
||||
class: 'btn',
|
||||
class: 'btn btn-secondary',
|
||||
data: { toggle: 'tooltip' },
|
||||
title: t('.help.invite', invite_as: u.to_s)
|
||||
- if policy(Collaboration.new(@site)).collaborate?
|
||||
= link_to t('.public_invite'),
|
||||
site_collaborate_path(@site),
|
||||
class: 'btn',
|
||||
class: 'btn btn-secondary',
|
||||
data: { toggle: 'tooltip' },
|
||||
title: t('.help.public_invite')
|
||||
%p.lead= t(".help.#{u}")
|
||||
|
@ -38,7 +38,7 @@
|
|||
- if @policy.demote? && @site.usuarie?(cuenta)
|
||||
= link_to t('.demote.text'),
|
||||
site_usuarie_demote_path(@site, cuenta),
|
||||
class: 'btn',
|
||||
class: 'btn btn-secondary',
|
||||
data: { toggle: 'tooltip',
|
||||
confirm: t('.demote.confirm') },
|
||||
title: t('.help.demote'),
|
||||
|
@ -46,7 +46,7 @@
|
|||
- if @policy.promote? && @site.invitade?(cuenta)
|
||||
= link_to t('.promote.text'),
|
||||
site_usuarie_promote_path(@site, cuenta),
|
||||
class: 'btn',
|
||||
class: 'btn btn-secondary',
|
||||
data: { toggle: 'tooltip',
|
||||
confirm: t('.promote.confirm') },
|
||||
title: t('.help.promote'),
|
||||
|
@ -54,7 +54,7 @@
|
|||
- if @policy.destroy?
|
||||
= link_to t('.destroy.text'),
|
||||
site_usuarie_path(@site, cuenta),
|
||||
class: 'btn',
|
||||
class: 'btn btn-secondary',
|
||||
data: { toggle: 'tooltip',
|
||||
confirm: t('.destroy.confirm') },
|
||||
title: t('.help.destroy'),
|
||||
|
|
|
@ -13,4 +13,4 @@
|
|||
invite_as: invite_as)
|
||||
= f.text_area :invitaciones, class: 'form-control'
|
||||
.form-group
|
||||
= f.submit t('.submit'), class: 'btn'
|
||||
= f.submit t('.submit'), class: 'btn btn-secondary'
|
||||
|
|
8
bin/modified_files
Executable file
8
bin/modified_files
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
test -n "${CI_MERGE_REQUEST_DIFF_BASE_SHA}"
|
||||
|
||||
git diff --name-status ${CI_MERGE_REQUEST_DIFF_BASE_SHA} \
|
||||
| grep -v "^D" \
|
||||
| cut -f 2
|
4
bin/with_extension
Executable file
4
bin/with_extension
Executable file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
grep "\.${1}$"
|
||||
exit 0
|
|
@ -21,6 +21,17 @@ require 'rails/test_unit/railtie'
|
|||
# you've limited to :test, :development, or :production.
|
||||
Bundler.require(*Rails.groups)
|
||||
|
||||
if %w[development test].include? ENV['RAILS_ENV']
|
||||
# https://github.com/bkeepers/dotenv/pull/453
|
||||
Dotenv::Railtie.class_eval do
|
||||
def overload
|
||||
Dotenv.overload(*dotenv_files.reverse)
|
||||
end
|
||||
end
|
||||
|
||||
Dotenv::Railtie.overload
|
||||
end
|
||||
|
||||
module Sutty
|
||||
# Sutty!
|
||||
class Application < Rails::Application
|
||||
|
|
252
config/brakeman.ignore
Normal file
252
config/brakeman.ignore
Normal file
|
@ -0,0 +1,252 @@
|
|||
{
|
||||
"ignored_warnings": [
|
||||
{
|
||||
"warning_type": "Redirect",
|
||||
"warning_code": 18,
|
||||
"fingerprint": "0ae5c3990d49dfbfd4fd61874451f7a576d5056aca913068adf58c314625f810",
|
||||
"check_name": "Redirect",
|
||||
"message": "Possible unprotected redirect",
|
||||
"file": "app/controllers/api/v1/posts_controller.rb",
|
||||
"line": 20,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
||||
"code": "redirect_to((params[:redirect_to] or origin.to_s))",
|
||||
"render_path": null,
|
||||
"location": {
|
||||
"type": "method",
|
||||
"class": "Api::V1::PostsController",
|
||||
"method": "create"
|
||||
},
|
||||
"user_input": "params[:redirect_to]",
|
||||
"confidence": "High",
|
||||
"cwe_id": [
|
||||
601
|
||||
],
|
||||
"note": "https://0xacab.org/sutty/sutty/-/issues/14957"
|
||||
},
|
||||
{
|
||||
"warning_type": "Denial of Service",
|
||||
"warning_code": 76,
|
||||
"fingerprint": "1947d1a2ae6e4bf718d0cc563e660efca96897165e9a8dd18186c1d7abe6ddf6",
|
||||
"check_name": "RegexDoS",
|
||||
"message": "Model attribute used in regular expression",
|
||||
"file": "app/controllers/api/v1/base_controller.rb",
|
||||
"line": 20,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/denial_of_service/",
|
||||
"code": "/\\.#{Site.domain}\\z/",
|
||||
"render_path": null,
|
||||
"location": {
|
||||
"type": "method",
|
||||
"class": "Api::V1::BaseController",
|
||||
"method": "site_id"
|
||||
},
|
||||
"user_input": "Site.domain",
|
||||
"confidence": "Medium",
|
||||
"cwe_id": [
|
||||
20,
|
||||
185
|
||||
],
|
||||
"note": "No es un atributo, es una variable de entorno"
|
||||
},
|
||||
{
|
||||
"warning_type": "Cross-Site Scripting",
|
||||
"warning_code": 4,
|
||||
"fingerprint": "28d98d08a15c4b3ad94a2cfa20a12573de12d99f1a30b3ca51074ee1f1886592",
|
||||
"check_name": "LinkToHref",
|
||||
"message": "Potentially unsafe model attribute in `link_to` href",
|
||||
"file": "app/views/layouts/_breadcrumb.haml",
|
||||
"line": 19,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
|
||||
"code": "link_to(t(\".tienda\"), Site.find(params[:site_id]).tienda_url, :role => \"button\", :class => \"btn\")",
|
||||
"render_path": [
|
||||
{
|
||||
"type": "controller",
|
||||
"class": "Api::V1::NoticesController",
|
||||
"method": "site",
|
||||
"line": 31,
|
||||
"file": "app/controllers/api/v1/notices_controller.rb",
|
||||
"rendered": {
|
||||
"name": "layouts/application",
|
||||
"file": "app/views/layouts/application.html.haml"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "layouts/application",
|
||||
"line": 25,
|
||||
"file": "app/views/layouts/application.html.haml",
|
||||
"rendered": {
|
||||
"name": "layouts/_breadcrumb",
|
||||
"file": "app/views/layouts/_breadcrumb.haml"
|
||||
}
|
||||
}
|
||||
],
|
||||
"location": {
|
||||
"type": "template",
|
||||
"template": "layouts/_breadcrumb"
|
||||
},
|
||||
"user_input": "Site.find(params[:site_id]).tienda_url",
|
||||
"confidence": "Weak",
|
||||
"cwe_id": [
|
||||
79
|
||||
],
|
||||
"note": ""
|
||||
},
|
||||
{
|
||||
"warning_type": "Redirect",
|
||||
"warning_code": 18,
|
||||
"fingerprint": "5034e51aaa1bac06d15fdde5956edffbfd65f94f5620a409526bbea896dc7b5f",
|
||||
"check_name": "Redirect",
|
||||
"message": "Possible unprotected redirect",
|
||||
"file": "app/controllers/api/v1/contact_controller.rb",
|
||||
"line": 26,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/redirect/",
|
||||
"code": "redirect_to((params[:redirect] or origin.to_s))",
|
||||
"render_path": null,
|
||||
"location": {
|
||||
"type": "method",
|
||||
"class": "Api::V1::ContactController",
|
||||
"method": "receive"
|
||||
},
|
||||
"user_input": "params[:redirect]",
|
||||
"confidence": "High",
|
||||
"cwe_id": [
|
||||
601
|
||||
],
|
||||
"note": "https://0xacab.org/sutty/sutty/-/issues/14957"
|
||||
},
|
||||
{
|
||||
"warning_type": "Mass Assignment",
|
||||
"warning_code": 70,
|
||||
"fingerprint": "50582f39f8dfa900d3f2b5b9908b1592f8b8bd9e2d0b9d1cc05d77e5ede2d94e",
|
||||
"check_name": "MassAssignment",
|
||||
"message": "Specify exact keys allowed for mass assignment instead of using `permit!` which allows any keys",
|
||||
"file": "app/views/layouts/_link_rel_alternate.haml",
|
||||
"line": 2,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
|
||||
"code": "params.permit!",
|
||||
"render_path": [
|
||||
{
|
||||
"type": "controller",
|
||||
"class": "Api::V1::BaseController",
|
||||
"method": "site_id",
|
||||
"line": 20,
|
||||
"file": "app/controllers/api/v1/base_controller.rb",
|
||||
"rendered": {
|
||||
"name": "layouts/application",
|
||||
"file": "app/views/layouts/application.html.haml"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "layouts/application",
|
||||
"line": 21,
|
||||
"file": "app/views/layouts/application.html.haml",
|
||||
"rendered": {
|
||||
"name": "layouts/_link_rel_alternate",
|
||||
"file": "app/views/layouts/_link_rel_alternate.haml"
|
||||
}
|
||||
}
|
||||
],
|
||||
"location": {
|
||||
"type": "template",
|
||||
"template": "layouts/_link_rel_alternate"
|
||||
},
|
||||
"user_input": null,
|
||||
"confidence": "Medium",
|
||||
"cwe_id": [
|
||||
915
|
||||
],
|
||||
"note": "https://0xacab.org/sutty/sutty/-/issues/14958"
|
||||
},
|
||||
{
|
||||
"warning_type": "Mass Assignment",
|
||||
"warning_code": 70,
|
||||
"fingerprint": "b8e0aa898288bebb614ccc1340d169caa196d315c6ac2e4744081cc892c2ae97",
|
||||
"check_name": "MassAssignment",
|
||||
"message": "Specify exact keys allowed for mass assignment instead of using `permit!` which allows any keys",
|
||||
"file": "app/views/layouts/_breadcrumb.haml",
|
||||
"line": 30,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/mass_assignment/",
|
||||
"code": "params.permit!",
|
||||
"render_path": [
|
||||
{
|
||||
"type": "controller",
|
||||
"class": "Api::V1::BaseController",
|
||||
"method": "site_id",
|
||||
"line": 20,
|
||||
"file": "app/controllers/api/v1/base_controller.rb",
|
||||
"rendered": {
|
||||
"name": "layouts/application",
|
||||
"file": "app/views/layouts/application.html.haml"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "layouts/application",
|
||||
"line": 25,
|
||||
"file": "app/views/layouts/application.html.haml",
|
||||
"rendered": {
|
||||
"name": "layouts/_breadcrumb",
|
||||
"file": "app/views/layouts/_breadcrumb.haml"
|
||||
}
|
||||
}
|
||||
],
|
||||
"location": {
|
||||
"type": "template",
|
||||
"template": "layouts/_breadcrumb"
|
||||
},
|
||||
"user_input": null,
|
||||
"confidence": "Medium",
|
||||
"cwe_id": [
|
||||
915
|
||||
],
|
||||
"note": "https://0xacab.org/sutty/sutty/-/issues/14958"
|
||||
},
|
||||
{
|
||||
"warning_type": "Cross-Site Scripting",
|
||||
"warning_code": 4,
|
||||
"fingerprint": "c051421c7cf4c2706b8e27bfd2f3b0661ec6a6df873da322a6b634b59e80351b",
|
||||
"check_name": "LinkToHref",
|
||||
"message": "Potentially unsafe model attribute in `link_to` href",
|
||||
"file": "app/views/sites/_form.haml",
|
||||
"line": 74,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/link_to_href",
|
||||
"code": "link_to(t(\".design.url\"), (Unresolved Model).new.url, :target => \"_blank\", :class => \"btn\")",
|
||||
"render_path": [
|
||||
{
|
||||
"type": "controller",
|
||||
"class": "SitesController",
|
||||
"method": "new",
|
||||
"line": 31,
|
||||
"file": "app/controllers/sites_controller.rb",
|
||||
"rendered": {
|
||||
"name": "sites/new",
|
||||
"file": "app/views/sites/new.haml"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "template",
|
||||
"name": "sites/new",
|
||||
"line": 6,
|
||||
"file": "app/views/sites/new.haml",
|
||||
"rendered": {
|
||||
"name": "sites/_form",
|
||||
"file": "app/views/sites/_form.haml"
|
||||
}
|
||||
}
|
||||
],
|
||||
"location": {
|
||||
"type": "template",
|
||||
"template": "sites/_form"
|
||||
},
|
||||
"user_input": "(Unresolved Model).new.url",
|
||||
"confidence": "Weak",
|
||||
"cwe_id": [
|
||||
79
|
||||
],
|
||||
"note": ""
|
||||
}
|
||||
],
|
||||
"updated": "2024-01-11 18:12:14 -0300",
|
||||
"brakeman_version": "5.4.1"
|
||||
}
|
|
@ -28,9 +28,6 @@ Rails.application.routes.draw do
|
|||
# alias en nginx sin tener que usar expresiones regulares para
|
||||
# detectar el nombre del sitio.
|
||||
get '/sites/private/:site_id(*file)', to: 'private#show', constraints: { site_id: %r{[^/]+} }
|
||||
# Obtener archivos estáticos desde el directorio público
|
||||
get '/sites/:site_id/static_file/(*file)', to: 'sites#static_file', as: 'site_static_file',
|
||||
constraints: { site_id: %r{[^/]+} }
|
||||
get '/env.js', to: 'env#index'
|
||||
|
||||
match '/api/v3/projects/:site_id/notices' => 'api/v1/notices#create', via: %i[post]
|
||||
|
|
|
@ -58,6 +58,35 @@ CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public;
|
|||
COMMENT ON EXTENSION pgcrypto IS 'cryptographic functions';
|
||||
|
||||
|
||||
--
|
||||
-- Name: access_logs_before_insert_row_tr(); Type: FUNCTION; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE FUNCTION public.access_logs_before_insert_row_tr() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
new.created_at := to_timestamp(new.msec);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
--
|
||||
-- Name: indexed_posts_before_insert_update_row_tr(); Type: FUNCTION; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE FUNCTION public.indexed_posts_before_insert_update_row_tr() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
new.indexed_content := to_tsvector(('pg_catalog.' || new.dictionary)::regconfig, coalesce(new.title, '') || '
|
||||
' || coalesce(new.content,''));
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
--
|
||||
-- Name: que_validate_tags(jsonb); Type: FUNCTION; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -117,35 +146,6 @@ WITH (fillfactor='90');
|
|||
COMMENT ON TABLE public.que_jobs IS '7';
|
||||
|
||||
|
||||
--
|
||||
-- Name: access_logs_before_insert_row_tr(); Type: FUNCTION; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE FUNCTION public.access_logs_before_insert_row_tr() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
new.created_at := to_timestamp(new.msec);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
--
|
||||
-- Name: indexed_posts_before_insert_update_row_tr(); Type: FUNCTION; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE FUNCTION public.indexed_posts_before_insert_update_row_tr() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
new.indexed_content := to_tsvector(('pg_catalog.' || new.dictionary)::regconfig, coalesce(new.title, '') || '
|
||||
' || coalesce(new.content,''));
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
|
||||
--
|
||||
-- Name: que_determine_job_state(public.que_jobs); Type: FUNCTION; Schema: public; Owner: -
|
||||
--
|
||||
|
|
|
@ -19,10 +19,10 @@ check program stats
|
|||
every "0 1 * * *"
|
||||
if status != 0 then alert
|
||||
|
||||
check process que with pidfile /srv/tmp/que.pid
|
||||
start program = "/usr/bin/foreman run -f /srv/Procfile -d /srv que"
|
||||
stop program = "/bin/sh -c 'cat /srv/tmp/que.pid | xargs -r kill'"
|
||||
|
||||
check filesystem root with path /
|
||||
if space usage > 80% for 5 times within 15 cycles then alert
|
||||
if space usage > 90% for 5 cycles then exec "/usr/bin/foreman run -f /srv/Procfile -d /srv emergency_cleanup" as uid "rails" gid "www-data"
|
||||
|
||||
check process que with pidfile /srv/tmp/que.pid
|
||||
start program = "/usr/bin/foreman run -f /srv/Procfile -d /srv que"
|
||||
stop program = "/bin/sh -c 'cat /srv/tmp/que.pid | xargs -r kill'"
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
"@rails/actiontext": "^6.0.0",
|
||||
"@rails/activestorage": "^6.1.3-1",
|
||||
"@rails/ujs": "^6.1.3-1",
|
||||
"@rails/webpacker": "5.2.1",
|
||||
"@suttyweb/editor": "^0.1.24",
|
||||
"@rails/webpacker": "5.4.4",
|
||||
"@suttyweb/editor": "^0.1.25",
|
||||
"babel-loader": "^8.2.2",
|
||||
"chart.js": "^3.5.1",
|
||||
"chartkick": "^4.0.5",
|
||||
|
|
BIN
public/assets/.sprockets-manifest-a1cbb907961024fc033716a7d30668dd.json
(Stored with Git LFS)
BIN
public/assets/.sprockets-manifest-a1cbb907961024fc033716a7d30668dd.json
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json
(Stored with Git LFS)
BIN
public/assets/.sprockets-manifest-c6294bb290dcb7473076f4de99ce9c00.json
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js.gz
(Stored with Git LFS)
BIN
public/assets/activestorage-a32231d4c74e0bd4b322c1466c29120152be4ea1f4b896d9bfa546b49c39c52f.js.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/application-ae222afd03002071cf20cb0e57e4f771c70fa5a843d587b8fc6a77a4a5df4ae1.css
(Stored with Git LFS)
BIN
public/assets/application-ae222afd03002071cf20cb0e57e4f771c70fa5a843d587b8fc6a77a4a5df4ae1.css
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/application-ae222afd03002071cf20cb0e57e4f771c70fa5a843d587b8fc6a77a4a5df4ae1.css.gz
(Stored with Git LFS)
BIN
public/assets/application-ae222afd03002071cf20cb0e57e4f771c70fa5a843d587b8fc6a77a4a5df4ae1.css.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/application-e103c526f0f1ddba4b6d570ac1bc4318f0e84d522fe2c02eb6fbb594ece6f7a5.css
(Stored with Git LFS)
Normal file
BIN
public/assets/application-e103c526f0f1ddba4b6d570ac1bc4318f0e84d522fe2c02eb6fbb594ece6f7a5.css
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/assets/application-e103c526f0f1ddba4b6d570ac1bc4318f0e84d522fe2c02eb6fbb594ece6f7a5.css.gz
(Stored with Git LFS)
Normal file
BIN
public/assets/application-e103c526f0f1ddba4b6d570ac1bc4318f0e84d522fe2c02eb6fbb594ece6f7a5.css.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css
(Stored with Git LFS)
Normal file
BIN
public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css.gz
(Stored with Git LFS)
Normal file
BIN
public/assets/application-fe50a06d71e148768669fb4e35c788fc1ac8ba9d94d55ed4292a198004c8dcc5.css.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css.gz
(Stored with Git LFS)
BIN
public/assets/blazer/application-de70452dc5fa2016142132ea36573395d45b4e5c5cf772ef1558462a46996967.css.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js.gz
(Stored with Git LFS)
BIN
public/assets/blazer/application-ec191b6689a395c0fede5f96bcc30a93a832cfbb325d6c50f1c31fffe8f7352b.js.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css.gz
(Stored with Git LFS)
BIN
public/assets/dark-e2d0356b7ccd0cf1af4e1bfd28d32c69caf3f11f464c5b5cef404487f864ae73.css.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/dark-eb9f64ef7c7dac0cb3eb2b7bd511327d12625e00d4e11216441787288070f7dd.css
(Stored with Git LFS)
Normal file
BIN
public/assets/dark-eb9f64ef7c7dac0cb3eb2b7bd511327d12625e00d4e11216441787288070f7dd.css
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/assets/dark-eb9f64ef7c7dac0cb3eb2b7bd511327d12625e00d4e11216441787288070f7dd.css.gz
(Stored with Git LFS)
Normal file
BIN
public/assets/dark-eb9f64ef7c7dac0cb3eb2b7bd511327d12625e00d4e11216441787288070f7dd.css.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css.gz
(Stored with Git LFS)
BIN
public/assets/editor-d0d83345c634efdd987cfc6359297fec136984dd3bd5a2f6bcac2d58459a7aec.css.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js.gz
(Stored with Git LFS)
BIN
public/assets/manifest-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css.gz
(Stored with Git LFS)
BIN
public/assets/new_editor-15587648151a2d95c803f56ceaa2b4333519e99469c673d583c280a9da54b695.css.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/css/application-1224e21e.css
(Stored with Git LFS)
Normal file
BIN
public/packs/css/application-1224e21e.css
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/css/application-1224e21e.css.br
(Stored with Git LFS)
Normal file
BIN
public/packs/css/application-1224e21e.css.br
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/css/application-1224e21e.css.gz
(Stored with Git LFS)
Normal file
BIN
public/packs/css/application-1224e21e.css.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/css/application-7d15ae94.css
(Stored with Git LFS)
BIN
public/packs/css/application-7d15ae94.css
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/css/application-7d15ae94.css.br
(Stored with Git LFS)
BIN
public/packs/css/application-7d15ae94.css.br
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/css/application-7d15ae94.css.br.br
(Stored with Git LFS)
BIN
public/packs/css/application-7d15ae94.css.br.br
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/css/application-7d15ae94.css.gz
(Stored with Git LFS)
BIN
public/packs/css/application-7d15ae94.css.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/css/application-bb1478c7.css
(Stored with Git LFS)
BIN
public/packs/css/application-bb1478c7.css
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/css/application-bb1478c7.css.br
(Stored with Git LFS)
BIN
public/packs/css/application-bb1478c7.css.br
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/css/application-bb1478c7.css.gz
(Stored with Git LFS)
BIN
public/packs/css/application-bb1478c7.css.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js
(Stored with Git LFS)
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.br
(Stored with Git LFS)
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.br
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.gz
(Stored with Git LFS)
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.map
(Stored with Git LFS)
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.map
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.map.br
(Stored with Git LFS)
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.map.br
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.map.gz
(Stored with Git LFS)
BIN
public/packs/js/application-17c8ec1abff8d9ee68fc.js.map.gz
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/js/application-886df482a133d55527f8.js
(Stored with Git LFS)
Normal file
BIN
public/packs/js/application-886df482a133d55527f8.js
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/js/application-886df482a133d55527f8.js.br
(Stored with Git LFS)
Normal file
BIN
public/packs/js/application-886df482a133d55527f8.js.br
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/js/application-886df482a133d55527f8.js.gz
(Stored with Git LFS)
Normal file
BIN
public/packs/js/application-886df482a133d55527f8.js.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/js/application-886df482a133d55527f8.js.map
(Stored with Git LFS)
Normal file
BIN
public/packs/js/application-886df482a133d55527f8.js.map
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/js/application-886df482a133d55527f8.js.map.br
(Stored with Git LFS)
Normal file
BIN
public/packs/js/application-886df482a133d55527f8.js.map.br
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/js/application-886df482a133d55527f8.js.map.gz
(Stored with Git LFS)
Normal file
BIN
public/packs/js/application-886df482a133d55527f8.js.map.gz
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js
(Stored with Git LFS)
BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js
(Stored with Git LFS)
Binary file not shown.
BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt
(Stored with Git LFS)
BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js.LICENSE.txt
(Stored with Git LFS)
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue