5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-15 21:31:42 +00:00

Merge branch 'issue-13780' into issue-12980

This commit is contained in:
f 2023-09-27 16:44:08 -03:00
commit ab5ed0dec9
No known key found for this signature in database
132 changed files with 595 additions and 100 deletions

11
.editorconfig Normal file
View file

@ -0,0 +1,11 @@
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = space
indent_size = 2
[Makefile]
indent_style = tab

View file

@ -20,6 +20,7 @@ pipeline:
branch: branch:
- "rails" - "rails"
- "panel.sutty.nl" - "panel.sutty.nl"
- "17.3.alpine.panel.sutty.nl"
event: "push" event: "push"
path: path:
include: include:
@ -27,7 +28,7 @@ pipeline:
- ".dockerignore" - ".dockerignore"
- ".woodpecker.yml" - ".woodpecker.yml"
assets: assets:
image: "gitea.nulo.in/sutty/panel:${ALPINE_VERSION}-${RUBY_VERSION}.${RUBY_PATCH}" image: "gitea.nulo.in/sutty/panel:3.14.10-2.7.8"
commands: commands:
- "apk add python2 dotenv openssh-client brotli" - "apk add python2 dotenv openssh-client brotli"
- "install -d -m 700 ~/.ssh/" - "install -d -m 700 ~/.ssh/"
@ -51,6 +52,9 @@ pipeline:
- "git add public && git commit -m \"ci: assets [skip ci]\"" - "git add public && git commit -m \"ci: assets [skip ci]\""
- "git pull upstream ${CI_COMMIT_BRANCH}" - "git pull upstream ${CI_COMMIT_BRANCH}"
- "git push upstream ${CI_COMMIT_BRANCH}" - "git push upstream ${CI_COMMIT_BRANCH}"
environment:
- "RUBY_VERSION=${RUBY_VERSION}"
- "GEMS_SOURCE=https://14.3.alpine.gems.sutty.nl"
secrets: secrets:
- "SSH_KEY" - "SSH_KEY"
- "KNOWN_HOSTS" - "KNOWN_HOSTS"
@ -65,8 +69,15 @@ pipeline:
- "app/javascript/**/*" - "app/javascript/**/*"
- "package.json" - "package.json"
- "yarn.lock" - "yarn.lock"
matrix:
ALPINE_VERSION: "3.14.10"
RUBY_VERSION: "2.7"
RUBY_PATCH: "8"
matrix: matrix:
include: include:
- ALPINE_VERSION: "3.17.3"
RUBY_VERSION: "3.1"
RUBY_PATCH: "4"
- ALPINE_VERSION: "3.14.10" - ALPINE_VERSION: "3.14.10"
RUBY_VERSION: "2.7" RUBY_VERSION: "2.7"
RUBY_PATCH: "8" RUBY_PATCH: "8"

14
Gemfile
View file

@ -1,9 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
puts 'Usa haini.sh para generar un entorno de trabajo reproducible' source ENV.fetch('GEMS_SOURCE', 'https://17.3.alpine.gems.sutty.nl')
source 'https://gems.sutty.nl'
ruby '~> 2.7' ruby "~> #{ENV.fetch('RUBY_VERSION', '3.1')}"
gem 'dotenv-rails', require: 'dotenv/rails-now' gem 'dotenv-rails', require: 'dotenv/rails-now'
@ -55,7 +54,7 @@ gem 'httparty'
gem 'safe_yaml', require: false gem 'safe_yaml', require: false
gem 'jekyll', '~> 4.2.0' gem 'jekyll', '~> 4.2.0'
gem 'jekyll-data' gem 'jekyll-data'
gem 'jekyll-commonmark' gem 'jekyll-commonmark', '~> 1.4.0'
gem 'jekyll-images' gem 'jekyll-images'
gem 'jekyll-include-cache' gem 'jekyll-include-cache'
gem 'sutty-liquid', '>= 0.7.3' gem 'sutty-liquid', '>= 0.7.3'
@ -79,6 +78,7 @@ gem 'validates_hostname'
gem 'webpacker' gem 'webpacker'
gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git' gem 'yaml_db', git: 'https://0xacab.org/sutty/yaml_db.git'
gem 'kaminari' gem 'kaminari'
gem 'device_detector'
# database # database
gem 'hairtrigger' gem 'hairtrigger'
@ -120,11 +120,11 @@ group :development do
gem 'brakeman' gem 'brakeman'
gem 'haml-lint', require: false gem 'haml-lint', require: false
gem 'letter_opener' gem 'letter_opener'
gem 'listen', '>= 3.0.5', '< 3.2' gem 'listen'
gem 'rubocop-rails' gem 'rubocop-rails'
gem 'spring' gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0' gem 'spring-watcher-listen'
gem 'web-console', '>= 3.3.0' gem 'web-console'
end end
group :test do group :test do

