file_transfer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,85 @@
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 close
55
+ @ftp_obj.close
56
+ end
57
+
58
+ private
59
+
60
+ def normalize_paths(paths)
61
+ response = paths.kind_of?(Array) ? paths : [paths]
62
+ Marshal.load(Marshal.dump(response))
63
+ end
64
+
65
+ def get_ftp_obj(type, options)
66
+ if type == :ftp
67
+ Ftp.new options
68
+ elsif type == :sftp
69
+ Sftp.new options
70
+ elsif type == :ftps
71
+ Ftps.new options
72
+ end
73
+ end
74
+
75
+ def _upload(from_path, to_path)
76
+ @ftp_obj.upload from_path, to_path
77
+ end
78
+
79
+ def _download(from_path, to_path)
80
+ @ftp_obj.download from_path, to_path
81
+ end
82
+
83
+ end
84
+
85
+ end
@@ -0,0 +1,83 @@
1
+ require "net/ftp"
2
+
3
+ module FileTransfer
4
+ class Ftp < Generic
5
+
6
+ def initialize(options = {})
7
+ super(options)
8
+ @ftp = Net::FTP.new
9
+ @ftp.passive = true
10
+ end
11
+
12
+ def list(dir, options = {})
13
+ connect if @ftp.closed?
14
+ timeout(60) do
15
+ @ftp.chdir dir
16
+ result = @ftp.nlst
17
+ if options.has_key? :file_type
18
+ result = result.select { |file_name| file_name.end_with? options[:file_type] }
19
+ end
20
+ result
21
+ end
22
+ end
23
+
24
+ def upload(from_path, to_path)
25
+ to_path = split_path(to_path)
26
+ connect if @ftp.closed?
27
+ timeout(300) do
28
+ @ftp.chdir to_path[:file_path]
29
+ @ftp.putbinaryfile(from_path)
30
+ end
31
+ end
32
+
33
+ def download(from_path, to_path)
34
+ from_path = split_path(from_path)
35
+ connect if @ftp.closed?
36
+ timeout(300) do
37
+ @ftp.chdir from_path[:file_path]
38
+ @ftp.getbinaryfile(to_path, from_path[:file_name])
39
+ "#{from_path[:file_path]}/#{from_path[:file_name]}"
40
+ end
41
+ end
42
+
43
+ def move(from_path, to_path)
44
+ from_path = split_path(from_path)
45
+ to_path = split_path(to_path)
46
+ connect if @ftp.closed?
47
+ timeout(60) do
48
+ @ftp.chdir from_path[:file_path]
49
+ @ftp.rename from_path[:file_name], "#{to_path[:file_path]}/#{to_path[:file_name]}" if exist?("#{from_path[:file_name]}/#{from_path[:file_path]}")
50
+ end
51
+ end
52
+
53
+ def exist?(file_path)
54
+ connect if @ftp.closed?
55
+ timeout(60) do
56
+ result = @ftp.list "#{file_path}"
57
+ result && result.size > 0
58
+ end
59
+ end
60
+
61
+ def close
62
+ unless @ftp.closed?
63
+ timeout(30) do
64
+ @ftp.close
65
+ end
66
+ end
67
+ end
68
+
69
+ def to_s
70
+ "FtpClient {@host => #{@host}, @username => #{@username}, @password => ***}"
71
+ end
72
+
73
+ private
74
+ def connect
75
+ timeout(30) do
76
+ @ftp.connect(@host, @port)
77
+ @ftp.login(@username, @password) if @username && @password
78
+ end
79
+ end
80
+
81
+
82
+ end
83
+ end
@@ -0,0 +1,5 @@
1
+ module FileTransfer
2
+ class Ftps
3
+ # To change this template use File | Settings | File Templates.
4
+ end
5
+ end
@@ -0,0 +1,49 @@
1
+ module FileTransfer
2
+
3
+ class Generic
4
+
5
+ attr_accessor :host, :username, :password, :port
6
+
7
+ def initialize(options = {})
8
+ @host = options[:host] || "localhost"
9
+ @username = options[:username] || "anonymous"
10
+ @password = options[:password] || ""
11
+ @port = options[:port] || 21
12
+ end
13
+
14
+ def list(dir, filter="")
15
+ end
16
+
17
+ def upload(from_path, to_path)
18
+ end
19
+
20
+ def download(from_path, to_path)
21
+ end
22
+
23
+ def move(file_name, from_dir, to_dir)
24
+ end
25
+
26
+ def exist?(file_path)
27
+ end
28
+
29
+ def close
30
+ end
31
+
32
+ protected
33
+
34
+ def split_path(path)
35
+ {:file_path => File.dirname(path), :file_name => File.basename(path)}
36
+ end
37
+
38
+ def timeout(seconds, &block)
39
+ Timeout.timeout(seconds.to_i) do
40
+ block.call(Hash.new)
41
+ end
42
+ end
43
+
44
+ def connect
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,32 @@
1
+ module FileTransfer
2
+
3
+ class Sftp < Generic
4
+
5
+ def initialize(options = {})
6
+ options[:port] ||= 22
7
+ super(options)
8
+ connect
9
+ end
10
+
11
+ def download(from_path, to_path)
12
+ @sftp.download! from_path, to_path
13
+ end
14
+
15
+ def upload(from_path, to_path)
16
+ @sftp.upload! from_path, to_path
17
+ end
18
+
19
+ private
20
+
21
+ def connect
22
+ @sftp = Net::SFTP.start(@host, @username, :password => @password, :port => @port)
23
+ end
24
+
25
+ def timeout(seconds, &block)
26
+ Timeout.timeout(seconds.to_i) do
27
+ block.call
28
+ end
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ module FileTransfer # :nodoc:
2
+ VERSION = "0.0.1" # :nodoc:
3
+ end
@@ -0,0 +1,71 @@
1
+ require "file_transfer/version"
2
+ require "file_transfer/file_transfer_handler"
3
+ require "file_transfer/generic"
4
+ require "file_transfer/ftp"
5
+ require "file_transfer/sftp"
6
+ require "file_transfer/ftps"
7
+ require "net/ftp"
8
+ require "net/sftp"
9
+
10
+ ##
11
+ # Module for file exchange from a locale directory to a remote directory and vice versa. Supported protocols are:
12
+ #
13
+ # * FTP
14
+ # * SFTP
15
+ # * FTPS
16
+
17
+ module FileTransfer
18
+
19
+ ##
20
+ # Uploads one or more files to a remote server. To upload files use the locale file paths, not the ruby class File.
21
+ # Types are:
22
+ # * <tt>:ftp</tt> - for FTP file upload
23
+ # * <tt>:ftps</tt> - for FTPS file upload
24
+ # * <tt>:sftp</tt> - for SFTP file upload
25
+ #
26
+ # Options are:
27
+ # * <tt>:username</tt> - Specifies the username for login to the remote server
28
+ # * <tt>:password</tt> - Specifies the password for login to the remote server
29
+ # * <tt>:host</tt> - Specifies the name of the remote server. It could be a DNS name or an IP-Address
30
+ # these options are not necessary.
31
+ # * <tt>:port</tt> - Specifies the port of the remote server. If the remote server listen on the default port,
32
+ # * <tt>:timeout</tt> - If connection hangs, it is possible to define a timeout in seconds here, where the connection
33
+ # will be automatically closed.
34
+ #
35
+ # ==Examples
36
+ # <tt>FileTransfer.upload :ftp,
37
+ # {:username => 'foo', :password => 'bar', :host => 'localhost'}, [
38
+ # {:from => "/local/1.txt", :to => "/remote/uploads/a_1.txt"},
39
+ # {:from => "/local/", :to => "/remote/uploads/"},
40
+ # {:from => "/local/pdf/*.pdf", :to => "/remote/uploads/pdf/"},
41
+ # {:from => ["/local/1.txt", "/local/2.txt", "/local/txt/*.txt"], :to => "/remote/uploads/txt/"}
42
+ # ]
43
+ # </tt>
44
+
45
+ def self.upload(type, options, paths)
46
+ handler = FileTransferHandler.new type, options
47
+ handler.upload paths
48
+ handler.close
49
+ end
50
+
51
+ # <tt>FileTransfer.download :ftp,
52
+ # {:username => 'foo', :password => 'bar', :host => 'localhost'}, [
53
+ # {:from => "/remote/uploads/a_1.txt", :to => "/local/1.txt"},
54
+ # {:from => "/remote/uploads/pdf/*.pdf", :to => "/local/pdf/"},
55
+ # {:from => ["/remote/uploads/a_1.txt", "/remote/uploads/a_2.txt", "/remote/uploads/txt/*.txt"], :to => "/local/txt/"}
56
+ # ]
57
+ # </tt>
58
+
59
+ def self.download(type, options, paths)
60
+ handler = FileTransferHandler.new type, options
61
+ handler.download paths
62
+ handler.close
63
+ end
64
+
65
+ def self.exists?(type, options, path)
66
+ handler = FileTransferHandler.new type, options
67
+ handler.exists? path
68
+ handler.close
69
+ end
70
+
71
+ end
@@ -0,0 +1,132 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.configure do |c|
4
+ c.filter_run_excluding :transaction => true
5
+ end
6
+
7
+ module FileTransfer
8
+
9
+ describe FileTransferHandler do
10
+
11
+ describe "#_upload", :transaction => true do
12
+
13
+ end
14
+
15
+ describe "#upload" do
16
+
17
+ it "should return an Array of JPG Files from one Folder" do
18
+ instance = FileTransferHandler.new :ftp, {}
19
+ this_path = File.dirname(__FILE__)
20
+ paths = {:from => ["#{this_path}/../test_files/folder2", "*.jpg"], :to => "/remote_path/"}
21
+ instance.stub(:_upload).and_return(true)
22
+ result = instance.upload(paths)
23
+ Dir.chdir(paths[:from][0])
24
+ result_array = Dir[paths[:from][1]]
25
+ result.should be_kind_of(Array)
26
+ result.should match_array(result_array)
27
+
28
+ puts "--BEGIN OF TEST"
29
+ puts result
30
+ puts "--END OF TEST"
31
+ end
32
+
33
+ it "should return an Array of JPG Files from all Subfolders incl. Root-Folder" do
34
+ instance = FileTransferHandler.new :ftp, {}
35
+ this_path = File.dirname(__FILE__)
36
+ paths = {:from => ["#{this_path}/../test_files/", "**/*.jpg"], :to => "/remote_path/"}
37
+ instance.stub(:_upload).and_return(true)
38
+ result = instance.upload(paths)
39
+ Dir.chdir(paths[:from][0])
40
+ result_array = Dir[paths[:from][1]]
41
+ result.should be_kind_of(Array)
42
+ result.should match_array(result_array)
43
+
44
+ puts "--BEGIN OF TEST"
45
+ puts result
46
+ puts "--END OF TEST"
47
+ end
48
+
49
+ it "should upload a test-file to OTTO SFTP" do
50
+ instance = FileTransferHandler.new :sftp, {
51
+ :host => "sftp-dmz.otto.de",
52
+ :username => "eosch",
53
+ :password => "hot}Orm1",
54
+ :port => 22
55
+ }
56
+ this_path = File.dirname(__FILE__)
57
+ paths = {:from => "#{this_path}/../test_files/empty_file.csv", :to => "/eosch/in/test/empty_file_1.csv"}
58
+ result = instance.upload(paths)
59
+ Dir.chdir("#{this_path}/../test_files/")
60
+ result_array = Dir["*.csv"]
61
+
62
+ result.should be_kind_of(Array)
63
+ #result.should match_array(result_array)
64
+
65
+ puts "--BEGIN OF TEST"
66
+ puts result
67
+ puts "--END OF TEST"
68
+ end
69
+
70
+ it "should download the test-file from OTTO SFTP" do
71
+ instance = FileTransferHandler.new :sftp, {
72
+ :host => "sftp-dmz.otto.de",
73
+ :username => "eosch",
74
+ :password => "hot}Orm1",
75
+ :port => 22
76
+ }
77
+ this_path = File.dirname(__FILE__)
78
+ paths = {:from => "/eosch/in/test/empty_file_1.csv", :to => "#{this_path}/../test_files/empty_file_from_sftp.csv"}
79
+ result = instance.download(paths)
80
+ Dir.chdir("#{this_path}/../test_files/")
81
+ result_array = Dir["*.csv"]
82
+
83
+ result.should be_kind_of(Array)
84
+ #result.should match_array(result_array)
85
+
86
+ puts "--BEGIN OF TEST"
87
+ puts result
88
+ puts "--END OF TEST"
89
+ end
90
+
91
+ #it "should return an Array of various Files" do
92
+ # instance = FileTransferHandler.new :ftp, {}
93
+ # this_path = File.dirname(__FILE__)
94
+ # paths = [
95
+ # {:from => [
96
+ # ["#{this_path}/../test_files/", "**/*.txt"],
97
+ # "#{this_path}/../test_files/folder1/"
98
+ # ],
99
+ # :to => "/remote_path/"
100
+ # },
101
+ # {:from => ["#{this_path}/../test_files/folder2/", "[jt]*.jpg"], :to => "/remote_path/"}
102
+ # ]
103
+ #
104
+ # instance.stub(:_upload).and_return(true)
105
+ # result = instance.upload(paths)
106
+ #
107
+ # Dir.chdir(paths[0][:from][0][0])
108
+ # result_array = Dir[paths[0][:from][0][1]]
109
+ #
110
+ # Dir.chdir(paths[0][:from][1])
111
+ # Dir["*.*"].each do |f|
112
+ # result_array.push f
113
+ # end
114
+ #
115
+ # Dir.chdir(paths[1][:from][0])
116
+ # Dir[paths[1][:from][1]].each do |f|
117
+ # result_array.push f
118
+ # end
119
+ #
120
+ # result.should be_kind_of(Array)
121
+ # result.should match_array(result_array)
122
+ #
123
+ # puts "--BEGIN OF TEST"
124
+ # puts result
125
+ # puts "--END OF TEST"
126
+ #end
127
+
128
+ end
129
+
130
+ end
131
+
132
+ end
@@ -0,0 +1,19 @@
1
+ require "file_transfer"
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # Require this file using `require "spec_helper"` to ensure that it is only
6
+ # loaded once.
7
+ #
8
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+
14
+ # Run specs in random order to surface order dependencies. If you find an
15
+ # order dependency and want to debug it, you can fix the order by providing
16
+ # the seed, which is printed after each run.
17
+ # --seed 1234
18
+ config.order = 'random'
19
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ COL1,COL2,COL3
Binary file
@@ -0,0 +1 @@
1
+ abc
@@ -0,0 +1 @@
1
+ abc
Binary file
@@ -0,0 +1 @@
1
+ abc
@@ -0,0 +1 @@
1
+ abc
@@ -0,0 +1 @@
1
+ abc
@@ -0,0 +1 @@
1
+ abc
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: file_transfer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - impac GmbH
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-29 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: jruby-pageant
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: net-sftp
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: File Transfer Handler for multiple Protocols
79
+ email:
80
+ - info@impac.ch
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - lib/file_transfer/file_transfer_handler.rb
86
+ - lib/file_transfer/ftp.rb
87
+ - lib/file_transfer/ftps.rb
88
+ - lib/file_transfer/generic.rb
89
+ - lib/file_transfer/sftp.rb
90
+ - lib/file_transfer/version.rb
91
+ - lib/file_transfer.rb
92
+ - spec/file_transfer/file_transfer_handler_spec.rb
93
+ - spec/spec_helper.rb
94
+ - spec/test_files/Chrysanthemum.jpg
95
+ - spec/test_files/Desert.jpg
96
+ - spec/test_files/empty_file.csv
97
+ - spec/test_files/folder1/Koala.jpg
98
+ - spec/test_files/folder1/Lighthouse.jpg
99
+ - spec/test_files/folder1/text_3.txt
100
+ - spec/test_files/folder1/text_4.txt
101
+ - spec/test_files/folder2/Jellyfish.jpg
102
+ - spec/test_files/folder2/Penguins.jpg
103
+ - spec/test_files/folder2/text_1.txt
104
+ - spec/test_files/folder2/text_6.txt
105
+ - spec/test_files/folder2/Tulips.jpg
106
+ - spec/test_files/Hydrangeas.jpg
107
+ - spec/test_files/text_1.txt
108
+ - spec/test_files/text_2.txt
109
+ homepage: http://www.impac.ch
110
+ licenses: []
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ none: false
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 1.8.24
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: Transfer Files from and to FTP/SFTP/FTPS
133
+ test_files:
134
+ - spec/file_transfer/file_transfer_handler_spec.rb
135
+ - spec/spec_helper.rb
136
+ - spec/test_files/Chrysanthemum.jpg
137
+ - spec/test_files/Desert.jpg
138
+ - spec/test_files/empty_file.csv
139
+ - spec/test_files/folder1/Koala.jpg
140
+ - spec/test_files/folder1/Lighthouse.jpg
141
+ - spec/test_files/folder1/text_3.txt
142
+ - spec/test_files/folder1/text_4.txt
143
+ - spec/test_files/folder2/Jellyfish.jpg
144
+ - spec/test_files/folder2/Penguins.jpg
145
+ - spec/test_files/folder2/text_1.txt
146
+ - spec/test_files/folder2/text_6.txt
147
+ - spec/test_files/folder2/Tulips.jpg
148
+ - spec/test_files/Hydrangeas.jpg
149
+ - spec/test_files/text_1.txt
150
+ - spec/test_files/text_2.txt