module Eco::API::UseCases::GraphQL::Utils module Sftp include Eco::API::UseCases::GraphQL::Helpers::Base::CaseEnv def upload(local_file, subfolder: remote_subfolder, gid: sftp_group_id) sftp_session.upload( local_file, remote_folder: remote_folder(subfolder), gid: gid ) end alias_method :sftp_upload, :upload def sftp_group_id if self.class.const_defined?(:SFTP_GROUP) self.class.const_get(:SFTP_GROUP) elsif (group_id = options.dig(:sftp, :group)) group_id end end def sftp_download_files(subfolder: remote_subfolder, pattern: nil, local_folder: self.local_folder) with_remote_files(subfolder: subfolder, pattern: pattern).tap do |files| next if files.empty? file_names = files.map {|file| to_remote_path(file.name, subfolder: subfolder)} log(:info) { msg = "Getting the following files into the local folder '#{local_folder}':\n" msg << " • " msg << files_names.join("\n • ") msg } sftp.download(file_names, local_folder: local_folder) end end def sftp_move_file(source, dest) sftp.move(source, dest, 0x0001) do |response| if response.ok? log(:info) { "#{source}\n -to-> #{dest}" } else log(:info) { "Could not move file #{source}" } end end end def ensure_remote_empty(subfolder: remote_subfolder, pattern: nil) files = with_remote_files(subfolder: subfolder, pattern: pattern) return if files.empty? msg = "There are still files in the remote folder that will be deleted: '#{subfolder}':\n" msg << " • " str = files.map(&:longname).join("\n • ") str << "\n" msg << str session.prompt_user( "Do you want to proceed to delete? (Y/n):", explanation: msg, default: "Y", timeout: 3 ) do |response| next unless response.upcase.start_with?("Y") files.each do |file| remote_full_path = to_remote_path(file.name, subfolder: subfolder) res = sftp_session.remove(remote_full_path) log(:info) { "Deleted remote file: '#{remote_full_path}' (#{res})" } end end end # @param subfolder [String] the subfolder. def with_remote_files(subfolder: remote_subfolder, pattern: nil) sftp.files(remote_folder(subfolder), pattern: pattern).each do |remote_file| yield(remote_file) if block_given? end rescue ArgumentError raise rescue ::Net::SFTP::StatusException => err log(:error) { msg = "(#{self.class}) There was an error trying to access " msg << "the remote folder '#{subfolder}': #{err}" msg } [] end def to_remote_path(file, subfolder: remote_subfolder) [remote_folder(subfolder), file].join('/') end def remote_subfolder if (remote_dir = options.dig(:sftp, :remote_subfolder)) remote_dir elsif self.class.const_defined?(:REMOTE_FOLDER) self.class::REMOTE_FOLDER end end def remote_folder(subfolder = remote_subfolder) [sftp_env_base_path, subfolder].compact.join('/') end def sftp_env_base_path sftp_config.remote_folder end def local_folder if (local_dir = options.dig(:sftp, :local_folder)) local_dir elsif self.class.const_defined?(:LOCAL_FOLDER) self.class::LOCAL_FOLDER else "." end end def sftp_config session.config.sftp end def sftp_session sftp.sftp_session end def sftp session.sftp end end end