View file

@ -25,7 +25,7 @@ GIT
groupdate (>= 5.2) groupdate (>= 5.2)
GEM GEM
remote: https://gems.sutty.nl/ remote: https://17.3.alpine.gems.sutty.nl/
specs: specs:
actioncable (6.1.7.3) actioncable (6.1.7.3)
actionpack (= 6.1.7.3) actionpack (= 6.1.7.3)
@ -91,11 +91,9 @@ GEM
ast (2.4.2) ast (2.4.2)
autoprefixer-rails (10.4.13.0) autoprefixer-rails (10.4.13.0)
execjs (~> 2) execjs (~> 2)
bcrypt (3.1.18-x86_64-linux-musl) bcrypt (3.1.19-x86_64-linux-musl)
bcrypt_pbkdf (1.1.0)
bcrypt_pbkdf (1.1.0-x86_64-linux-musl) bcrypt_pbkdf (1.1.0-x86_64-linux-musl)
benchmark-ips (2.12.0) benchmark-ips (2.12.0)
bindex (0.8.1)
bindex (0.8.1-x86_64-linux-musl) bindex (0.8.1-x86_64-linux-musl)
blazer (2.6.5) blazer (2.6.5)
activerecord (>= 5) activerecord (>= 5)
@ -119,8 +117,7 @@ GEM
climate_control (1.2.0) climate_control (1.2.0)
coderay (1.1.3) coderay (1.1.3)
colorator (1.1.0) colorator (1.1.0)
commonmarker (0.23.9) commonmarker (0.23.10-x86_64-linux-musl)
commonmarker (0.23.9-x86_64-linux-musl)
concurrent-ruby (1.2.2) concurrent-ruby (1.2.2)
concurrent-ruby-ext (1.2.2-x86_64-linux-musl) concurrent-ruby-ext (1.2.2-x86_64-linux-musl)
concurrent-ruby (= 1.2.2) concurrent-ruby (= 1.2.2)
@ -131,7 +128,6 @@ GEM
activerecord (>= 5.a) activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0) database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1) database_cleaner-core (2.0.1)
date (3.3.3)
date (3.3.3-x86_64-linux-musl) date (3.3.3-x86_64-linux-musl)
dead_end (4.0.0) dead_end (4.0.0)
derailed_benchmarks (2.1.2) derailed_benchmarks (2.1.2)
@ -146,6 +142,7 @@ GEM
rake (> 10, < 14) rake (> 10, < 14)
ruby-statistics (>= 2.1) ruby-statistics (>= 2.1)
thor (>= 0.19, < 2) thor (>= 0.19, < 2)
device_detector (1.1.1)
devise (4.9.2) devise (4.9.2)
bcrypt (~> 3.0) bcrypt (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
@ -154,7 +151,7 @@ GEM
warden (~> 1.2.3) warden (~> 1.2.3)
devise-i18n (1.11.0) devise-i18n (1.11.0)
devise (>= 4.9.0) devise (>= 4.9.0)
devise_invitable (2.0.7) devise_invitable (2.0.8)
actionmailer (>= 5.0) actionmailer (>= 5.0)
devise (>= 4.6) devise (>= 4.6)
distributed-press-api-client (0.2.4) distributed-press-api-client (0.2.4)
@ -196,14 +193,12 @@ GEM
dry-inflector (~> 1.0) dry-inflector (~> 1.0)
dry-logic (~> 1.4) dry-logic (~> 1.4)
zeitwerk (~> 2.6) zeitwerk (~> 2.6)
ed25519 (1.3.0)
ed25519 (1.3.0-x86_64-linux-musl) ed25519 (1.3.0-x86_64-linux-musl)
em-websocket (0.5.3) em-websocket (0.5.3)
eventmachine (>= 0.12.9) eventmachine (>= 0.12.9)
http_parser.rb (~> 0) http_parser.rb (~> 0)
errbase (0.2.2) errbase (0.2.2)
erubi (1.12.0) erubi (1.12.0)
eventmachine (1.2.7)
eventmachine (1.2.7-x86_64-linux-musl) eventmachine (1.2.7-x86_64-linux-musl)
exception_notification (4.5.0) exception_notification (4.5.0)
actionmailer (>= 5.2, < 8) actionmailer (>= 5.2, < 8)
@ -214,11 +209,8 @@ GEM
factory_bot_rails (6.2.0) factory_bot_rails (6.2.0)
factory_bot (~> 6.2.0) factory_bot (~> 6.2.0)
railties (>= 5.0.0) railties (>= 5.0.0)
fast_blank (1.0.1)
fast_blank (1.0.1-x86_64-linux-musl) fast_blank (1.0.1-x86_64-linux-musl)
fast_jsonparser (0.5.0)
fast_jsonparser (0.5.0-x86_64-linux-musl) fast_jsonparser (0.5.0-x86_64-linux-musl)
ffi (1.15.5)
ffi (1.15.5-x86_64-linux-musl) ffi (1.15.5-x86_64-linux-musl)
flamegraph (0.9.5) flamegraph (0.9.5)
forwardable-extended (2.6.0) forwardable-extended (2.6.0)
@ -234,7 +226,7 @@ GEM
activerecord (>= 6.0, < 8) activerecord (>= 6.0, < 8)
ruby2ruby (~> 2.4) ruby2ruby (~> 2.4)
ruby_parser (~> 3.10) ruby_parser (~> 3.10)
haml (6.1.1-x86_64-linux-musl) haml (6.1.2-x86_64-linux-musl)
temple (>= 0.8.2) temple (>= 0.8.2)
thor thor
tilt tilt
@ -246,10 +238,6 @@ GEM
rainbow rainbow
rubocop (>= 0.50.0) rubocop (>= 0.50.0)
sysexits (~> 1.1) sysexits (~> 1.1)
hamlit (3.0.3)
temple (>= 0.8.2)
thor
tilt
hamlit (3.0.3-x86_64-linux-musl) hamlit (3.0.3-x86_64-linux-musl)
temple (>= 0.8.2) temple (>= 0.8.2)
thor thor
@ -261,14 +249,12 @@ GEM
railties (>= 4.0.1) railties (>= 4.0.1)
heapy (0.2.0) heapy (0.2.0)
thor thor
hiredis (0.6.3)
hiredis (0.6.3-x86_64-linux-musl) hiredis (0.6.3-x86_64-linux-musl)
http_parser.rb (0.8.0)
http_parser.rb (0.8.0-x86_64-linux-musl) http_parser.rb (0.8.0-x86_64-linux-musl)
httparty (0.21.0) httparty (0.21.0)
mini_mime (>= 1.0.0) mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
i18n (1.13.0) i18n (1.14.1)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
icalendar (2.8.0) icalendar (2.8.0)
ice_cube (~> 0.16) ice_cube (~> 0.16)
@ -334,10 +320,9 @@ GEM
letter_opener (1.8.1) letter_opener (1.8.1)
launchy (>= 2.2, < 3) launchy (>= 2.2, < 3)
liquid (4.0.4) liquid (4.0.4)
listen (3.1.5) listen (3.8.0)
rb-fsevent (~> 0.9, >= 0.9.4) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.7) rb-inotify (~> 0.9, >= 0.9.10)
ruby_dep (~> 1.2)
loaf (0.10.0) loaf (0.10.0)
railties (>= 3.2) railties (>= 3.2)
lockbox (1.2.0) lockbox (1.2.0)
@ -361,6 +346,7 @@ GEM
mini_histogram (0.3.1) mini_histogram (0.3.1)
mini_magick (4.12.0) mini_magick (4.12.0)
mini_mime (1.1.2) mini_mime (1.1.2)
mini_portile2 (2.8.2)
minitest (5.18.0) minitest (5.18.0)
mobility (1.2.9) mobility (1.2.9)
i18n (>= 0.6.10, < 2) i18n (>= 0.6.10, < 2)
@ -381,7 +367,8 @@ GEM
njalla-api-client (0.2.0) njalla-api-client (0.2.0)
dry-schema dry-schema
httparty (~> 0.18) httparty (~> 0.18)
nokogiri (1.15.1-x86_64-linux) nokogiri (1.15.4-x86_64-linux-musl)
mini_portile2 (~> 2.8.2)
racc (~> 1.4) racc (~> 1.4)
orm_adapter (0.5.0) orm_adapter (0.5.0)
pairing_heap (3.0.1) pairing_heap (3.0.1)
@ -400,14 +387,13 @@ GEM
pry (0.14.2) pry (0.14.2)
coderay (~> 1.1) coderay (~> 1.1)
method_source (~> 1.0) method_source (~> 1.0)
public_suffix (5.0.1) public_suffix (5.0.3)
puma (6.2.2-x86_64-linux-musl) puma (6.3.1-x86_64-linux-musl)
nio4r (~> 2.0) nio4r (~> 2.0)
pundit (2.3.0) pundit (2.3.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
que (2.2.1) que (2.2.1)
racc (1.6.2) racc (1.7.1-x86_64-linux-musl)
racc (1.6.2-x86_64-linux-musl)
rack (2.2.7) rack (2.2.7)
rack-cors (2.0.1) rack-cors (2.0.1)
rack (>= 2.0.0) rack (>= 2.0.0)
@ -498,7 +484,6 @@ GEM
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
rack (>= 1.1) rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0) rubocop (>= 1.33.0, < 2.0)
ruby-filemagic (0.7.3)
ruby-filemagic (0.7.3-x86_64-linux-musl) ruby-filemagic (0.7.3-x86_64-linux-musl)
ruby-progressbar (1.13.0) ruby-progressbar (1.13.0)
ruby-statistics (3.0.2) ruby-statistics (3.0.2)
@ -507,17 +492,13 @@ GEM
ruby2ruby (2.5.0) ruby2ruby (2.5.0)
ruby_parser (~> 3.1) ruby_parser (~> 3.1)
sexp_processor (~> 4.6) sexp_processor (~> 4.6)
ruby_dep (1.5.0)
ruby_parser (3.20.1) ruby_parser (3.20.1)
sexp_processor (~> 4.16) sexp_processor (~> 4.16)
rubyzip (2.3.2) rubyzip (2.3.2)
rugged (1.6.3)
rugged (1.6.3-x86_64-linux-musl) rugged (1.6.3-x86_64-linux-musl)
safe_yaml (1.0.6) safe_yaml (1.0.6)
safely_block (0.3.0) safely_block (0.3.0)
errbase (>= 0.1.1) errbase (>= 0.1.1)
sassc (2.4.0)
ffi (~> 1.9)
sassc (2.4.0-x86_64-linux-musl) sassc (2.4.0-x86_64-linux-musl)
ffi (~> 1.9) ffi (~> 1.9)
sassc-rails (2.1.2) sassc-rails (2.1.2)
@ -535,10 +516,10 @@ GEM
simpleidn (0.2.1) simpleidn (0.2.1)
unf (~> 0.1.4) unf (~> 0.1.4)
sourcemap (0.1.1) sourcemap (0.1.1)
spring (2.1.1) spring (4.1.1)
spring-watcher-listen (2.0.1) spring-watcher-listen (2.1.0)
listen (>= 2.7, < 4.0) listen (>= 2.7, < 4.0)
spring (>= 1.2, < 3.0) spring (>= 4)
sprockets (4.2.0) sprockets (4.2.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (>= 2.2.4, < 4) rack (>= 2.2.4, < 4)
@ -546,10 +527,11 @@ GEM
actionpack (>= 5.2) actionpack (>= 5.2)
activesupport (>= 5.2) activesupport (>= 5.2)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sqlite3 (1.6.3-x86_64-linux) sqlite3 (1.6.3-x86_64-linux-musl)
mini_portile2 (~> 2.8.0)
stackprof (0.2.25-x86_64-linux-musl) stackprof (0.2.25-x86_64-linux-musl)
stream (0.5.5) stream (0.5.5)
sutty-liquid (0.11.10) sutty-liquid (0.11.11)
fast_blank (~> 1.0) fast_blank (~> 1.0)
jekyll (~> 4) jekyll (~> 4)
symbol-fstring (1.0.2-x86_64-linux-musl) symbol-fstring (1.0.2-x86_64-linux-musl)
@ -589,7 +571,7 @@ GEM
semantic_range (>= 2.3.0) semantic_range (>= 2.3.0)
webrick (1.8.1) webrick (1.8.1)
websocket (1.2.9) websocket (1.2.9)
websocket-driver (0.7.5-x86_64-linux-musl) websocket-driver (0.7.6-x86_64-linux-musl)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5) websocket-extensions (0.1.5)
xpath (3.2.0) xpath (3.2.0)
@ -597,7 +579,6 @@ GEM
zeitwerk (2.6.8) zeitwerk (2.6.8)
PLATFORMS PLATFORMS
ruby
x86_64-linux-musl x86_64-linux-musl
DEPENDENCIES DEPENDENCIES
@ -612,6 +593,7 @@ DEPENDENCIES
concurrent-ruby-ext concurrent-ruby-ext
database_cleaner database_cleaner
derailed_benchmarks derailed_benchmarks
device_detector
devise devise
devise-i18n devise-i18n
devise_invitable devise_invitable
@ -636,13 +618,13 @@ DEPENDENCIES
inline_svg inline_svg
jbuilder (~> 2.5) jbuilder (~> 2.5)
jekyll (~> 4.2.0) jekyll (~> 4.2.0)
jekyll-commonmark jekyll-commonmark (~> 1.4.0)
jekyll-data jekyll-data
jekyll-images jekyll-images
jekyll-include-cache jekyll-include-cache
kaminari kaminari
letter_opener letter_opener
listen (>= 3.0.5, < 3.2) listen
loaf loaf
lockbox lockbox
lograge lograge
@ -677,7 +659,7 @@ DEPENDENCIES
selenium-webdriver (~> 4.8.0) selenium-webdriver (~> 4.8.0)
sourcemap sourcemap
spring spring
spring-watcher-listen (~> 2.0.0) spring-watcher-listen
sqlite3 sqlite3
stackprof stackprof
sutty-liquid (>= 0.7.3) sutty-liquid (>= 0.7.3)
@ -687,12 +669,12 @@ DEPENDENCIES
turbolinks (~> 5) turbolinks (~> 5)
uglifier (>= 1.3.0) uglifier (>= 1.3.0)
validates_hostname validates_hostname
web-console (>= 3.3.0) web-console
webpacker webpacker
yaml_db! yaml_db!
RUBY VERSION RUBY VERSION
ruby 2.7.1p83 ruby 3.1.4p223
BUNDLED WITH BUNDLED WITH
2.2.20 2.4.17

