lib/xftp/session/sftp.rb in xftp-0.1.0.pre.alpha vs lib/xftp/session/sftp.rb in xftp-0.2.0.pre.alpha

- old
+ new

@@ -18,50 +18,92 @@ # @param [Hash] settings the adapter connection settings def initialize(uri, settings = {}) super @path = Pathname '.' @settings.merge!(password: @credentials[:password]) - @options = XFTP.config.sftp.deep_merge(@settings) + @ssh_options = XFTP.config.ssh.deep_merge(@settings) end # Changes the current (remote) working directory # @param [String] path the relative (remote) path def chdir(path) - @path /= path + @path += path end # Creates a remote directory # @param [String] dirname the name of new directory # relative to the current (remote) working directory # @param [Hash] attrs the attributes of new directory # supported by the the version of SFTP protocol in use def mkdir(dirname, attrs = {}) - @sftp.mkdir! pathname(dirname), attrs + @sftp.mkdir!(remote_path(dirname), attrs) end + # @return [Boolean] `true` if the file exists + # in a current working directory on the remote host + def exists?(filename) + entries.include? filename + end + + # @return [Boolean] `true` if the argument refers to a directory on the remote host + def directory?(dirname) + @sftp.file.directory? remote_path(dirname) + end + # Removes the remote directory # @param [String] dirname the name of directory to be removed def rmdir(dirname) - @sftp.rmdir! pathname(dirname) + @sftp.rmdir! remote_path(dirname) end # Renames (moves) a file on the server # @param [String] from the path to move from # @param [String] to the path to move to def move(from, to:, flags: RENAME_OPERATION_FLAGS) - @sftp.rename(from, to, flags) + @sftp.rename!(remote_path(from), remote_path(to), flags) end + # Calls the block once for each entry in the current directory + # on the remote server and (asynchronously) yields a filename to the block + def each_file + @sftp.dir.foreach(@path.to_s) do |entry| + filename = entry.name + yield filename unless directory? filename + end + end + # For more info (see Dir#glob), it's almost of the same nature # @param [String] pattern the search pattern relative # the the current working directory # @param [Integer] (see File.fnmatch) for the meaning of the flags parameter. # Default value is `File::FNM_EXTGLOB` def glob(pattern, flags: GLOB_OPERATION_FLAGS) - @sftp.dir.glob(@path.to_s, pattern, flags) + @sftp.dir.glob(@path.to_s, pattern, flags) { |entry| yield entry.name } end + # Initiates a download from remote to local, synchronously + # @param [String] from the source remote file name + # @param [String] to the target local file name + # @param [Hash] options the download operation options + # @see Net::SFTP::Operations::Download + def download(from, to: File.basename(from), **options) + remote = remote_path(from) + local = (Pathname.pwd + to).to_s + @sftp.download!(remote, local, options) + end + + # @return [Array<String>] an array of filenames in the remote directory + def files + entries.reject { |filename| directory? filename } + end + + # @return [Array<String>] an array of entries (including directories) + # in the remote directory + def entries + @sftp.dir.entries(@path.to_s).map(&:name) + end + protected # Opens a new SFTP connection def open connect @@ -81,17 +123,17 @@ end private def connect - @ssh = Net::SSH.start(@uri.host, @credentials[:login], @options) + @ssh = Net::SSH.start(@uri.host, @credentials[:login], @ssh_options) @sftp = Net::SFTP::Session.new @ssh @sftp.connect! end # @return [String] a path name relative to the current working directory - def pathname(relative) - (@path / relative).to_s + def remote_path(relative) + (@path + relative).to_s end end end end