file_transfer 0.0.7 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/file_transfer/file_transfer_handler.rb +96 -96
- data/lib/file_transfer/ftp.rb +82 -82
- data/lib/file_transfer/ftps.rb +4 -4
- data/lib/file_transfer/generic.rb +58 -57
- data/lib/file_transfer/sftp.rb +65 -61
- data/lib/file_transfer/version.rb +3 -3
- data/lib/file_transfer.rb +95 -95
- data/spec/file_transfer/file_transfer_handler_spec.rb +151 -151
- data/spec/file_transfer/generic_spec.rb +66 -0
- data/spec/file_transfer/sftp_spec.rb +22 -0
- data/spec/file_transfer_spec.rb +137 -0
- data/spec/spec_helper.rb +98 -19
- metadata +118 -131
- data/spec/test_files/Chrysanthemum.jpg +0 -0
- data/spec/test_files/Desert.jpg +0 -0
- data/spec/test_files/Hydrangeas.jpg +0 -0
- data/spec/test_files/empty_file_from_sftp.csv +0 -1
- data/spec/test_files/folder1/Koala.jpg +0 -0
- data/spec/test_files/folder1/Lighthouse.jpg +0 -0
- data/spec/test_files/folder1/text_3.txt +0 -1
- data/spec/test_files/folder1/text_4.txt +0 -1
- data/spec/test_files/folder2/Jellyfish.jpg +0 -0
- data/spec/test_files/folder2/Penguins.jpg +0 -0
- data/spec/test_files/folder2/Tulips.jpg +0 -0
- data/spec/test_files/folder2/text_1.txt +0 -1
- data/spec/test_files/folder2/text_6.txt +0 -1
- data/spec/test_files/text_1.txt +0 -1
- data/spec/test_files/text_2.txt +0 -1
@@ -1,97 +1,97 @@
|
|
1
|
-
module FileTransfer
|
2
|
-
|
3
|
-
class FileTransferHandler
|
4
|
-
|
5
|
-
def initialize(type, options)
|
6
|
-
@type = type
|
7
|
-
@options = options
|
8
|
-
@ftp_obj = get_ftp_obj type, options
|
9
|
-
end
|
10
|
-
|
11
|
-
def upload(paths)
|
12
|
-
paths = normalize_paths paths
|
13
|
-
all_file_paths = []
|
14
|
-
# Loop over Path Specs
|
15
|
-
paths.each do |path|
|
16
|
-
# Make sure it's an Array of from-Paths
|
17
|
-
path[:from] = [path[:from]] unless path[:from].kind_of?(Array) && path[:from][0].kind_of?(Array)
|
18
|
-
# Loop over Path From Specs
|
19
|
-
path[:from].each do |path_pattern|
|
20
|
-
path_pattern = [path_pattern] unless path_pattern.kind_of?(Array)
|
21
|
-
file_paths = []
|
22
|
-
if File.exists?(path_pattern[0]) && File.directory?(path_pattern[0])
|
23
|
-
path_pattern[1] = "*.*" if path_pattern.length < 2
|
24
|
-
Dir.chdir(path_pattern[0])
|
25
|
-
file_paths = Dir.glob(path_pattern[1])
|
26
|
-
elsif File.exists?(path_pattern[0])
|
27
|
-
file_paths = [path_pattern[0]]
|
28
|
-
end
|
29
|
-
file_paths.each do |file_path|
|
30
|
-
_upload file_path, path[:to]
|
31
|
-
all_file_paths.push file_path
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
all_file_paths
|
36
|
-
end
|
37
|
-
|
38
|
-
def download(paths)
|
39
|
-
paths = normalize_paths paths
|
40
|
-
all_file_paths = []
|
41
|
-
# Loop over Path Specs
|
42
|
-
paths.each do |path|
|
43
|
-
# Make sure it's an Array of from-Paths
|
44
|
-
path[:from] = [path[:from]] unless path[:from].kind_of?(Array) && path[:from][0].kind_of?(Array)
|
45
|
-
# Loop over Path From Specs
|
46
|
-
path[:from].each do |path_pattern|
|
47
|
-
_download path_pattern, path[:to]
|
48
|
-
all_file_paths.push path_pattern
|
49
|
-
end
|
50
|
-
end
|
51
|
-
all_file_paths
|
52
|
-
end
|
53
|
-
|
54
|
-
def list(path)
|
55
|
-
@ftp_obj.list path
|
56
|
-
end
|
57
|
-
|
58
|
-
def remove(path)
|
59
|
-
@ftp_obj.remove path
|
60
|
-
end
|
61
|
-
|
62
|
-
def rename(from_path, to_path)
|
63
|
-
@ftp_obj.rename from_path, to_path
|
64
|
-
end
|
65
|
-
|
66
|
-
def close
|
67
|
-
@ftp_obj.close
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def normalize_paths(paths)
|
73
|
-
response = paths.kind_of?(Array) ? paths : [paths]
|
74
|
-
Marshal.load(Marshal.dump(response))
|
75
|
-
end
|
76
|
-
|
77
|
-
def get_ftp_obj(type, options)
|
78
|
-
if type == :ftp
|
79
|
-
Ftp.new options
|
80
|
-
elsif type == :sftp
|
81
|
-
Sftp.new options
|
82
|
-
elsif type == :ftps
|
83
|
-
Ftps.new options
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
def _upload(from_path, to_path)
|
88
|
-
@ftp_obj.upload from_path, to_path
|
89
|
-
end
|
90
|
-
|
91
|
-
def _download(from_path, to_path)
|
92
|
-
@ftp_obj.download from_path, to_path
|
93
|
-
end
|
94
|
-
|
95
|
-
end
|
96
|
-
|
1
|
+
module FileTransfer
|
2
|
+
|
3
|
+
class FileTransferHandler
|
4
|
+
|
5
|
+
def initialize(type, options)
|
6
|
+
@type = type
|
7
|
+
@options = options
|
8
|
+
@ftp_obj = get_ftp_obj type, options
|
9
|
+
end
|
10
|
+
|
11
|
+
def upload(paths)
|
12
|
+
paths = normalize_paths paths
|
13
|
+
all_file_paths = []
|
14
|
+
# Loop over Path Specs
|
15
|
+
paths.each do |path|
|
16
|
+
# Make sure it's an Array of from-Paths
|
17
|
+
path[:from] = [path[:from]] unless path[:from].kind_of?(Array) && path[:from][0].kind_of?(Array)
|
18
|
+
# Loop over Path From Specs
|
19
|
+
path[:from].each do |path_pattern|
|
20
|
+
path_pattern = [path_pattern] unless path_pattern.kind_of?(Array)
|
21
|
+
file_paths = []
|
22
|
+
if File.exists?(path_pattern[0]) && File.directory?(path_pattern[0])
|
23
|
+
path_pattern[1] = "*.*" if path_pattern.length < 2
|
24
|
+
Dir.chdir(path_pattern[0])
|
25
|
+
file_paths = Dir.glob(path_pattern[1])
|
26
|
+
elsif File.exists?(path_pattern[0])
|
27
|
+
file_paths = [path_pattern[0]]
|
28
|
+
end
|
29
|
+
file_paths.each do |file_path|
|
30
|
+
_upload file_path, path[:to]
|
31
|
+
all_file_paths.push file_path
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
all_file_paths
|
36
|
+
end
|
37
|
+
|
38
|
+
def download(paths)
|
39
|
+
paths = normalize_paths paths
|
40
|
+
all_file_paths = []
|
41
|
+
# Loop over Path Specs
|
42
|
+
paths.each do |path|
|
43
|
+
# Make sure it's an Array of from-Paths
|
44
|
+
path[:from] = [path[:from]] unless path[:from].kind_of?(Array) && path[:from][0].kind_of?(Array)
|
45
|
+
# Loop over Path From Specs
|
46
|
+
path[:from].each do |path_pattern|
|
47
|
+
_download path_pattern, path[:to]
|
48
|
+
all_file_paths.push path_pattern
|
49
|
+
end
|
50
|
+
end
|
51
|
+
all_file_paths
|
52
|
+
end
|
53
|
+
|
54
|
+
def list(path)
|
55
|
+
@ftp_obj.list path
|
56
|
+
end
|
57
|
+
|
58
|
+
def remove(path)
|
59
|
+
@ftp_obj.remove path
|
60
|
+
end
|
61
|
+
|
62
|
+
def rename(from_path, to_path)
|
63
|
+
@ftp_obj.rename from_path, to_path
|
64
|
+
end
|
65
|
+
|
66
|
+
def close
|
67
|
+
@ftp_obj.close
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def normalize_paths(paths)
|
73
|
+
response = paths.kind_of?(Array) ? paths : [paths]
|
74
|
+
Marshal.load(Marshal.dump(response))
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_ftp_obj(type, options)
|
78
|
+
if type == :ftp
|
79
|
+
Ftp.new options
|
80
|
+
elsif type == :sftp
|
81
|
+
Sftp.new options
|
82
|
+
elsif type == :ftps
|
83
|
+
Ftps.new options
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def _upload(from_path, to_path)
|
88
|
+
@ftp_obj.upload from_path, to_path
|
89
|
+
end
|
90
|
+
|
91
|
+
def _download(from_path, to_path)
|
92
|
+
@ftp_obj.download from_path, to_path
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
97
|
end
|
data/lib/file_transfer/ftp.rb
CHANGED
@@ -1,83 +1,83 @@
|
|
1
|
-
require "net/ftp"
|
2
|
-
|
3
|
-
module FileTransfer
|
4
|
-
class Ftp < Generic
|
5
|
-
|
6
|
-
def initialize(options = {})
|
7
|
-
super(options)
|
8
|
-
end
|
9
|
-
|
10
|
-
def list(dir, options = {})
|
11
|
-
connect if @ftp.closed?
|
12
|
-
timeout(60) do
|
13
|
-
@ftp.chdir dir
|
14
|
-
result = @ftp.nlst
|
15
|
-
if options.has_key? :file_type
|
16
|
-
result = result.select { |file_name| file_name.end_with? options[:file_type] }
|
17
|
-
end
|
18
|
-
result
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def upload(from_path, to_path)
|
23
|
-
to_path = split_path(to_path)
|
24
|
-
connect if @ftp.closed?
|
25
|
-
timeout(timeout_seconds) do
|
26
|
-
@ftp.chdir to_path[:file_path]
|
27
|
-
@ftp.putbinaryfile(from_path)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def download(from_path, to_path)
|
32
|
-
from_path = split_path(from_path)
|
33
|
-
connect if @ftp.closed?
|
34
|
-
timeout(timeout_seconds) do
|
35
|
-
@ftp.chdir from_path[:file_path]
|
36
|
-
@ftp.getbinaryfile(to_path, from_path[:file_name])
|
37
|
-
"#{from_path[:file_path]}/#{from_path[:file_name]}"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def move(from_path, to_path)
|
42
|
-
from_path = split_path(from_path)
|
43
|
-
to_path = split_path(to_path)
|
44
|
-
connect if @ftp.closed?
|
45
|
-
timeout(timeout_seconds) do
|
46
|
-
@ftp.chdir from_path[:file_path]
|
47
|
-
@ftp.rename from_path[:file_name], "#{to_path[:file_path]}/#{to_path[:file_name]}" if exist?("#{from_path[:file_name]}/#{from_path[:file_path]}")
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def exist?(file_path)
|
52
|
-
connect if @ftp.closed?
|
53
|
-
timeout(60) do
|
54
|
-
result = @ftp.list "#{file_path}"
|
55
|
-
result && result.size > 0
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def close
|
60
|
-
if @ftp && !@ftp.closed?
|
61
|
-
timeout(30) do
|
62
|
-
@ftp.close
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
protected
|
68
|
-
|
69
|
-
def closed?
|
70
|
-
!@ftp || @ftp.closed?
|
71
|
-
end
|
72
|
-
|
73
|
-
def connect
|
74
|
-
timeout(30) do
|
75
|
-
@ftp ||= Net::FTP.new
|
76
|
-
@ftp.passive = true
|
77
|
-
@ftp.connect(@host, @port)
|
78
|
-
@ftp.login(@username, @password) if @username && @password
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
1
|
+
require "net/ftp"
|
2
|
+
|
3
|
+
module FileTransfer
|
4
|
+
class Ftp < Generic
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
super(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def list(dir, options = {})
|
11
|
+
connect if @ftp.closed?
|
12
|
+
timeout(60) do
|
13
|
+
@ftp.chdir dir
|
14
|
+
result = @ftp.nlst
|
15
|
+
if options.has_key? :file_type
|
16
|
+
result = result.select { |file_name| file_name.end_with? options[:file_type] }
|
17
|
+
end
|
18
|
+
result
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def upload(from_path, to_path)
|
23
|
+
to_path = split_path(to_path)
|
24
|
+
connect if @ftp.closed?
|
25
|
+
timeout(timeout_seconds) do
|
26
|
+
@ftp.chdir to_path[:file_path]
|
27
|
+
@ftp.putbinaryfile(from_path)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def download(from_path, to_path)
|
32
|
+
from_path = split_path(from_path)
|
33
|
+
connect if @ftp.closed?
|
34
|
+
timeout(timeout_seconds) do
|
35
|
+
@ftp.chdir from_path[:file_path]
|
36
|
+
@ftp.getbinaryfile(to_path, from_path[:file_name])
|
37
|
+
"#{from_path[:file_path]}/#{from_path[:file_name]}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def move(from_path, to_path)
|
42
|
+
from_path = split_path(from_path)
|
43
|
+
to_path = split_path(to_path)
|
44
|
+
connect if @ftp.closed?
|
45
|
+
timeout(timeout_seconds) do
|
46
|
+
@ftp.chdir from_path[:file_path]
|
47
|
+
@ftp.rename from_path[:file_name], "#{to_path[:file_path]}/#{to_path[:file_name]}" if exist?("#{from_path[:file_name]}/#{from_path[:file_path]}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def exist?(file_path)
|
52
|
+
connect if @ftp.closed?
|
53
|
+
timeout(60) do
|
54
|
+
result = @ftp.list "#{file_path}"
|
55
|
+
result && result.size > 0
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def close
|
60
|
+
if @ftp && !@ftp.closed?
|
61
|
+
timeout(30) do
|
62
|
+
@ftp.close
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def closed?
|
70
|
+
!@ftp || @ftp.closed?
|
71
|
+
end
|
72
|
+
|
73
|
+
def connect
|
74
|
+
timeout(30) do
|
75
|
+
@ftp ||= Net::FTP.new
|
76
|
+
@ftp.passive = true
|
77
|
+
@ftp.connect(@host, @port)
|
78
|
+
@ftp.login(@username, @password) if @username && @password
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
83
|
end
|
data/lib/file_transfer/ftps.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
module FileTransfer
|
2
|
-
class Ftps
|
3
|
-
# To change this template use File | Settings | File Templates.
|
4
|
-
end
|
1
|
+
module FileTransfer
|
2
|
+
class Ftps
|
3
|
+
# To change this template use File | Settings | File Templates.
|
4
|
+
end
|
5
5
|
end
|
@@ -1,57 +1,58 @@
|
|
1
|
-
module FileTransfer
|
2
|
-
|
3
|
-
class Generic
|
4
|
-
|
5
|
-
attr_accessor :host, :username, :password, :port, :timeout_seconds
|
6
|
-
|
7
|
-
def initialize(options = {})
|
8
|
-
@host = options[:host] ||
|
9
|
-
@username = options[:username] ||
|
10
|
-
@password = options[:password] ||
|
11
|
-
@
|
12
|
-
@
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
1
|
+
module FileTransfer
|
2
|
+
|
3
|
+
class Generic
|
4
|
+
|
5
|
+
attr_accessor :host, :username, :password, :keys, :port, :timeout_seconds
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
@host = options[:host] || 'localhost'
|
9
|
+
@username = options[:username] || 'anonymous'
|
10
|
+
@password = options[:password] || ''
|
11
|
+
@keys = options[:keys].to_s.split(',') || []
|
12
|
+
@port = options[:port] || 21
|
13
|
+
@timeout_seconds = options[:timeout] || 300
|
14
|
+
end
|
15
|
+
|
16
|
+
def list(dir, filter = '')
|
17
|
+
end
|
18
|
+
|
19
|
+
def upload(from_path, to_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
def download(from_path, to_path)
|
23
|
+
end
|
24
|
+
|
25
|
+
def move(file_name, from_dir, to_dir)
|
26
|
+
end
|
27
|
+
|
28
|
+
def exist?(file_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def close
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
"FtpClient {@host => #{host}, @username => #{username}, @protocol => #{type}, @port => #{port}, @password => ***}"
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def split_path(path)
|
41
|
+
{:file_path => File.dirname(path), :file_name => File.basename(path)}
|
42
|
+
end
|
43
|
+
|
44
|
+
def timeout(seconds, &block)
|
45
|
+
Timeout.timeout(seconds.to_i) do
|
46
|
+
block.call(Hash.new)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def connect
|
51
|
+
end
|
52
|
+
|
53
|
+
def closed?
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/lib/file_transfer/sftp.rb
CHANGED
@@ -1,62 +1,66 @@
|
|
1
|
-
module FileTransfer
|
2
|
-
|
3
|
-
class Sftp < Generic
|
4
|
-
|
5
|
-
def initialize(options = {})
|
6
|
-
options[:port] ||= 22
|
7
|
-
super(options)
|
8
|
-
end
|
9
|
-
|
10
|
-
def download(from_path, to_path)
|
11
|
-
connect if closed?
|
12
|
-
timeout(timeout_seconds) do
|
13
|
-
@sftp.download! from_path, to_path
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def upload(from_path, to_path)
|
18
|
-
connect if closed?
|
19
|
-
timeout(timeout_seconds) do
|
20
|
-
@sftp.upload! from_path, to_path
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def list(path)
|
25
|
-
connect if closed?
|
26
|
-
timeout(60) do
|
27
|
-
@sftp.dir.entries path
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def remove(path)
|
32
|
-
connect if closed?
|
33
|
-
timeout(60) do
|
34
|
-
@sftp.remove! path
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def rename(from_path, to_path)
|
39
|
-
connect if closed?
|
40
|
-
timeout(60) do
|
41
|
-
@sftp.rename! from_path, to_path
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def close
|
46
|
-
# do nothing
|
47
|
-
end
|
48
|
-
|
49
|
-
protected
|
50
|
-
|
51
|
-
def connect
|
52
|
-
timeout(60) do
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
|
1
|
+
module FileTransfer
|
2
|
+
|
3
|
+
class Sftp < Generic
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
options[:port] ||= 22
|
7
|
+
super(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
def download(from_path, to_path)
|
11
|
+
connect if closed?
|
12
|
+
timeout(timeout_seconds) do
|
13
|
+
@sftp.download! from_path, to_path
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def upload(from_path, to_path)
|
18
|
+
connect if closed?
|
19
|
+
timeout(timeout_seconds) do
|
20
|
+
@sftp.upload! from_path, to_path
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def list(path)
|
25
|
+
connect if closed?
|
26
|
+
timeout(60) do
|
27
|
+
@sftp.dir.entries path
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def remove(path)
|
32
|
+
connect if closed?
|
33
|
+
timeout(60) do
|
34
|
+
@sftp.remove! path
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def rename(from_path, to_path)
|
39
|
+
connect if closed?
|
40
|
+
timeout(60) do
|
41
|
+
@sftp.rename! from_path, to_path
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def close
|
46
|
+
# do nothing
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
|
51
|
+
def connect
|
52
|
+
timeout(60) do
|
53
|
+
if keys.empty?
|
54
|
+
@sftp = Net::SFTP.start(host, username, :password => password, :port => port)
|
55
|
+
else
|
56
|
+
@sftp = Net::SFTP.start(host, username, :keys => keys, :port => port)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def closed?
|
62
|
+
!@sftp || @sftp.closed?
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
62
66
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
module FileTransfer # :nodoc:
|
2
|
-
VERSION =
|
3
|
-
end
|
1
|
+
module FileTransfer # :nodoc:
|
2
|
+
VERSION = '0.0.9' # :nodoc:
|
3
|
+
end
|