View file

@ -525,5 +525,3 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1);
} }
} }
} }
// force ci

View file

@ -10,7 +10,7 @@ module Api
# solo si la API key es verificable. Del otro lado siempre # solo si la API key es verificable. Del otro lado siempre
# respondemos con lo mismo. # respondemos con lo mismo.
def create def create
if site&.airbrake_valid? airbrake_token if (site&.airbrake_valid? airbrake_token) && !detected_device.bot?
BacktraceJob.perform_later site_id: params[:site_id], BacktraceJob.perform_later site_id: params[:site_id],
params: airbrake_params.to_h params: airbrake_params.to_h
end end
@ -34,6 +34,11 @@ module Api
def airbrake_token def airbrake_token
@airbrake_token ||= params[:key] @airbrake_token ||= params[:key]
end end
# @return [DeviceDetector]
def detected_device
@detected_device ||= DeviceDetector.new(request.headers['User-Agent'], request.headers)
end
end end
end end
end end

View file

@ -2,11 +2,21 @@
import { Notifier } from '@airbrake/browser' import { Notifier } from '@airbrake/browser'
window.airbrake = new Notifier({ try {
projectId: window.env.AIRBRAKE_SITE_ID, window.airbrake = new Notifier({
projectKey: window.env.AIRBRAKE_API_KEY, projectId: window.env.AIRBRAKE_PROJECT_ID,
projectKey: window.env.AIRBRAKE_PROJECT_KEY,
host: window.env.PANEL_URL host: window.env.PANEL_URL
}) });
console.originalError = console.error;
console.error = (...e) => {
window.airbrake.notify(e.join(" "));
return console.originalError(...e);
};
} catch(e) {
console.error(e);
}
import 'core-js/stable' import 'core-js/stable'
import 'regenerator-runtime/runtime' import 'regenerator-runtime/runtime'

