# frozen_string_literal: true module ActiveStorage class Service # Sube los archivos a cada repositorio y los agrega al LFS de su # repositorio git. # # @todo: Implementar LFS. No nos gusta mucho la idea porque duplica # el espacio en disco, pero es la única forma que tenemos (hasta que # implementemos IPFS) para poder transferir los archivos junto con el # sitio. class JekyllService < Service::DiskService # Genera un servicio para un sitio determinado # # @param :site [Site] # @return [ActiveStorage::Service::JekyllService] def self.build_for_site(site:) new(root: File.join(site.path, 'public'), public: true).tap do |js| js.name = site.name.to_sym end end # Solo copiamos el archivo si no existe # # @param :key [String] # @param :io [IO] # @param :checksum [String] def upload(key, io, checksum: nil, **) instrument :upload, key: key, checksum: checksum do IO.copy_stream(io, make_path_for(key)) unless exist?(key) ensure_integrity_of(key, checksum) if checksum end end # Lo mismo que en DiskService agregando el nombre de archivo en la # firma. Esto permite que luego podamos guardar el archivo donde # corresponde. # # @param :key [String] # @param :expires_in [Integer] # @param :content_type [String] # @param :content_length [Integer] # @param :checksum [String] # @return [String] def url_for_direct_upload(key, expires_in:, content_type:, content_length:, checksum:) instrument :url, key: key do |payload| verified_token_with_expiration = ActiveStorage.verifier.generate( { key: key, content_type: content_type, content_length: content_length, checksum: checksum, service_name: name, filename: filename_for(key) }, expires_in: expires_in, purpose: :blob_token ) generated_url = url_helpers.update_rails_disk_service_url(verified_token_with_expiration, host: current_host) payload[:url] = generated_url generated_url end end # Mantener retrocompatibilidad con cómo gestionamos los archivos # subidos hasta ahora. # # @param :key [String] # @return [String] def folder_for(key) key end # Obtiene el nombre de archivo para esta key # # @param :key [String] # @return [String] def filename_for(key) ActiveStorage::Blob.where(key: key).limit(1).pluck(:filename).first.tap do |filename| raise ArgumentError, "Filename for key #{key} is blank" if filename.blank? end end # Crea una ruta para la llave con un nombre conocido. # # @param :key [String] # @return [String] def path_for(key) File.join root, folder_for(key), filename_for(key) end end end end