Class: FtpAdapter

Inherits:
Object
  • Object
show all
Defined in:
lib/piggy-core/ftp_adapter.rb

Overview

This is a wrapper around Net::FTP. It has a different interface and introduces two additional timeouts. Configure the timeouts and other parameters through PiggyOptions.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ FtpAdapter

Returns a new instance of FtpAdapter.



15
16
17
18
# File 'lib/piggy-core/ftp_adapter.rb', line 15

def initialize(options)
  @connection = nil
  @options = options # some options may change any time
end

Instance Attribute Details

#hostObject

Returns the value of attribute host.



13
14
15
# File 'lib/piggy-core/ftp_adapter.rb', line 13

def host
  @host
end

#passwordObject

Returns the value of attribute password.



13
14
15
# File 'lib/piggy-core/ftp_adapter.rb', line 13

def password
  @password
end

#userObject

Returns the value of attribute user.



13
14
15
# File 'lib/piggy-core/ftp_adapter.rb', line 13

def user
  @user
end

Instance Method Details

#chdir(path) ⇒ Object



32
33
34
35
36
# File 'lib/piggy-core/ftp_adapter.rb', line 32

def chdir(path)
  if path && !path.empty?
    c_timeout { @connection.chdir(path) }
  end
end

#closeObject



144
145
146
# File 'lib/piggy-core/ftp_adapter.rb', line 144

def close
  @connection.close unless @connection.nil?
end

#closed?Boolean

Returns:

  • (Boolean)


148
149
150
# File 'lib/piggy-core/ftp_adapter.rb', line 148

def closed?
  @connection.nil? or @connection.closed?
end

#connect(host, user, password) ⇒ Object



20
21
22
23
24
25
# File 'lib/piggy-core/ftp_adapter.rb', line 20

def connect(host, user, password)
  @host = host
  @user = user
  @password = password
  reconnect
end

#delete(file) ⇒ Object



60
61
62
# File 'lib/piggy-core/ftp_adapter.rb', line 60

def delete(file)
  c_timeout { @connection.delete(file) }
end

#info(file, path) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/piggy-core/ftp_adapter.rb', line 42

def info(file, path)
  info = FileInfo.new(file, path)
  begin
    mtime = c_timeout {
      @connection.mtime(file, @options.ftpHasLocaltime?)
    }
    mtime = mtime.localtime unless @options.ftpHasLocaltime?
    info.mtime = mtime
  rescue Net::FTPError
    info.directory!
  end
  info
end

#mkdir(dir) ⇒ Object



56
57
58
# File 'lib/piggy-core/ftp_adapter.rb', line 56

def mkdir(dir)
  c_timeout { @connection.mkdir(dir) }
end

#nlstObject



38
39
40
# File 'lib/piggy-core/ftp_adapter.rb', line 38

def nlst
  c_timeout { @connection.nlst }
end

#putbinaryfile(file, &block) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/piggy-core/ftp_adapter.rb', line 125

def putbinaryfile(file, &block)
  aborted = false
  alive_checker = AliveCheck.new(@options.ftpTransferTimeout,
    "ftp transfer timeout")
  alive_checker.check do
    @connection.putbinaryfile(file) { |data|
      alive_checker.alive!
      if block.call(data)
        print "."
      else
        # @connection.abort would cause Errno::EINVAL later on
        aborted = true
        break 
      end
    }
  end
  return !aborted
end

#reconnectObject



27
28
29
30
# File 'lib/piggy-core/ftp_adapter.rb', line 27

def reconnect
  c_timeout { @connection = Net::FTP.open(@host, @user, @password) }
  @connection.debug_mode = @options.debug    
end

#rmdir(dir) ⇒ Object



64
65
66
# File 'lib/piggy-core/ftp_adapter.rb', line 64

def rmdir(dir)
  c_timeout { @connection.rmdir(dir) }
end

#upload(local_path, file, &block) ⇒ Object

Upload with progress events.

Example:

upload('C:\tmp', 'C:\tmp\bla\big.zip') {
  |data|
  ...
  data.size
  ...
}

This will create a remote file bla/big.zip and every chunk of transferred data will be given to the block.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/piggy-core/ftp_adapter.rb', line 80

def upload(local_path, file, &block)
  puts "FtpAdapter\#upload #{file}"
  depth_offset = FilePath.split(local_path).size
  path_sections = FilePath.split(file)
  dirs = path_sections[depth_offset..-2]
  pwd = c_timeout { @connection.pwd } 
  unless dirs == nil
    dirs.each do
      |dir|
      begin
        chdir(dir)
      rescue Net::FTPError
        mkdir(dir)
        chdir(dir)
      end
    end
  end
  if(putbinaryfile(file, &block))
    unless dirs == nil
      dirs.each { |dir| chdir('..') }
    end
    puts "Done"
  else
    begin
      puts "Abortion delete: #{file}"
      reconnect
      chdir(pwd + dirs.join("/"))
      puts(@connection.pwd)
      delete(File.basename(file))
      puts "Abortion delete done"
    rescue StandardError => ex
      puts "Abortion delete failed"
      puts "#{ex.class.to_s}: #{ex.message}"
    ensure
      # force cleanup after error or abortion
      begin
        c_timeout { @connection.close }
      rescue StandardError => ex
        puts "Abortion cleanup failed"
        puts "#{ex.class.to_s}: #{ex.message}"
      end
    end
  end
end