View file

@ -8,9 +8,9 @@ module ExceptionNotifier
# Recibe la excepción y empieza la tarea de notificación en segundo # Recibe la excepción y empieza la tarea de notificación en segundo
# plano. # plano.
# #
# @param [Exception] # @param :exception [Exception]
# @param [Hash] # @param :options [Hash]
def call(exception, **options) def call(exception, options, &block)
case exception case exception
when BacktraceJob::BacktraceException when BacktraceJob::BacktraceException
GitlabNotifierJob.perform_later(exception, **options) GitlabNotifierJob.perform_later(exception, **options)

View file

@ -37,7 +37,7 @@ class Site
author = GitAuthor.new email: "sutty@#{Site.domain}", name: 'Sutty' author = GitAuthor.new email: "sutty@#{Site.domain}", name: 'Sutty'
repository.commit(file: modified, repository.commit(add: modified,
message: I18n.t('sites.find_and_replace'), message: I18n.t('sites.find_and_replace'),
usuarie: author) usuarie: author)
end end

View file

@ -1,9 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
# Indexa todos los artículos de un sitio
#
# TODO: Hacer opcional
class Site class Site
# Indexa todos los artículos de un sitio
#
# TODO: Hacer opcional
module Index module Index
extend ActiveSupport::Concern extend ActiveSupport::Concern
@ -12,11 +12,113 @@ class Site
after_create :index_posts! after_create :index_posts!
has_many :indexed_posts, dependent: :destroy has_many :indexed_posts, dependent: :destroy
MODIFIED_STATUSES = %i[added modified].freeze
DELETED_STATUSES = %i[deleted].freeze
LOCALE_FROM_PATH = /\A_/.freeze
def index_posts! def index_posts!
Site.transaction do Site.transaction do
docs.each(&:index!) docs.each(&:index!)
update(last_indexed_commit: repository.head_commit.oid)
end end
end end
# Encuentra los artículos modificados entre dos commits y los
# reindexa.
def reindex_changes!
return unless reindexable?
Site.transaction do
remove_deleted_posts!
reindex_modified_posts!
update(last_indexed_commit: repository.head_commit.oid)
end
end
# No hacer nada si el repositorio no cambió o no hubo cambios
# necesarios
def reindexable?
return false if last_indexed_commit.blank?
return false if last_indexed_commit == repository.head_commit.oid
!indexable_posts.empty?
end
private
# Trae el último commit indexado desde el repositorio
#
# @return [Rugged::Commit]
def indexed_commit
@indexed_commit ||= repository.rugged.lookup(last_indexed_commit)
end
# Calcula la diferencia entre el último commit indexado y el
# actual
#
# XXX: Esto no tiene en cuenta modificaciones en la historia como
# cambio de ramas, reverts y etc, solo asume que se mueve hacia
# adelante en la misma rama o las dos ramas están relacionadas.
#
# @return [Rugged::Diff]
def diff_with_head
@diff_with_head ||= indexed_commit.diff(repository.head_commit)
end
# Obtiene todos los archivos a reindexar
#
# @return [Array<Rugged::Delta>]
def indexable_posts
@indexable_posts ||=
diff_with_head.each_delta.select do |delta|
locales.any? do |locale|
delta.old_file[:path].start_with? "_#{locale}/"
end
end
end
# Elimina los artículos eliminados o que cambiaron de ubicación
# del índice
def remove_deleted_posts!
indexable_posts.select do |delta|
DELETED_STATUSES.include? delta.status
end.each do |delta|
locale, path = locale_and_path_from(delta.old_file[:path])
indexed_posts.destroy_by(locale: locale, path: path).tap do |destroyed_posts|
next unless destroyed_posts.empty?
Rails.logger.info I18n.t('indexed_posts.deleted', site: name, path: path, records: destroyed_posts.count)
end
end
end
# Reindexa artículos que cambiaron de ubicación, se agregaron
# o fueron modificados
def reindex_modified_posts!
indexable_posts.select do |delta|
MODIFIED_STATUSES.include? delta.status
end.each do |delta|
locale, path = locale_and_path_from(delta.new_file[:path])
posts(lang: locale).find(path).index!
end
end
# Obtiene el idioma y la ruta del post a partir de la ubicación en
# el disco
#
# @return [Array<String>]
def locale_and_path_from(path)
locale, path = path.split(File::SEPARATOR, 2)
[
locale.sub(LOCALE_FROM_PATH, ''),
File.basename(path, '.*')
]
end
end end
end end
end end

