5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-07-03 11:26:06 +00:00
panel/app/models/site/deployment.rb
2021-08-14 20:31:28 -03:00

114 lines
3.7 KiB
Ruby

# frozen_string_literal: true
class Site
# Abstrae todo el comportamiento de publicación del sitio en un
# módulo.
module Deployment
extend ActiveSupport::Concern
included do
# TODO: Hacer que los diferentes tipos de deploy se auto registren
# @see app/services/site_service.rb
DEPLOYS = %i[local private www zip hidden_service].freeze
validates :name,
format: { with: /\A[0-9a-z\-]+\z/,
message: I18n.t('activerecord.errors.models.site.attributes.name.no_subdomains') }
validates :name, hostname: true
validates_presence_of :canonical_deploy
validate :deploy_local_presence
validate :name_changed_is_unique_hostname, if: :name_changed?
has_one :canonical_deploy, class_name: 'Deploy'
has_many :deploys, dependent: :destroy
has_many :access_logs, through: :deploys
has_many :build_stats, through: :deploys
before_validation :deploy_local_is_default_canonical_deploy!, unless: :canonical_deploy_id?
before_update :update_deploy_local_hostname!, if: :name_changed?
accepts_nested_attributes_for :deploys, allow_destroy: true
# El primer deploy del sitio, si no existe en la base de datos es
# porque recién estamos creando el sitio y todavía no se guardó.
#
# @return [DeployLocal]
def deploy_local
@deploy_local ||= deploys.order(created_at: :asc).find_by(type: 'DeployLocal') || deploys.find do |d|
d.type == 'DeployLocal'
end
end
# Obtiene la URL principal
#
# @param :slash [Boolean]
# @return [String]
def canonical_url(slash: true)
canonical_deploy.url.dup.tap do |url|
url << '/' if slash
end
end
alias_method :url, :canonical_url
# Devuelve todas las URLs posibles
#
# @param :slash [Boolean]
# @return [Array]
def urls(slash: true)
deploys.map(&:url).map do |url|
slash ? "#{url}/" : url
end
end
# Obtiene el hostname principal
#
# @return [String]
def hostname
canonical_deploy.hostname
end
private
# Validar que al cambiar el nombre no estemos utilizando un
# hostname reservado por otro sitio.
#
# Al cambiar el nombre del DeployLocal se va a validar que el
# hostname nuevo sea único.
def name_changed_is_unique_hostname
deploy_local.hostname = nil
return if deploy_local.valid?
errors.add :name, I18n.t('activerecord.errors.models.site.attributes.name.duplicated_hostname')
end
# Si cambia el nombre queremos actualizarlo en el DeployLocal y
# recargar el deploy canónico para tomar el nombre que
# corresponda.
def update_deploy_local_hostname!
deploy_local.update(hostname: name)
canonical_deploy.reload if canonical_deploy == deploy_local
end
# Si no asignamos un deploy canónico en el momento le asignamos el
# deploy local
def deploy_local_is_default_canonical_deploy!
self.canonical_deploy ||= deploy_local
end
# Valida si el sitio tiene al menos una forma de alojamiento asociada
# y es la local
#
# TODO: Volver opcional el alojamiento local, pero ahora mismo está
# atado a la generación del sitio así que no puede faltar
def deploy_local_presence
# Usamos size porque queremos saber la cantidad de deploys sin
# guardar también
return if deploys.size.positive? && deploys.map(&:type).include?('DeployLocal')
errors.add(:deploys, I18n.t('activerecord.errors.models.site.attributes.deploys.deploy_local_presence'))
end
end
end
end