lib/io_streams/paths/sftp.rb in iostreams-1.0.0.beta7 vs lib/io_streams/paths/sftp.rb in iostreams-1.0.0
- old
+ new
@@ -1,9 +1,29 @@
require 'open3'
module IOStreams
module Paths
+ # Read a file from a remote sftp server.
+ #
+ # Example:
+ # IOStreams.
+ # path("sftp://example.org/path/file.txt", username: "jbloggs", password: "secret", compression: false).
+ # reader do |input|
+ # puts input.read
+ # end
+ #
+ # Note:
+ # - raises Net::SFTP::StatusException when the file could not be read.
+ #
+ # Write to a file on a remote sftp server.
+ #
+ # Example:
+ # IOStreams.
+ # path("sftp://example.org/path/file.txt", username: "jbloggs", password: "secret", compression: false).
+ # writer do |output|
+ # output.write('Hello World')
+ # end
class SFTP < IOStreams::Path
include SemanticLogger::Loggable if defined?(SemanticLogger)
class << self
attr_accessor :sshpass_bin, :sftp_bin, :sshpass_wait_seconds
@@ -52,11 +72,11 @@
#
# # When using the sftp executable use an identity file instead of a password to authenticate:
# IOStreams.path("sftp://test.com/path/file_name.csv", username: "jack", IdentityFile: "~/.ssh/private_key").reader do |io|
# puts io.read
# end
- def initialize(url, username: nil, password: nil, ruby: true, ssh_options: {})
+ def initialize(url, username: nil, password: nil, ssh_options: {})
uri = Utils::URI.new(url)
raise(ArgumentError, "Invalid URL. Required Format: 'sftp://<host_name>/<file_name>'") unless uri.scheme == 'sftp'
@hostname = uri.hostname
@mkdir = false
@@ -85,44 +105,10 @@
def mkdir
@mkdir = true
self
end
- # Read a file from a remote sftp server.
- #
- # Example:
- # IOStreams.
- # path("sftp://example.org/path/file.txt", username: "jbloggs", password: "secret", compression: false).
- # reader do |input|
- # puts input.read
- # end
- #
- # Note:
- # - raises Net::SFTP::StatusException when the file could not be read.
- def reader(&block)
- IOStreams.temp_file("iostreams-sftp-reader") do |temp_file|
- sftp_download(path, temp_file.to_s)
- ::File.open(temp_file.to_s, "rb") { |io| streams.reader(io, &block) }
- end
- end
-
- # Write to a file on a remote sftp server.
- #
- # Example:
- # IOStreams.
- # path("sftp://example.org/path/file.txt", username: "jbloggs", password: "secret", compression: false).
- # writer do |output|
- # output.write('Hello World')
- # end
- def writer(&block)
- IOStreams.temp_file("iostreams-sftp-writer") do |temp_file|
- ::File.open(temp_file.to_s, "wb") { |io| streams.writer(io, &block) }
- sftp_upload(temp_file.to_s, path)
- temp_file.size
- end
- end
-
# TODO: Add #copy_from shortcut to detect when a file is supplied that does not require conversion.
# Search for files on the remote sftp server that match the provided pattern.
#
# The pattern matching works like Net::SFTP::Operations::Dir.glob and Dir.glob
@@ -145,19 +131,34 @@
flags |= ::File::FNM_DOTMATCH if hidden
Net::SFTP.start(hostname, username, build_ssh_options) do |sftp|
sftp.dir.glob(".", pattern, flags) do |path|
next if !directories && !path.file?
- new_path = self.class.new("sftp://#{hostname}/#{path.name}", username: username, password: password, ruby: ruby, **ssh_options)
+ new_path = self.class.new("sftp://#{hostname}/#{path.name}", username: username, password: password, **ssh_options)
yield(new_path, path.attributes.attributes)
end
end
nil
end
private
attr_reader :password
+
+ def stream_reader(&block)
+ IOStreams.temp_file("iostreams-sftp-reader") do |temp_file|
+ sftp_download(path, temp_file.to_s)
+ ::File.open(temp_file.to_s, "rb") { |io| builder.reader(io, &block) }
+ end
+ end
+
+ def stream_writer(&block)
+ IOStreams.temp_file("iostreams-sftp-writer") do |temp_file|
+ ::File.open(temp_file.to_s, "wb") { |io| builder.writer(io, &block) }
+ sftp_upload(temp_file.to_s, path)
+ temp_file.size
+ end
+ end
# Use sftp and sshpass executables to download to a local file
def sftp_download(remote_file_name, local_file_name)
with_sftp_args do |args|
Open3.popen2e(*args) do |writer, reader, waith_thr|