downspout 0.2.2

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,42 @@
1
+ require 'webrick'
2
+ include WEBrick
3
+
4
+ class TestServlet < WEBrick::HTTPServlet::AbstractServlet
5
+ #
6
+ # Simple server for integration tests
7
+ #
8
+
9
+ def self.port
10
+ 8899
11
+ end
12
+
13
+ def self.path
14
+ '/'
15
+ end
16
+
17
+ def self.url
18
+ "http://127.0.0.1:#{port}#{path}"
19
+ end
20
+
21
+ def respond_with(method,req,res)
22
+ res.body = method.to_s
23
+ res['Content-Type'] = "text/plain"
24
+ end
25
+
26
+ def do_GET(req,res)
27
+ respond_with(:GET,req,res)
28
+ end
29
+
30
+ def do_POST(req,res)
31
+ respond_with(:POST,req,res)
32
+ end
33
+
34
+ def do_PUT(req,res)
35
+ respond_with(:PUT,req,res)
36
+ end
37
+
38
+ def do_DELETE(req,res)
39
+ respond_with(:DELETE,req,res)
40
+ end
41
+
42
+ end
@@ -0,0 +1,124 @@
1
+ require 'test_helper'
2
+
3
+ class DownspoutTest < Test::Unit::TestCase
4
+ context "Downspout" do
5
+ context "Base" do
6
+
7
+ should "respond to supported_protocol?" do
8
+ assert Downspout.respond_to?("supported_protocol?")
9
+ end
10
+
11
+ should "respond to supported_protocols" do
12
+ assert Downspout.respond_to?("supported_protocols")
13
+ end
14
+
15
+ should "respond to viable_url?" do
16
+ assert Downspout.respond_to?("viable_url?")
17
+ end
18
+
19
+ should "respond to download_url_to_path for backwards compatibility" do
20
+ assert Downspout.respond_to?(:download_url_to_path)
21
+ end
22
+
23
+ should "respond to fetch_url" do
24
+ assert Downspout.respond_to?(:download_url_to_path)
25
+ end
26
+ end
27
+
28
+ context "protocols" do
29
+
30
+ should "not support SFTP" do
31
+ assert !( Downspout.supported_protocol?( "sftp" ) )
32
+ end
33
+
34
+ should "not support AFP" do
35
+ assert !( Downspout.supported_protocol?( "afp" ) )
36
+ end
37
+
38
+ should "not support SCP" do
39
+ assert !( Downspout.supported_protocol?( "scp" ) )
40
+ end
41
+
42
+ should "support all secret herbs and spices" do
43
+ assert_not_nil Downspout.supported_protocols
44
+ assert_equal Array, Downspout.supported_protocols.class
45
+ assert_equal 3, Downspout.supported_protocols.size
46
+ $logger.info "List of supported protocols : #{Downspout.supported_protocols.join(", ")}"
47
+ end
48
+
49
+ should "support HTTP" do
50
+ assert Downspout.supported_protocol?( "http" )
51
+ end
52
+
53
+ should "support HTTPS" do
54
+ assert Downspout.supported_protocol?( "https" )
55
+ end
56
+
57
+ should "support URI::HTTP" do
58
+ assert Downspout.supported_protocol?( URI::HTTP )
59
+ end
60
+
61
+ should "support URI::HTTPS" do
62
+ assert Downspout.supported_protocol?( URI::HTTPS )
63
+ end
64
+
65
+ should "support FTP" do
66
+ assert Downspout.supported_protocol?( "ftp" )
67
+ end
68
+
69
+ should "support URI::FTP" do
70
+ assert Downspout.supported_protocol?( URI::FTP )
71
+ end
72
+
73
+ end
74
+
75
+ context "URLs" do
76
+ context "which are bad" do
77
+ should "be rejected with unknown protocols" do
78
+ assert !( Downspout.viable_url?( "protocol://host.domain.tld/resource/file.format" ) )
79
+ end
80
+
81
+ should "be rejected with SCP protocol" do
82
+ assert !( Downspout.viable_url?( "scp://host.domain.tld/resource/file.format" ) )
83
+ end
84
+
85
+ should "be rejected with SFTP protocol" do
86
+ assert !( Downspout.viable_url?( "sftp://host.domain.tld/resource/file.format" ) )
87
+ end
88
+
89
+ should "be rejected with FTPS protocol" do
90
+ assert !( Downspout.viable_url?( "ftps://host.domain.tld/resource/file.format" ) )
91
+ end
92
+
93
+ end
94
+
95
+ context "which are good" do
96
+ should "be accepted with HTTP protocol" do
97
+ assert Downspout.viable_url?( "http://host.domain.tld/resource/file.format" )
98
+ end
99
+
100
+ should "be accepted with HTTPS protocol" do
101
+ assert Downspout.viable_url?( "https://host.domain.tld/resource/file.format" )
102
+ end
103
+
104
+ should "be accepted to PDF file" do
105
+ assert Downspout.viable_url?( "http://host.domain.tld/resource/file.pdf" )
106
+ end
107
+
108
+ should "be accepted to PHP file with arbitrary parameters" do
109
+ assert Downspout.viable_url?( "http://host.domain.tld/resource/file.php?doc_id=A1B2C3&vendor=xyz" )
110
+ end
111
+
112
+ should "be accepted with FTP protocol" do
113
+ assert Downspout.viable_url?( "ftp://host.domain.tld/resource/file.format" )
114
+ end
115
+
116
+ should "be accepted with FTP protocol containing user & password" do
117
+ assert Downspout.viable_url?( "ftp://uzer:passw0rd@host.domain.tld/resource/file.format" )
118
+ end
119
+
120
+ end
121
+ end
122
+
123
+ end
124
+ end
@@ -0,0 +1,101 @@
1
+ require 'test_helper'
2
+
3
+ class ConfigTest < Test::Unit::TestCase
4
+ context "Downspout" do
5
+ context "Config" do
6
+
7
+ should "respond to tmp_dir" do
8
+ assert Downspout::Config.respond_to?(:tmp_dir)
9
+ end
10
+
11
+ should "default to '/tmp/downloads/' for Downspout::Config#tmp_dir" do
12
+ assert_equal "/tmp/downloads/", Downspout::Config.tmp_dir
13
+ end
14
+
15
+ should "respond to Network Enabled" do
16
+ assert Downspout::Config.respond_to?("network_enabled?")
17
+ end
18
+
19
+ should "default to Network Enabled" do
20
+ assert Downspout::Config.network_enabled?
21
+ end
22
+
23
+ should "respond to Disable Networking" do
24
+ assert Downspout::Config.respond_to?("disable_networking!")
25
+ end
26
+
27
+ should "support disabling network operations" do
28
+ assert Downspout::Config.network_enabled?
29
+ assert Downspout::Config.disable_networking!
30
+ assert !(Downspout::Config.network_enabled?)
31
+ end
32
+
33
+ should "respond to Enable Networking" do
34
+ assert Downspout::Config.respond_to?("enable_networking!")
35
+ end
36
+
37
+ should "detect whether Curb is available" do
38
+ assert Downspout::Config.curb_available?
39
+ end
40
+
41
+ should "enable Curb if library is available" do
42
+ assert Downspout::Config.curb_available?
43
+ assert Downspout::Config.enable_curb!
44
+ end
45
+
46
+ should "support enabling network operations" do
47
+ assert !(Downspout::Config.network_enabled?)
48
+ assert Downspout::Config.enable_networking!
49
+ assert Downspout::Config.network_enabled?
50
+ end
51
+
52
+ context "Host-Based Credentials" do
53
+ should "respond to Credentials" do
54
+ assert Downspout::Config.respond_to?(:credentials)
55
+ assert_not_nil Downspout::Config.credentials
56
+ end
57
+
58
+ should "support adding Credentials" do
59
+ assert Downspout::Config.respond_to?("add_credential")
60
+ end
61
+
62
+ should "add FTP Credential" do
63
+ assert_equal 0, Downspout::Config.credentials.size
64
+
65
+ ftp_url = "ftp://ftp-intake.vitalbook.com/hammer.rb"
66
+ ftp_host = URI.parse( ftp_url ).host
67
+
68
+ Downspout::Config.add_credential( :scheme => 'ftp',
69
+ :host => ftp_host,
70
+ :user_name => "deploy",
71
+ :pass_word => "m@keitRUUN!"
72
+ )
73
+
74
+ assert_equal 1, Downspout::Config.credentials.size
75
+
76
+ assert_equal ftp_host, Downspout::Config.credentials.first.host
77
+ end
78
+
79
+ end
80
+
81
+ end
82
+ end
83
+
84
+ context "with stubbed-out curb detection" do
85
+ setup do
86
+ Downspout::Config.stubs('curb_available?').returns(false)
87
+ end
88
+
89
+ should "fail to enable Curb when library is unavailable" do
90
+ assert !(Downspout::Config.curb_available?)
91
+ assert !(Downspout::Config.enable_curb!)
92
+ end
93
+
94
+ teardown do
95
+ # this is pretty heinous...
96
+ Downspout::Config.stubs('curb_available?').returns(true)
97
+ Downspout::Config.enable_curb!
98
+ end
99
+ end
100
+
101
+ end
@@ -0,0 +1,31 @@
1
+ require 'test_helper'
2
+
3
+ class CredentialTest < Test::Unit::TestCase
4
+ context "Downspout" do
5
+ context "Credential" do
6
+
7
+ should "respond to scheme" do
8
+ assert Downspout::Credential.new.respond_to?(:scheme)
9
+ end
10
+
11
+ should "respond to host" do
12
+ assert Downspout::Credential.new.respond_to?(:host)
13
+ end
14
+
15
+ should "respond to port" do
16
+ assert Downspout::Credential.new.respond_to?(:port)
17
+ end
18
+
19
+ should "respond to user_name" do
20
+ assert Downspout::Credential.new.respond_to?(:user_name)
21
+ end
22
+
23
+ should "respond to pass_word" do
24
+ assert Downspout::Credential.new.respond_to?(:pass_word)
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,211 @@
1
+ require 'test_helper'
2
+
3
+ class DownloaderTest < Test::Unit::TestCase
4
+
5
+ context "Downspout" do
6
+ context "Downloader" do
7
+
8
+ should "respond to URL" do
9
+ assert Downspout::Downloader.new.respond_to?(:url)
10
+ end
11
+
12
+ should "respond to URI" do
13
+ assert Downspout::Downloader.new.respond_to?(:uri)
14
+ end
15
+
16
+ should "respond to Scheme" do
17
+ assert Downspout::Downloader.new.respond_to?(:scheme)
18
+ end
19
+
20
+ should "respond to Path" do
21
+ assert Downspout::Downloader.new.respond_to?(:path)
22
+ end
23
+
24
+ should "respond to Basename" do
25
+ assert Downspout::Downloader.new.respond_to?(:basename)
26
+ end
27
+
28
+ should "respond to Response" do
29
+ assert Downspout::Downloader.new.respond_to?(:response)
30
+ end
31
+
32
+ should "respond to Response Headers" do
33
+ assert Downspout::Downloader.new.respond_to?(:response_headers)
34
+ end
35
+
36
+ should "respond to download!" do
37
+ assert Downspout::Downloader.new.respond_to?("download!")
38
+ end
39
+
40
+ should "support explicitly using Net:::HTTP for downloads" do
41
+ assert Downspout::Config.curb_available?
42
+
43
+ dlx = Downspout::Downloader.new()
44
+ assert dlx.use_curb?
45
+
46
+ dlx.disable_curb!
47
+
48
+ assert !(dlx.use_curb?)
49
+ assert dlx.use_net_http?
50
+ end
51
+
52
+ should "default to using Curb for downloads when available" do
53
+ assert Downspout::Config.curb_available?
54
+
55
+ dlx = Downspout::Downloader.new
56
+ assert dlx.use_curb?
57
+ assert !(dlx.use_net_http?)
58
+ end
59
+
60
+ should "support configuration to switch default to Net:::HTTP for downloads" do
61
+ assert Downspout::Config.curb_available?
62
+ assert Downspout::Config.use_curb?
63
+ begin
64
+ Downspout::Config.disable_curb!
65
+
66
+ assert !(Downspout::Config.use_curb?)
67
+
68
+ dlx = Downspout::Downloader.new()
69
+ assert !(dlx.use_curb?)
70
+ assert dlx.use_net_http?
71
+ ensure
72
+ Downspout::Config.enable_curb!
73
+ end
74
+ end
75
+
76
+ context "with HTTP URL" do
77
+ setup do
78
+ @obj = Downspout::Downloader.new( :url => "http://machine.local/downspout.test" )
79
+ end
80
+
81
+ should "populate URL" do
82
+ assert_not_nil @obj.url
83
+ end
84
+
85
+ should "automatically parse URI from given URL" do
86
+ assert_not_nil @obj.uri
87
+ end
88
+
89
+ should "determine download scheme" do
90
+ assert_not_nil @obj.scheme
91
+ assert_equal "http", @obj.scheme
92
+ end
93
+
94
+ should "populate basename" do
95
+ assert_not_nil @obj.basename
96
+ assert_equal "downspout.test", @obj.basename
97
+ end
98
+
99
+ end
100
+
101
+ context "with URL for unsupported scheme (protocol)" do
102
+ should "fail on invalid scheme (Gopher)" do
103
+ assert_raise Downspout::UnsupportedScheme do
104
+ @obj = Downspout::Downloader.new( :url => "gopher://umn.edu/" )
105
+ @obj.download!
106
+ end
107
+ end
108
+ should "fail on invalid scheme (SMB)" do
109
+ assert_raise Downspout::UnsupportedScheme do
110
+ @obj = Downspout::Downloader.new( :url => "smb://windows.microsoft.com/" )
111
+ @obj.download!
112
+ end
113
+ end
114
+ end
115
+
116
+ context "over-writing an existing file" do
117
+ setup do
118
+ dts = Time.now.utc.strftime("%Y%m%d_%H%M%S")
119
+ @tmp_conflict_path = File.join( Test::App.root , 'tmp', "#{dts}.tmp" )
120
+
121
+ FileUtils.touch( @tmp_conflict_path )
122
+
123
+ @ds_url = "http://machine.local/folder/file.txt"
124
+
125
+ Downspout::Config.disable_networking!
126
+ end
127
+
128
+ should "remove the conflict file before the download" do
129
+ assert File.exist?( @tmp_conflict_path )
130
+
131
+ @df = Downspout.download_url_to_path( @ds_url, @tmp_conflict_path )
132
+ # note: due to disabled networking, the download is not actually performed,
133
+ # but the method otherwise operates as normal
134
+
135
+ assert !( File.exist?( @tmp_conflict_path ) )
136
+ end
137
+
138
+ teardown do
139
+ FileUtils.rm( @tmp_conflict_path) if (@tmp_conflict_path && File.exist?( @tmp_conflict_path ))
140
+ Downspout::Config.enable_networking!
141
+ end
142
+ end
143
+
144
+ end
145
+
146
+ context "faking net/http response" do
147
+ should "map 302 code to Found" do
148
+ assert_equal Net::HTTPFound, Net::HTTPResponse.send('response_class','302')
149
+ end
150
+ should "map 301 code to Moved" do
151
+ assert_equal Net::HTTPMovedPermanently, Net::HTTPResponse.send('response_class','301')
152
+ end
153
+ end
154
+
155
+ context "with FTP URL" do
156
+ setup do
157
+ @obj = Downspout::Downloader.new( :url => "ftp://ftp.machine.local/directory/image.jpg" )
158
+ end
159
+
160
+ should "populate URL" do
161
+ assert_not_nil @obj.url
162
+ end
163
+
164
+ should "automatically parse URI from given URL" do
165
+ assert_not_nil @obj.uri
166
+ end
167
+
168
+ should "determine download scheme" do
169
+ assert_not_nil @obj.scheme
170
+ assert_equal "ftp", @obj.scheme
171
+ end
172
+
173
+ should "populate basename" do
174
+ assert_not_nil @obj.basename
175
+ assert_equal "image.jpg", @obj.basename
176
+ end
177
+
178
+ end
179
+
180
+ end
181
+
182
+ should 'download google index page via curb' do
183
+ g = Downspout.fetch_url( 'http://www.google.com/' )
184
+
185
+ assert_not_nil g
186
+ assert File.exist?( g.path )
187
+ assert_equal Downspout::Downloader, g.class
188
+ assert g.response.is_a?(Net::HTTPResponse)
189
+ assert_equal Net::HTTPOK, g.response.class
190
+ assert g.response_headers.keys.include?('Content-Type')
191
+ end
192
+
193
+ should 'download google index page via net/http' do
194
+ g = Downspout::Downloader.new( :url => 'http://www.google.com/' )
195
+ assert g.use_curb?
196
+
197
+ g.disable_curb!
198
+
199
+ assert g.use_net_http?
200
+
201
+ g.download!
202
+
203
+ assert_not_nil g
204
+ assert File.exist?( g.path )
205
+ assert_equal Downspout::Downloader, g.class
206
+ assert g.response.is_a?(Net::HTTPResponse)
207
+ assert_equal Net::HTTPOK, g.response.class
208
+ assert g.response_headers.keys.include?('content-type') # Note case difference for Net/HTTP vs Curb
209
+ end
210
+
211
+ end
@@ -0,0 +1,32 @@
1
+ require 'test_helper'
2
+
3
+ class TmpFileTest < Test::Unit::TestCase
4
+ context "Downspout" do
5
+ context "Tmpfile" do
6
+ setup do
7
+ @explicit_name = "explicit.txt"
8
+ @explicit_path = File.join( Downspout::Config.tmp_dir, @explicit_name )
9
+ FileUtils.rm( @explicit_path ) if File.exist?( @explicit_path )
10
+ end
11
+
12
+ should "work similar to Ruby tempfile" do
13
+ jltf = Downspout::Tmpfile.new()
14
+ assert jltf
15
+ assert jltf.path =~ /#{Downspout::Config.tmp_dir}/
16
+ end
17
+
18
+ should "create tempfile in configured directory" do
19
+ assert Downspout::Tmpfile.new.path =~ /#{Downspout::Config.tmp_dir}/
20
+ end
21
+
22
+ should "create file with given basename in configured directory" do
23
+ dstf = Downspout::Tmpfile.new( :name => @explicit_name )
24
+
25
+ assert_equal @explicit_name, File.basename( dstf.path )
26
+
27
+ assert dstf.path =~ /#{Downspout::Config.tmp_dir}/
28
+ end
29
+
30
+ end
31
+ end
32
+ end
data/test/watchr.rb ADDED
@@ -0,0 +1,17 @@
1
+ # Watchr 'Auto-Test' Config
2
+
3
+ $module_name = 'downspout'
4
+
5
+ def lib_trigger(match)
6
+ test_name = match.gsub('lib/','test/test_')
7
+ system("ruby -I'test' #{test_name}")
8
+ end
9
+
10
+ def unit_trigger(match)
11
+ test_name = match.gsub('lib','test').gsub( $module_name, 'unit' ).gsub('.rb','_test.rb')
12
+ system("ruby -I'test' #{test_name}")
13
+ end
14
+
15
+ watch( 'lib/.*\.rb' ) {|md| lib_trigger( md[0] ) }
16
+ watch( "lib/#{$module_name }/.*\.rb" ) {|md| unit_trigger( md[0] ) }
17
+ watch( 'test/.*_test\.rb' ) {|md| system("ruby -Itest #{md[0]}") }
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: downspout
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 2
10
+ version: 0.2.2
11
+ platform: ruby
12
+ authors:
13
+ - Phi.Sanders
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-03-29 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: jeweler
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 1
32
+ - 5
33
+ - 2
34
+ version: 1.5.2
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: shoulda
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rcov
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
65
+ description: Downspout is an easy-to-use library for downloading files from given URLs. HTTP downloads can use either Net::HTTP, or libcurl (via the Curb gem)
66
+ email: phi.sanders@sciphi.me
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - LICENSE.txt
73
+ - README.rdoc
74
+ files:
75
+ - LICENSE.txt
76
+ - README.rdoc
77
+ - Rakefile
78
+ - VERSION
79
+ - lib/downspout.rb
80
+ - lib/downspout/base.rb
81
+ - lib/downspout/config.rb
82
+ - lib/downspout/credential.rb
83
+ - lib/downspout/downloader.rb
84
+ - lib/downspout/logger.rb
85
+ - lib/downspout/tmp_file.rb
86
+ - test/downspout_test.rb
87
+ - test/fixtures/ruby.png
88
+ - test/servlet.rb
89
+ - test/test_helper.rb
90
+ - test/test_logger.rb
91
+ - test/test_servlet.rb
92
+ - test/unit/base_test.rb
93
+ - test/unit/config_test.rb
94
+ - test/unit/credential_test.rb
95
+ - test/unit/downloader_test.rb
96
+ - test/unit/tmp_file_test.rb
97
+ - test/watchr.rb
98
+ has_rdoc: true
99
+ homepage: http://github.com/sci-phi/downspout
100
+ licenses:
101
+ - MIT
102
+ post_install_message:
103
+ rdoc_options: []
104
+
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ hash: 3
113
+ segments:
114
+ - 0
115
+ version: "0"
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ hash: 3
122
+ segments:
123
+ - 0
124
+ version: "0"
125
+ requirements: []
126
+
127
+ rubyforge_project:
128
+ rubygems_version: 1.4.2
129
+ signing_key:
130
+ specification_version: 3
131
+ summary: Downspout is an easy-to-use library for downloading files from given URLs.
132
+ test_files:
133
+ - test/downspout_test.rb
134
+ - test/servlet.rb
135
+ - test/test_helper.rb
136
+ - test/test_logger.rb
137
+ - test/test_servlet.rb
138
+ - test/unit/base_test.rb
139
+ - test/unit/config_test.rb
140
+ - test/unit/credential_test.rb
141
+ - test/unit/downloader_test.rb
142
+ - test/unit/tmp_file_test.rb
143
+ - test/watchr.rb