View file

@ -118,14 +118,21 @@ class Site
end end
# Guarda los cambios en git # Guarda los cambios en git
def commit(file:, usuarie:, message:, remove: false) #
file = [file] unless file.respond_to? :each # @param :add [Array] Archivos a agregar
# @param :rm [Array] Archivos a eliminar
# @param :usuarie [Usuarie] Quién hace el commit
# @param :message [String] Mensaje
def commit(add: [], rm: [], usuarie:, message:)
# Cargar el árbol actual # Cargar el árbol actual
rugged.index.read_tree rugged.head.target.tree rugged.index.read_tree rugged.head.target.tree
file.each do |f| add.each do |file|
remove ? rm(f) : add(f) rugged.index.add(relativize(file))
end
rm.each do |file|
rugged.index.remove(relativize(file))
end end
# Escribir los cambios para que el repositorio se vea tal cual # Escribir los cambios para que el repositorio se vea tal cual
@ -146,14 +153,6 @@ class Site
{ name: 'Sutty', email: "sutty@#{Site.domain}", time: Time.now } { name: 'Sutty', email: "sutty@#{Site.domain}", time: Time.now }
end end
def add(file)
rugged.index.add(relativize(file))
end
def rm(file)
rugged.index.remove(relativize(file))
end
# Garbage collection # Garbage collection
# #
# @return [Boolean] # @return [Boolean]

