Class: AnPostReturn::SFTP::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/an_post_return/sftp/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, username, password, proxy_config = nil) ⇒ Client

Initialize a new SFTP client

Parameters:

  • host (String)

    SFTP server hostname

  • username (String)

    SFTP username

  • password (String)

    SFTP password

  • proxy_config (Hash, nil) (defaults to: nil)

    Optional HTTP proxy configuration @option proxy_config [String] :host Proxy host @option proxy_config [Integer] :port Proxy port @option proxy_config [String, nil] :username Optional proxy username @option proxy_config [String, nil] :password Optional proxy password



26
27
28
29
30
31
32
# File 'lib/an_post_return/sftp/client.rb', line 26

def initialize(host, username, password, proxy_config = nil)
  @host = host
  @username = username
  @password = password
  @proxy_config = proxy_config
  @connected = false
end

Instance Attribute Details

#connectedObject (readonly) Also known as: connected?

SFTP connection configuration



12
13
14
# File 'lib/an_post_return/sftp/client.rb', line 12

def connected
  @connected
end

#hostObject (readonly)

SFTP connection configuration



12
13
14
# File 'lib/an_post_return/sftp/client.rb', line 12

def host
  @host
end

#passwordObject (readonly)

SFTP connection configuration



12
13
14
# File 'lib/an_post_return/sftp/client.rb', line 12

def password
  @password
end

#proxy_configObject (readonly)

SFTP connection configuration



12
13
14
# File 'lib/an_post_return/sftp/client.rb', line 12

def proxy_config
  @proxy_config
end

#usernameObject (readonly)

SFTP connection configuration



12
13
14
# File 'lib/an_post_return/sftp/client.rb', line 12

def username
  @username
end

Instance Method Details

#connectBoolean

Establish SFTP connection

Returns:

  • (Boolean)

    true if connection successful, false otherwise

Raises:



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/an_post_return/sftp/client.rb', line 38

def connect
  return true if @connected

  @ssh_session = start_ssh_session
  @sftp_client = Net::SFTP::Session.new(@ssh_session)
  @sftp_client.connect!

  @connected = true
  true
rescue Net::SSH::Exception => e
  raise ConnectionError, "Failed to connect to #{host}: #{e.message}"
end

#disconnectvoid

This method returns an undefined value.

Close SFTP connection



54
55
56
57
58
59
60
# File 'lib/an_post_return/sftp/client.rb', line 54

def disconnect
  return unless @connected

  @sftp_client.close_channel
  @ssh_session.close
  @connected = false
end

#list_files(remote_path, glob_pattern = nil) ⇒ Array<Net::SFTP::Protocol::V01::Name>

List files in remote directory

Parameters:

  • remote_path (String)

    Remote directory path

  • glob_pattern (String, nil) (defaults to: nil)

    Optional glob pattern for filtering files

Returns:

  • (Array<Net::SFTP::Protocol::V01::Name>)

    Array of file entries

Raises:



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/an_post_return/sftp/client.rb', line 95

def list_files(remote_path, glob_pattern = nil)
  ensure_connected
  entries = []

  begin
    if glob_pattern
      @sftp_client.dir.glob(remote_path, glob_pattern) { |entry| entries << entry }
    else
      @sftp_client.dir.foreach(remote_path) { |entry| entries << entry }
    end
    entries
  rescue Net::SFTP::StatusException => e
    raise FileError, "Failed to list files in #{remote_path}: #{e.message}"
  end
end

#read_file(remote_path) {|Tempfile| ... } ⇒ Tempfile, Object

Download and read a file from SFTP server

Parameters:

  • remote_path (String)

    Path to file on SFTP server

Yields:

  • (Tempfile)

    Temporary file containing downloaded content

Returns:

  • (Tempfile, Object)

    If block given, returns block result; otherwise returns Tempfile

Raises:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/an_post_return/sftp/client.rb', line 68

def read_file(remote_path)
  ensure_connected
  temp_file = Tempfile.new(["sftp", File.extname(remote_path)])

  begin
    @sftp_client.download!(remote_path, temp_file.path)
    block_given? ? yield(temp_file) : temp_file
  rescue Net::SFTP::StatusException => e
    if e.message.include?("no such file")
      raise FileNotFoundError
    else
      raise FileError, "Failed to download #{remote_path}: #{e.message}"
    end
  ensure
    unless block_given?
      temp_file.close
      temp_file.unlink
    end
  end
end