diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 0f848946..61349081 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -386,6 +386,9 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); } } +.word-break-all { word-break: break-all !important; } +.hyphens { hyphens: auto; } + /* * Modificadores de Bootstrap que no tienen versión responsive. */ @@ -408,6 +411,8 @@ $bezier: cubic-bezier(0.75, 0, 0.25, 1); .text-#{$grid-breakpoint}-right { text-align: right !important; } .text-#{$grid-breakpoint}-center { text-align: center !important; } + .word-break-#{$grid-breakpoint}-all { word-break: break-all !important; } + // posición @each $position in $positions { .position-#{$grid-breakpoint}-#{$position} { position: $position !important; } diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b4be5a97..ee153394 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -91,6 +91,10 @@ class ApplicationController < ActionController::Base breadcrumb 'stats.index', root_path, match: :exact end + def site + @site ||= find_site + end + protected def configure_permitted_parameters diff --git a/app/controllers/build_stats_controller.rb b/app/controllers/build_stats_controller.rb new file mode 100644 index 00000000..31a4c5d6 --- /dev/null +++ b/app/controllers/build_stats_controller.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# La lista de estados de compilación, por ahora solo mostramos el último +# estado. +class BuildStatsController < ApplicationController + include ActionView::Helpers::NumberHelper + include ActionView::Helpers::DateHelper + + before_action :authenticate_usuarie! + + breadcrumb -> { current_usuarie.email }, :edit_usuarie_registration_path + breadcrumb 'sites.index', :sites_path, match: :exact + breadcrumb -> { site.title }, -> { site_posts_path(site, locale: locale) }, match: :exact + + def index + authorize SiteBuildStat.new(site) + breadcrumb I18n.t('build_stats.index.title'), '' + + @headers = %w[type url seconds size].map do |header| + t("deploy_mailer.deployed.th.#{header}") + end + + @table = site.deployment_list.map do |deploy| + type = deploy.class.name.underscore + urls = deploy.respond_to?(:urls) ? deploy.urls : [deploy.url].compact + urls = [nil] if urls.empty? + build_stat = deploy.build_stats.where(status: true).last + seconds = build_stat&.seconds || 0 + + { + title: t("deploy_mailer.deployed.#{type}.title"), + urls: urls, + seconds: { + human: distance_of_time_in_words(seconds), + machine: "PT#{seconds}S" + }, + size: number_to_human_size(build_stat&.bytes || 0, precision: 2) + } + end + end +end diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 3c529c24..9720fe13 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -159,10 +159,6 @@ class PostsController < ApplicationController end.transform_keys(&:to_sym) end - def site - @site ||= find_site - end - def post @post ||= site.posts(lang: locale).find(params[:post_id] || params[:id]) end diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index 9e9cac71..6924c860 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -96,6 +96,13 @@ class UsuariesController < ApplicationController # XXX: La invitación tiene que ser enviada luego de crear el rol if role.persisted? + # Si es una cuenta manual que no está confirmada aun, + # aprovechar para reconfirmarla. + if !usuarie.confirmed? && !usuarie.created_by_invite? + usuarie.confirmation_token = nil + usuarie.send :generate_confirmation_token! + end + usuarie.deliver_invitation else raise ArgumentError, role.errors.full_messages diff --git a/app/jobs/renew_distributed_press_tokens_job.rb b/app/jobs/renew_distributed_press_tokens_job.rb index 5664d9fa..86086ac7 100644 --- a/app/jobs/renew_distributed_press_tokens_job.rb +++ b/app/jobs/renew_distributed_press_tokens_job.rb @@ -7,7 +7,7 @@ class RenewDistributedPressTokensJob < ApplicationJob # detener la tarea si algo pasa. def perform DistributedPressPublisher.with_about_to_expire_tokens.find_each do |publisher| - publisher.touch + publisher.save rescue DistributedPress::V1::Error => e data = { instance: publisher.instance, expires_at: publisher.client.token.expires_at } diff --git a/app/models/deploy_distributed_press.rb b/app/models/deploy_distributed_press.rb index 32a3049e..889d8e34 100644 --- a/app/models/deploy_distributed_press.rb +++ b/app/models/deploy_distributed_press.rb @@ -80,25 +80,18 @@ class DeployDistributedPress < Deploy # Devuelve las URLs de todos los protocolos def urls - protocol_urls + gateway_urls + gateway_urls end private + # @return [Array] def gateway_urls - remote_info.dig(:distributed_press, :links).values.map do |protocol| + remote_info.dig(:distributed_press, :links)&.values&.map do |protocol| [ protocol[:link], protocol[:gateway] ] - end.flatten.compact.select do |link| + end&.flatten&.compact&.select do |link| link.include? '://' - end - end - - def protocol_urls - remote_info.dig(:distributed_press, :protocols).select do |_, enabled| - enabled - end.map do |protocol, _| - "#{protocol}://#{site.hostname}" - end + end || [] end # El cliente de la API diff --git a/app/models/deploy_full_rsync.rb b/app/models/deploy_full_rsync.rb index b8c48eab..b417470a 100644 --- a/app/models/deploy_full_rsync.rb +++ b/app/models/deploy_full_rsync.rb @@ -27,8 +27,4 @@ class DeployFullRsync < DeployRsync result.present? && result.all? end - - def url - "https://#{user_host.last}/" - end end diff --git a/app/models/deploy_rsync.rb b/app/models/deploy_rsync.rb index 1dff2d99..fcc5a65d 100644 --- a/app/models/deploy_rsync.rb +++ b/app/models/deploy_rsync.rb @@ -38,6 +38,7 @@ class DeployRsync < Deploy # # @return [Boolean] def ssh? + return true if destination.start_with? 'rsync://' user, host = user_host ssh_available = false diff --git a/app/models/site/build_stats.rb b/app/models/site/build_stats.rb index 6eebcc84..071b1eab 100644 --- a/app/models/site/build_stats.rb +++ b/app/models/site/build_stats.rb @@ -40,6 +40,72 @@ class Site def not_published_yet? build_stats.jekyll.where(status: true).count.zero? end + + # Cambios posibles luego de la última publicación exitosa: + # + # * Artículos modificados + # * Configuración modificada + # * Métodos de publicación añadidos + # + # @return [Boolean] + def awaiting_publication? + waiting? && (post_pending? || deploy_pending? || configuration_pending?) + end + + # Se modificaron artículos después de publicar el sitio por última + # vez + # + # @return [Boolean] + def post_pending? + last_indexed_post_time > last_publication_time + end + + # Se modificó el sitio después de publicarlo por última vez + # + # @return [Boolean] + def deploy_pending? + last_deploy_time > last_publication_time + end + + # Se modificó la configuración del sitio + # + # @return [Boolean] + def configuration_pending? + last_configuration_time > last_publication_time + end + + private + + # Encuentra la fecha del último artículo modificado. Si no hay + # ninguno, devuelve la fecha de modificación del sitio. + # + # @return [Time] + def last_indexed_post_time + indexed_posts.order(updated_at: :desc).select(:updated_at).first&.updated_at || updated_at + end + + # Encuentra la fecha de última modificación de los métodos de + # publicación. + # + # @return [Time] + def last_deploy_time + deploys.order(created_at: :desc).select(:created_at).first&.created_at || updated_at + end + + # Encuentra la fecha de última publicación exitosa, si no hay + # ninguno, devuelve la fecha de modificación del sitio. + # + # @return [Time] + def last_publication_time + build_stats.jekyll.where(status: true).order(created_at: :desc).select(:created_at).first&.created_at || updated_at + end + + # Fecha de última modificación de la configuración + # + # @return [Time] + def last_configuration_time + File.mtime(config.path) + end end end end diff --git a/app/models/site_build_stat.rb b/app/models/site_build_stat.rb new file mode 100644 index 00000000..1a63a0bb --- /dev/null +++ b/app/models/site_build_stat.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +SiteBuildStat = Struct.new(:site) diff --git a/app/models/usuarie.rb b/app/models/usuarie.rb index 9b9fd4e6..2bc7a1b5 100644 --- a/app/models/usuarie.rb +++ b/app/models/usuarie.rb @@ -12,6 +12,8 @@ class Usuarie < ApplicationRecord validates_with EmailAddress::ActiveRecordValidator, field: :email before_create :lang_from_locale! + before_update :remove_confirmation_invitation_inconsistencies! + before_update :accept_invitation_after_confirmation! has_many :roles has_many :sites, through: :roles @@ -49,9 +51,31 @@ class Usuarie < ApplicationRecord end end + # Les usuaries necesitan link de invitación si no tenían cuenta + # y todavía no aceptaron la invitación anterior. + def needs_invitation_link? + created_by_invite? && !invitation_accepted? + end + private def lang_from_locale! self.lang = I18n.locale.to_s end + + # El invitation_token solo es necesario cuando fue creade por otre + # usuarie. De lo contrario lo que queremos es un proceso de + # confirmación. + def remove_confirmation_invitation_inconsistencies! + self.invitation_token = nil unless created_by_invite? + end + + # Si le usuarie (re)confirma su cuenta con una invitación pendiente, + # considerarla aceptada también. + def accept_invitation_after_confirmation! + if confirmed? + self.invitation_token = nil + self.invitation_accepted_at ||= Time.now.utc + end + end end diff --git a/app/policies/site_build_stat_policy.rb b/app/policies/site_build_stat_policy.rb new file mode 100644 index 00000000..03f09d21 --- /dev/null +++ b/app/policies/site_build_stat_policy.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# Quiénes pueden ver estados de compilación de un sitio +class SiteBuildStatPolicy + attr_reader :site_build_stat, :usuarie + + def initialize(usuarie, site_build_stat) + @usuarie = usuarie + @site_build_stat = site_build_stat + end + + # Todes les usuaries e invitades de este sitio + def index? + site_build_stat.site.usuarie?(usuarie) || site_build_stat.site.invitade?(usuarie) + end +end diff --git a/app/services/site_service.rb b/app/services/site_service.rb index 5d28bf91..2c29538c 100644 --- a/app/services/site_service.rb +++ b/app/services/site_service.rb @@ -15,7 +15,8 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do add_role temporal: false, rol: 'usuarie' site.deploys.build type: 'DeployLocal' - sync_nodes + # Los sitios de testing no se sincronizan + sync_nodes unless site.name.end_with? '.testing' I18n.with_locale(usuarie.lang.to_sym || I18n.default_locale) do # No se puede llamar a site.config antes de save porque el sitio @@ -215,7 +216,7 @@ SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # Crea los deploys necesarios para sincronizar a otros nodos de Sutty def sync_nodes Rails.application.nodes.each do |node| - site.deploys.build(type: 'DeployFullRsync', destination: "sutty@#{node}:") + site.deploys.build(type: 'DeployFullRsync', destination: "rsync://rsyncd.#{node}/deploys/", hostname: node) end end diff --git a/app/views/build_stats/index.haml b/app/views/build_stats/index.haml new file mode 100644 index 00000000..27c063f9 --- /dev/null +++ b/app/views/build_stats/index.haml @@ -0,0 +1,20 @@ +%main.row + %aside.menu.col-md-3 + = render 'sites/header', site: @site + .col + %h1= t('.title') + + %table.table + %thead + %tr + - @headers.each do |header| + %th{ scope: 'col' }= header + %tbody + - @table.each do |row| + - row[:urls].each do |url| + %tr + %th{ scope: 'row' }= row[:title] + %td= link_to_if url.present?, url, url, class: 'word-break-all' + %td + %time{ datetime: row[:seconds][:machine] }= row[:seconds][:human] + %td= row[:size] diff --git a/app/views/devise/mailer/invitation_instructions.html.haml b/app/views/devise/mailer/invitation_instructions.html.haml index b12cef64..e87d99d9 100644 --- a/app/views/devise/mailer/invitation_instructions.html.haml +++ b/app/views/devise/mailer/invitation_instructions.html.haml @@ -8,7 +8,7 @@ %h1= site.title %p= site.description -- if @resource.created_by_invite? && !@resource.invitation_accepted? +- if @resource.needs_invitation_link? %p= link_to t('devise.mailer.invitation_instructions.accept'), accept_invitation_url(@resource, invitation_token: @token, change_locale_to: @resource.lang) @@ -18,5 +18,7 @@ format: :'devise.mailer.invitation_instructions.accept_until_format')) %p= t('devise.mailer.invitation_instructions.ignore') +- elsif !@resource.confirmed? && @resource.confirmation_token + = confirmation_url(@resource, confirmation_token: @resource.confirmation_token, change_locale_to: @resource.lang) - else %p= link_to t('devise.mailer.invitation_instructions.sign_in'), root_url diff --git a/app/views/devise/mailer/invitation_instructions.text.haml b/app/views/devise/mailer/invitation_instructions.text.haml index bb496733..5cb007de 100644 --- a/app/views/devise/mailer/invitation_instructions.text.haml +++ b/app/views/devise/mailer/invitation_instructions.text.haml @@ -9,7 +9,7 @@ \ = site.description \ -- if @resource.created_by_invite? && !@resource.invitation_accepted? +- if @resource.needs_invitation_link? = accept_invitation_url(@resource, invitation_token: @token, change_locale_to: @resource.lang) \ - if @resource.invitation_due_at @@ -18,6 +18,8 @@ format: :'devise.mailer.invitation_instructions.accept_until_format')) \ = t('devise.mailer.invitation_instructions.ignore') +- elsif !@resource.confirmed? && @resource.confirmation_token + = confirmation_url(@resource, confirmation_token: @resource.confirmation_token, change_locale_to: @resource.lang) - else = root_url(change_locale_to: @resource.lang) = t('devise.mailer.invitation_instructions.sign_in') diff --git a/app/views/layouts/_breadcrumb.haml b/app/views/layouts/_breadcrumb.haml index b1c42cb2..6281404a 100644 --- a/app/views/layouts/_breadcrumb.haml +++ b/app/views/layouts/_breadcrumb.haml @@ -19,6 +19,10 @@ = link_to t('.tienda'), @site.tienda_url, role: 'button', class: 'btn' + %li.nav-item + = link_to t('.contact_us'), t('.contact_us_href'), + class: 'btn', rel: 'me', target: '_blank' + %li.nav-item = link_to t('.logout'), main_app.destroy_usuarie_session_path, method: :delete, role: 'button', class: 'btn' diff --git a/app/views/posts/_submit.haml b/app/views/posts/_submit.haml index cad43320..944694c1 100644 --- a/app/views/posts/_submit.haml +++ b/app/views/posts/_submit.haml @@ -1,6 +1,8 @@ +- 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' = render 'bootstrap/alert', class: 'invalid-help d-none' do - = site.config.fetch('invalid_help', t('.invalid_help')) + = invalid_help = render 'bootstrap/alert', class: 'sending-help d-none' do - = site.config.fetch('sending_help', t('.sending_help')) + = sending_help diff --git a/app/views/posts/index.haml b/app/views/posts/index.haml index cbc67a60..e8c3dea7 100644 --- a/app/views/posts/index.haml +++ b/app/views/posts/index.haml @@ -1,9 +1,10 @@ %main.row %aside.menu.col-md-3 - %h1= @site.title - %p.lead= @site.description - - cache_if @usuarie, [@site, I18n.locale] do - = render 'sites/status', site: @site + = render 'sites/header', site: @site + + = render 'sites/status', site: @site + + = render 'sites/build', site: @site, class: 'btn-block' %h3= t('posts.new') %table.table.table-sm.mb-3 @@ -29,8 +30,6 @@ type: 'info', link: site_usuaries_path(@site) - = render 'sites/build', site: @site - - if @site.design.credits = render 'bootstrap/alert' do = sanitize_markdown @site.design.credits @@ -45,7 +44,8 @@ - next if param == 'q' %input{ type: 'hidden', name: param, value: value } .form-group.flex-grow-0.m-0 - %input.form-control.border.border-magenta{ type: 'search', placeholder: 'Buscar', name: 'q', value: @filter_params[:q] } + %label.sr-only{for: 'q'}= t('.search') + %input#q.form-control.border.border-magenta{ type: 'search', placeholder: t('.search'), name: 'q', value: @filter_params[:q] } %input.sr-only{ type: 'submit' } - if @site.locales.size > 1 diff --git a/app/views/sites/_build.haml b/app/views/sites/_build.haml index 6bc4d11b..5911e908 100644 --- a/app/views/sites/_build.haml +++ b/app/views/sites/_build.haml @@ -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', + class: "btn no-border-radius #{local_assigns[:class]}", title: site.enqueued? ? t('help.sites.enqueued') : t('help.sites.enqueue'), data: { disable_with: t('sites.enqueued') }, disabled: site.enqueued? diff --git a/app/views/sites/_form.haml b/app/views/sites/_form.haml index 001f542e..69997ffa 100644 --- a/app/views/sites/_form.haml +++ b/app/views/sites/_form.haml @@ -55,7 +55,7 @@ layouts: site.incompatible_layouts.to_sentence) .row.row-cols-1.row-cols-md-2.designs -# Demasiado complejo para un f.collection_radio_buttons - - Design.all.find_each do |design| + - Design.all.order(priority: :desc).each do |design| .design.col.d-flex.flex-column .custom-control.custom-radio = f.radio_button :design_id, design.id, diff --git a/app/views/sites/_header.haml b/app/views/sites/_header.haml new file mode 100644 index 00000000..c8931041 --- /dev/null +++ b/app/views/sites/_header.haml @@ -0,0 +1,3 @@ +.hyphens{ lang: site.default_locale } + %h1= site.title + %p.lead= site.description diff --git a/app/views/sites/_status.haml b/app/views/sites/_status.haml index a731aa7d..6a610e73 100644 --- a/app/views/sites/_status.haml +++ b/app/views/sites/_status.haml @@ -1,7 +1,9 @@ - link = nil - if site.not_published_yet? - message = t('.not_published_yet') -- if site.building? +- elsif site.awaiting_publication? + - message = t('.awaiting_publication') +- elsif site.building? - if site.average_publication_time_calculable? - average_building_time = site.average_publication_time - elsif !site.similar_sites? @@ -16,4 +18,4 @@ - link = true = render 'bootstrap/alert' do - = link_to_if link, message.html_safe, site.url, class: 'alert-link' + = link_to_if link, message.html_safe, site_build_stats_path(site), class: 'alert-link' diff --git a/config/locales/devise_invitable.es.yml b/config/locales/devise_invitable.es.yml index e83a703c..860ee4f8 100644 --- a/config/locales/devise_invitable.es.yml +++ b/config/locales/devise_invitable.es.yml @@ -22,7 +22,7 @@ es: someone_invited_you: "Alguien te ha invitado a colaborar en %{url}, podés aceptar la invitación con el enlace a continuación." accept: "Aceptar la invitación" accept_until: "La invitación vencerá el %{due_date}." - ignore: "Si no querés aceptar la invitación, por favor ignora este correo. Tu cuenta no será creada hasta que aceptes la invitación y configures una contraseña." + ignore: "Si no querés aceptar la invitación, por favor ignorá este correo. Tu cuenta no será creada hasta que aceptes la invitación y configures una contraseña." sign_in: "Iniciá sesión con tu cuenta para aceptar o rechazar la invitación." time: formats: diff --git a/config/locales/en.yml b/config/locales/en.yml index 5da5fe4f..f6b7017c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -206,6 +206,8 @@ en: title: 'Your location in Sutty' logout: Log out mutual_aid: Mutual aid + contact_us: "Contact us" + contact_us_href: "https://sutty.nl/en/#contact" collaborations: collaborate: submit: Register @@ -302,7 +304,7 @@ en: storage network may continue retaining copies of the data indefinitely. - [Learn more](https://ffdweb.org/building-distributed-press-a-publishing-tool-for-the-decentralized-web/) + [Learn more](https://sutty.nl/learn-more-about-publish-to-dweb-functionality/) stats: index: title: Statistics @@ -362,9 +364,10 @@ en: static_file_migration: 'File migration' find_and_replace: 'Search and replace' status: - building: "Your site is building, please wait to refresh this page..." + building: "Your site is building, refresh this page in ." not_published_yet: "Your site is being published for the first time, please wait up to 1 minute..." - available: "Your site is available! Click here to visit it." + available: "Your site is available! Click here to find all the different ways to visit it." + awaiting_publication: "There are unpublished changes. Click the button below and wait a moment to find them on your site." index: title: 'My Sites' pull: 'Upgrade' @@ -430,7 +433,7 @@ en: title: 'Design' actions: 'Information about this design' url: 'Demo' - licencia: 'License' + license: 'License' licencia: title: 'License for the site and everything published on it' url: 'Read the license' @@ -541,7 +544,8 @@ en: new: 'Post types' remove_filter_help: 'Remove the filter: %{filter}' categories: 'Everything' - index: 'Posts' + index: + search: 'Search' edit: 'Edit' preview: btn: 'Preliminary version' @@ -699,3 +703,6 @@ en: filter: filter: 'Filter' remove: 'Back' + build_stats: + index: + title: "Publications" diff --git a/config/locales/es.yml b/config/locales/es.yml index 829e0ccc..aeb385e0 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -206,6 +206,8 @@ es: title: 'Tu ubicación en Sutty' logout: Cerrar sesión mutual_aid: Ayuda mutua + contact_us: "Contacto" + contact_us_href: "https://sutty.nl/#contacto" collaborations: collaborate: submit: Registrarme @@ -307,7 +309,7 @@ es: nodos en la red de almacenamiento distribuida puedan retener copias de tu contenido indefinidamente. - [Saber más (en inglés)](https://ffdweb.org/building-distributed-press-a-publishing-tool-for-the-decentralized-web/) + [Saber más](https://sutty.nl/saber-mas-sobre-publicar-a-la-web-distribuida/) stats: index: title: Estadísticas @@ -367,9 +369,10 @@ es: static_file_migration: 'Migración de archivos' find_and_replace: 'Búsqueda y reemplazo' status: - building: "Tu sitio se está publicando, por favor espera para recargar esta página..." + building: "Tu sitio se está publicando, recargá esta página en ." not_published_yet: "Tu sitio se está publicando por primera vez, por favor espera hasta un minuto..." - available: "¡Tu sitio está disponible! Cliquea aquí para visitarlo." + available: "¡Tu sitio está disponible! Cliqueá aquí para encontrar todas las formas en que podés visitarlo." + awaiting_publication: "Hay cambios sin publicar, cliqueá el botón debajo y espera un momento para encontrarlos en tu sitio." index: title: 'Mis sitios' pull: 'Actualizar' @@ -549,7 +552,8 @@ es: categories: 'Todos' new: 'Tipos de artículos' remove_filter_help: 'Quitar este filtro: %{filter}' - index: 'Artículos' + index: + search: 'Buscar' edit: 'Editar' preview: btn: 'Versión preliminar' @@ -708,3 +712,6 @@ es: filter: filter: 'Filtrar' remove: 'Volver' + build_stats: + index: + title: "Publicaciones" diff --git a/config/routes.rb b/config/routes.rb index 511ca654..3828915c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -75,5 +75,7 @@ Rails.application.routes.draw do get :'stats/host', to: 'stats#host' get :'stats/uris', to: 'stats#uris' get :'stats/resources', to: 'stats#resources' + + resources :build_stats, only: %i[index] end end diff --git a/db/migrate/20230415153231_add_priority_to_designs.rb b/db/migrate/20230415153231_add_priority_to_designs.rb new file mode 100644 index 00000000..7fc45558 --- /dev/null +++ b/db/migrate/20230415153231_add_priority_to_designs.rb @@ -0,0 +1,5 @@ +class AddPriorityToDesigns < ActiveRecord::Migration[6.1] + def change + add_column :designs, :priority, :integer + end +end diff --git a/db/migrate/20230421182627_change_full_rsync_destination.rb b/db/migrate/20230421182627_change_full_rsync_destination.rb new file mode 100644 index 00000000..3a22aea6 --- /dev/null +++ b/db/migrate/20230421182627_change_full_rsync_destination.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +# Envía los cambios a través de rsyncd +class ChangeFullRsyncDestination < ActiveRecord::Migration[6.1] + def up + DeployFullRsync.find_each do |deploy| + Rails.application.nodes.each do |node| + deploy.destination = "rsync://rsyncd.#{node}/deploys/" + deploy.save + end + end + end + + def down + DeployFullRsync.find_each do |deploy| + Rails.application.nodes.each do |node| + deploy.destination = "sutty@#{node}:" + deploy.save + end + end + end +end diff --git a/db/migrate/20230424174544_add_node_to_access_logs.rb b/db/migrate/20230424174544_add_node_to_access_logs.rb new file mode 100644 index 00000000..805fbc27 --- /dev/null +++ b/db/migrate/20230424174544_add_node_to_access_logs.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Agrega la columna de nodo a los logs +class AddNodeToAccessLogs < ActiveRecord::Migration[6.1] + def change + add_column :access_logs, :node, :string, index: true + end +end diff --git a/db/schema.rb b/db/schema.rb index a395329d..fd82d447 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_10_22_225449) do +ActiveRecord::Schema.define(version: 2023_04_15_153231) do # These are extensions that must be enabled in order to support this database enable_extension "pg_trgm" @@ -217,6 +217,7 @@ ActiveRecord::Schema.define(version: 2021_10_22_225449) do t.boolean "disabled", default: false t.text "credits" t.string "designer_url" + t.integer "priority" end create_table "indexed_posts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| @@ -380,6 +381,7 @@ ActiveRecord::Schema.define(version: 2021_10_22_225449) do add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + create_trigger("indexed_posts_before_insert_update_row_tr", :compatibility => 1). on("indexed_posts"). before(:insert, :update) do diff --git a/db/seeds/designs.yml b/db/seeds/designs.yml index b1508b84..a04c99c1 100644 --- a/db/seeds/designs.yml +++ b/db/seeds/designs.yml @@ -6,6 +6,7 @@ disabled: true description_en: "Upload your own theme. [This feature is in development, help us!](https://sutty.nl/en/#contact)" description_es: "Subir tu propio diseño. [Esta posibilidad está en desarrollo, ¡ayudanos!](https://sutty.nl/#contacto)" + priority: '0' - name_en: 'I want you to develop a site for me' name_es: 'Quiero que desarrollen mi sitio' gem: 'sutty-theme-custom' @@ -13,6 +14,7 @@ disabled: true description_en: "If you want us to develop your site, you're welcome to [contact us!](https://sutty.nl/en/#contact) :)" description_es: "Si querés que desarrollemos tu sitio, [escribinos](https://sutty.nl/#contacto) :)" + priority: '2' - name_en: 'Minima' name_es: 'Mínima' gem: 'sutty-minima' @@ -20,6 +22,7 @@ description_en: "Sutty Minima is based on [Minima](https://jekyll.github.io/minima/), a blog-focused theme for Jekyll." description_es: 'Sutty Mínima es una plantilla para blogs basada en [Mínima](https://jekyll.github.io/minima/).' license: 'https://0xacab.org/sutty/jekyll/minima/-/blob/master/LICENSE.txt' + priority: '100' - name_en: 'Sutty' name_es: 'Sutty' gem: 'sutty-jekyll-theme' @@ -29,6 +32,7 @@ license: 'https://0xacab.org/sutty/jekyll/sutty-jekyll-theme/-/blob/master/LICENSE.txt' credits_es: 'Sutty es parte de la economía solidaria :)' credits_en: 'Sutty is a solidarity economy project!' + priority: '90' - name_en: 'Self-managed Book Publisher' name_es: 'Editorial Autogestiva' gem: 'editorial-autogestiva-jekyll-theme' @@ -38,6 +42,7 @@ license: 'https://0xacab.org/sutty/jekyll/editorial-autogestiva-jekyll-theme/-/blob/master/LICENSE.txt' credits_es: 'Esta plantilla fue inspirada en el trabajo de las [editoriales autogestivas](https://sutty.nl/plantillas-para-crear-cat%C3%A1logos-de-editoriales-autogestivas/)' credits_en: 'This theme is inspired by [independent publishing projects](https://sutty.nl/en/new-template-for-publishing-projects/)' + priority: '50' - name_en: 'Donations' name_es: 'Donaciones' gem: 'sutty-donaciones-jekyll-theme' @@ -47,6 +52,7 @@ license: 'https://0xacab.org/sutty/jekyll/sutty-donaciones-jekyll-theme/-/blob/master/LICENSE.txt' credits_es: 'Diseñamos esta plantilla para [visibilizar campañas de donaciones](https://sutty.nl/plantilla-para-donaciones/) durante la cuarentena.' credits_en: 'We designed this theme to increase [visibility for donation requests](https://sutty.nl/template-for-donations/) during the quarantine.' + priority: '80' - name_en: 'Support campaign' name_es: 'Adhesiones' gem: 'adhesiones-jekyll-theme' @@ -57,6 +63,7 @@ credits_es: 'Desarrollamos esta plantilla junto con [Librenauta](https://sutty.nl/plantilla-para-campa%C3%B1as-de-adhesiones/)' credits_en: 'This template was made in collaboration with Librenauta' designer_url: 'https://copiona.com/donaunbit/' + priority: '60' - name_en: 'Community Radio' name_es: 'Radio comunitaria' gem: 'radios-comunitarias-jekyll-theme' @@ -67,6 +74,7 @@ credits_es: 'Desarrollamos esta plantilla junto con Librenauta en 15 horas :)' credits_en: 'This template was made in collaboration with Librenauta in 15 hours!' designer_url: 'https://copiona.com/donaunbit/' + priority: '70' - name_en: 'Resource toolkit' name_es: 'Recursero' gem: 'recursero-jekyll-theme' @@ -74,10 +82,12 @@ disabled: true description_en: "We're working towards adding more themes for you to use. [Contact us!](https://sutty.nl/en/#contact)" description_es: "Estamos trabajando para que puedas tener más diseños. [¡Escribinos!](https://sutty.nl/#contacto)" -- name_en: 'Other themes' - name_es: 'Mi propio diseño' + priority: '3' +- name_en: 'More themes' + name_es: 'Más plantillas' gem: 'sutty-theme-own' url: 'https://jekyllthemes.org' disabled: true description_en: "We're working towards adding more themes for you to use. [Contact us!](https://sutty.nl/en/#contact)" description_es: "Estamos trabajando para que puedas tener más diseños. [¡Escribinos!](https://sutty.nl/#contacto)" + priority: '1' diff --git a/public/500.html b/public/500.html index 2d69baf6..9e8ea780 100644 --- a/public/500.html +++ b/public/500.html @@ -19,7 +19,11 @@

Gracias por ayudarnos a encontrar errores :)

-

Volver al panel

+

+ Volver al panel + | + Contáctanos +

@@ -31,7 +35,11 @@

Thanks for helping us in finding errors! :)

-

Go back to panel

+

+ Go back to panel + | + Contact us +