file_transfer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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