View file

@ -22,7 +22,7 @@ class LfsObjectService
Site::Writer.new(site: site, file: path, content: pointer).save Site::Writer.new(site: site, file: path, content: pointer).save
# Commitear el pointer # Commitear el pointer
site.repository.commit(file: path, usuarie: author, message: File.basename(path)) site.repository.commit(add: [path], usuarie: author, message: File.basename(path))
# Eliminar el pointer # Eliminar el pointer
FileUtils.rm(path) FileUtils.rm(path)

View file

@ -16,7 +16,7 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
post.slug.value = p[:slug] if p[:slug].present? post.slug.value = p[:slug] if p[:slug].present?
end end
commit(action: :created, file: update_related_posts) if post.update(post_params) commit(action: :created, add: update_related_posts) if post.update(post_params)
update_site_license! update_site_license!
@ -34,7 +34,7 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
# Los artículos anónimos siempre son borradores # Los artículos anónimos siempre son borradores
params[:draft] = true params[:draft] = true
commit(action: :created) if post.update(anon_post_params) commit(action: :created, add: [post.path.absolute]) if post.update(anon_post_params)
post post
end end
@ -42,11 +42,17 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
post.usuaries << usuarie post.usuaries << usuarie
params[:post][:draft] = true if site.invitade? usuarie params[:post][:draft] = true if site.invitade? usuarie
# Eliminar ("mover") el archivo si cambió de ubicación.
if post.update(post_params)
rm = []
rm << post.path.value_was if post.path.changed?
# Es importante que el artículo se guarde primero y luego los # Es importante que el artículo se guarde primero y luego los
# relacionados. # relacionados.
commit(action: :updated, file: update_related_posts) if post.update(post_params) commit(action: :updated, add: update_related_posts, rm: rm)
update_site_license! update_site_license!
end
# Devolver el post aunque no se haya salvado para poder rescatar los # Devolver el post aunque no se haya salvado para poder rescatar los
# errores # errores
@ -56,7 +62,7 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
def destroy def destroy
post.destroy! post.destroy!
commit(action: :destroyed) if post.destroyed? commit(action: :destroyed, rm: [post.path.absolute]) if post.destroyed?
post post
end end
@ -85,15 +91,15 @@ PostService = Struct.new(:site, :usuarie, :post, :params, keyword_init: true) do
# TODO: Implementar transacciones! # TODO: Implementar transacciones!
posts.save_all(validate: false) && posts.save_all(validate: false) &&
commit(action: :reorder, file: files) commit(action: :reorder, add: files)
end end
private private
def commit(action:, file: nil) def commit(action:, add: [], rm: [])
site.repository.commit(file: file || post.path.absolute, site.repository.commit(add: add,
rm: rm,
usuarie: usuarie, usuarie: usuarie,
remove: action == :destroyed,
message: I18n.t("post_service.#{action}", message: I18n.t("post_service.#{action}",
title: post&.title&.value)) title: post&.title&.value))
end end

