# frozen_string_literal: true # Se encargar de guardar cambios en sitios # TODO: Implementar rollback en la configuración SiteService = Struct.new(:site, :usuarie, :params, keyword_init: true) do # Crea un sitio, agrega un rol nuevo y guarda los cambios a la # configuración en el repositorio git def create self.site = Site.new params add_role temporal: false, rol: 'usuarie' sync_nodes I18n.with_locale(usuarie.lang.to_sym || I18n.default_locale) do # No se puede llamar a site.config antes de save porque el sitio # todavía no existe. # # TODO: hacer que el repositorio se cree cuando es necesario, para # que no haya estados intermedios. site.locales = [usuarie.lang] + I18n.available_locales site.save && site.config.write && commit_config(action: :create) end add_licencias site end # Actualiza el sitio y guarda los cambios en la configuración def update I18n.with_locale(usuarie&.lang&.to_sym || I18n.default_locale) do site.update(params) && site.config.write && commit_config(action: :update) end change_licencias site end # Genera los Deploy necesarios para el sitio a menos que ya los tenga. def build_deploys Site::DEPLOYS.map { |deploy| "Deploy#{deploy.to_s.camelcase}" } .each do |deploy| next if site.deploys.find_by type: deploy site.deploys.build type: deploy end end # Agregar una dirección oculta de Tor al DeployHiddenService y a la # configuración del Site. def add_onion onion = params[:onion].strip deploy = DeployHiddenService.find_by(site: site) return false unless !onion.blank? && deploy deploy.values[:onion] = onion deploy.save site.config['onion-location'] = onion site.config.write commit_config(action: :tor) end # Trae cambios desde la rama remota y reindexa los artículos. # # @return [Boolean] def merge result = site.repository.merge(usuarie) # TODO: Implementar callbacks site.try(:index_posts!) if result result.present? end private # Guarda los cambios de la configuración en el repositorio git def commit_config(action:) site.repository .commit(usuarie: usuarie, file: site.config.path, message: I18n.t("site_service.#{action}", name: site.name)) end def add_role(temporal: true, rol: 'invitade') site.roles << Rol.new(site: site, usuarie: usuarie, temporal: temporal, rol: rol) end # Crea la licencia del sitio para cada locale disponible en el sitio def add_licencias site.locales.each do |locale| next unless I18n.available_locales.include? locale Mobility.with_locale(locale) do add_licencia lang: locale end end end def add_licencia(lang:) params = ActionController::Parameters.new( post: { lang: lang, title: site.licencia.name, description: I18n.t('sites.form.licencia.title'), author: %w[Sutty], permalink: "#{I18n.t('activerecord.models.licencia').downcase}/", content: CommonMarker.render_html(site.licencia.deed) } ) PostService.new(site: site, usuarie: usuarie, params: params).create end # Encuentra la licencia a partir de su enlace permanente y le cambia # el contenido # # TODO: Crear un layout específico para licencias así es más certera # la búsqueda. def change_licencias site.locales.each do |locale| next unless I18n.available_locales.include? locale Mobility.with_locale(locale) do permalink = "#{I18n.t('activerecord.models.licencia').downcase}/" post = site.posts(lang: locale).find_by(permalink: permalink) post ? change_licencia(post: post) : add_licencia(lang: locale) end end end def change_licencia(post:) params = ActionController::Parameters.new( post: { title: site.licencia.name, content: CommonMarker.render_html(site.licencia.deed) } ) PostService.new(site: site, usuarie: usuarie, post: post, params: params).update end # Crea los deploys necesarios para sincronizar a otros nodos de Sutty def sync_nodes Rails.application.nodes.each do |node| site.deploys.build(type: 'DeployRsync', destination: "sutty@#{node}:#{site.hostname}") end end end