View file

@ -94,7 +94,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do
def commit_config(action:) def commit_config(action:)
site.repository site.repository
.commit(usuarie: usuarie, .commit(usuarie: usuarie,
file: site.config.path, add: [site.config.path],
message: I18n.t("site_service.#{action}", message: I18n.t("site_service.#{action}",
name: site.name)) name: site.name))
end end

View file

@ -0,0 +1,3 @@
DeviceDetector.configure do |config|
config.max_cache_keys = 5_000 # to check if not too much
end

View file

@ -4,5 +4,5 @@ ActiveJob::Serializers.add_serializers ActiveJob::Serializers::ExceptionSerializ
# Notificar los errores # Notificar los errores
Que.error_notifier = proc do |error, job| Que.error_notifier = proc do |error, job|
ExceptionNotifier.notify_exception(error, data: (job || {})) ExceptionNotifier.notify_exception(error, data: (job.dup || {}))
end end

View file

@ -167,6 +167,7 @@ en:
usuarie: User usuarie: User
licencia: License licencia: License
design: Design design: Design
indexed_post: Indexed post
attributes: attributes:
usuarie: usuarie:
email: 'E-mail address' email: 'E-mail address'
@ -709,3 +710,5 @@ en:
build_stats: build_stats:
index: index:
title: "Publications" title: "Publications"
indexed_posts:
deleted: "Deleted indexed post %{path} from %{site} (records: %{records})"

View file

@ -167,6 +167,7 @@ es:
usuarie: Usuarie usuarie: Usuarie
licencia: Licencia licencia: Licencia
design: Diseño design: Diseño
indexed_post: Artículo indexado
attributes: attributes:
usuarie: usuarie:
email: 'Correo electrónico' email: 'Correo electrónico'
@ -717,3 +718,5 @@ es:
build_stats: build_stats:
index: index:
title: "Publicaciones" title: "Publicaciones"
indexed_posts:
deleted: "Eliminado artículo %{path} de %{site} (filas: %{records})"

View file

@ -0,0 +1,18 @@
# frozen_string_literal: true
# Almacenar el último commit indexado
class AddLastIndexedCommitToSites < ActiveRecord::Migration[6.1]
def up
add_column :sites, :last_indexed_commit, :string, null: true
Site.find_each do |site|
site.update_columns(last_indexed_commit: site.repository.head_commit.oid)
rescue Rugged::Error, Rugged::OSError => e
puts "Falló #{site.name}, ignorando: #{e.message}"
end
end
def down
remove_column :sites, :last_indexed_commit
end
end

View file

@ -75,6 +75,14 @@
credits_en: 'This template was made in collaboration with Librenauta in 15 hours!' credits_en: 'This template was made in collaboration with Librenauta in 15 hours!'
designer_url: 'https://copiona.com/donaunbit/' designer_url: 'https://copiona.com/donaunbit/'
priority: '70' priority: '70'
- name_en: 'Magazine'
name_es: 'Revista'
gem: 'compost-jekyll-theme'
url: 'https://two.compost.digital/'
description_en: 'A theme to create multimedia publications, based in COMPOST magazine'
description_es: 'Plantilla para crear publicaciones multimedia, basada en COMPOST magazine'
license: 'https://0xacab.org/sutty/jekyll/compost-jekyll-theme/-/blob/no-masters/LICENSE.txt'
priority: '40'
- name_en: 'Resource toolkit' - name_en: 'Resource toolkit'
name_es: 'Recursero' name_es: 'Recursero'
gem: 'recursero-jekyll-theme' gem: 'recursero-jekyll-theme'

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/packs/css/application-7d15ae94.css (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/packs/css/application-7d15ae94.css.br (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/packs/css/application-7d15ae94.css.br.br (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/packs/css/application-7d15ae94.css.gz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js.br.br (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js.gz (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map (Stored with Git LFS) Normal file

Binary file not shown.

BIN
public/packs/js/application-fd20cd4c95f90c1a3ecd.js.map.br (Stored with Git LFS) Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more