easy_downloader 0.0.2.alpha → 0.0.3.alpha
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.
- data/README.rdoc +56 -2
- data/VERSION +1 -1
- data/easy_downloader.gemspec +10 -5
- data/lib/easy_downloader/abstract_loader.rb +50 -0
- data/lib/easy_downloader/downloader.rb +34 -0
- data/lib/easy_downloader/ftp.rb +76 -0
- data/lib/easy_downloader/http.rb +32 -0
- data/lib/easy_downloader/options.rb +19 -7
- data/lib/easy_downloader/result.rb +20 -10
- data/lib/easy_downloader/{sftp_downloader.rb → sftp.rb} +5 -12
- data/lib/easy_downloader/uploader.rb +29 -0
- data/lib/easy_downloader.rb +13 -62
- data/spec/easy_downloader/abstract_loader_spec.rb +38 -0
- data/spec/easy_downloader/options_spec.rb +31 -4
- metadata +12 -7
- data/lib/easy_downloader/ftp_downloader.rb +0 -39
- data/lib/easy_downloader/http_downloader.rb +0 -30
data/README.rdoc
CHANGED
@@ -1,9 +1,63 @@
|
|
1
1
|
= easy_downloader
|
2
2
|
|
3
|
-
|
3
|
+
This is a dead simple, one-method downloader, with friendly error messages.
|
4
|
+
|
5
|
+
EasyDownloader reduces the amount of work required to setup and check for errors when downloading from another location. This
|
6
|
+
is useful when, for example, a client wants to you to pick a file up from their FTP, SFTP, or regular website on a nightly basis.
|
7
|
+
EasyDownloader gives you a one-method means of downloading those files, returns with a friendly error message if it fails
|
8
|
+
(geared at cron job notifications), or returns an array of file names it downloaded.
|
9
|
+
|
10
|
+
== Example
|
11
|
+
|
12
|
+
First, add the following to your Gemfile:
|
13
|
+
|
14
|
+
gem 'easy_downloader'
|
15
|
+
|
16
|
+
Then, in your application:
|
17
|
+
|
18
|
+
my_results = EasyDownloader.download(
|
19
|
+
:type => :ftp,
|
20
|
+
:host => '127.0.0.1',
|
21
|
+
:user => 'app',
|
22
|
+
:password => 'example'
|
23
|
+
:remote_path => '/some/directory/IWantToChangeTo'
|
24
|
+
:remote_pattern => '.*\.txt'
|
25
|
+
:local_path => Rails.root+'/my_downloaded_stuff/'
|
26
|
+
)
|
27
|
+
|
28
|
+
my_results.results
|
29
|
+
=> "We found 1 file(s) to download with the following names:
|
30
|
+
#1. test_file.txt
|
31
|
+
Started downloading at Tue Dec 21 16:04:46 -0500 2010
|
32
|
+
Progress:
|
33
|
+
Starting to download test_file.txt
|
34
|
+
Finished downloading test_file.txt
|
35
|
+
Finished downloading at Tue Dec 21 16:04:46 -0500 2010
|
36
|
+
Downloaded 1 file(s)"
|
37
|
+
|
38
|
+
my_results.files
|
39
|
+
=> ['test_file.txt']
|
40
|
+
|
41
|
+
The returned object only has two attributes (did I mention this was dead simple):
|
42
|
+
1. result
|
43
|
+
2. files
|
44
|
+
|
45
|
+
The available keys are:
|
46
|
+
|
47
|
+
:type => (required) The protocal used to download the file. One of :sftp, :ftp or :http.
|
48
|
+
:host => (required) the domain of the remote server (source)
|
49
|
+
:remote_path => a relative path to "cd" into when we first access the remote server
|
50
|
+
:remote_pattern => a glob pattern that will select only the files we want to download.%
|
51
|
+
see Ruby's core API if you are not familiar with this concept.
|
52
|
+
|
53
|
+
NOTE: for *ftp* downloads, this matches a regular expression to the name of files in the current directory.
|
54
|
+
for *Sftp* downloads, this uses the 'glob' pattern as mentioned above.
|
55
|
+
|
56
|
+
:user => a username or login used for authenticating on the server
|
57
|
+
:password => a password that, in combination with the user, will grant access to the remote server/host
|
4
58
|
|
5
59
|
== Contributing to easy_downloader
|
6
|
-
|
60
|
+
|
7
61
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
62
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
63
|
* Fork the project
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3.alpha
|
data/easy_downloader.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{easy_downloader}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.3.alpha"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bernardo Telles"]
|
12
|
-
s.date = %q{2010-12-
|
12
|
+
s.date = %q{2010-12-22}
|
13
13
|
s.description = %q{ EasyDownloader reduces the amount of work required to setup and check for errors when downloading from another location. This
|
14
14
|
is useful when, for example, a client wants to you to pick a file up from their FTP, SFTP, or regular website on a nightly basis.
|
15
15
|
EasyDownloader gives you a one-method means of downloading those files, returns with a friendly error message if it fails
|
@@ -30,11 +30,15 @@ Gem::Specification.new do |s|
|
|
30
30
|
"VERSION",
|
31
31
|
"easy_downloader.gemspec",
|
32
32
|
"lib/easy_downloader.rb",
|
33
|
-
"lib/easy_downloader/
|
34
|
-
"lib/easy_downloader/
|
33
|
+
"lib/easy_downloader/abstract_loader.rb",
|
34
|
+
"lib/easy_downloader/downloader.rb",
|
35
|
+
"lib/easy_downloader/ftp.rb",
|
36
|
+
"lib/easy_downloader/http.rb",
|
35
37
|
"lib/easy_downloader/options.rb",
|
36
38
|
"lib/easy_downloader/result.rb",
|
37
|
-
"lib/easy_downloader/
|
39
|
+
"lib/easy_downloader/sftp.rb",
|
40
|
+
"lib/easy_downloader/uploader.rb",
|
41
|
+
"spec/easy_downloader/abstract_loader_spec.rb",
|
38
42
|
"spec/easy_downloader/options_spec.rb",
|
39
43
|
"spec/spec_helper.rb"
|
40
44
|
]
|
@@ -44,6 +48,7 @@ Gem::Specification.new do |s|
|
|
44
48
|
s.rubygems_version = %q{1.3.7}
|
45
49
|
s.summary = %q{A dead simple, one-method downloader, with friendly error messages}
|
46
50
|
s.test_files = [
|
51
|
+
"spec/easy_downloader/abstract_loader_spec.rb",
|
47
52
|
"spec/easy_downloader/options_spec.rb",
|
48
53
|
"spec/spec_helper.rb"
|
49
54
|
]
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module EasyDownloader
|
2
|
+
class AbstractLoader
|
3
|
+
|
4
|
+
attr_reader :files, :result
|
5
|
+
|
6
|
+
include Sftp
|
7
|
+
include Ftp
|
8
|
+
include Http
|
9
|
+
|
10
|
+
def initialize(*options)
|
11
|
+
@options= Options.new(*options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute
|
15
|
+
begin
|
16
|
+
@options.result.started
|
17
|
+
execute_load
|
18
|
+
@options.result.loaded(@options.load_count)
|
19
|
+
@options.result.finished
|
20
|
+
rescue Exception => e
|
21
|
+
@options.result.errors= error_message(@options, e)
|
22
|
+
end
|
23
|
+
@result = @options.result
|
24
|
+
@files = @result.loaded
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def execute_load
|
31
|
+
raise NotImplementedError.new("#{self.class.name} does not have an 'execute_load' method.")
|
32
|
+
end
|
33
|
+
|
34
|
+
def error_message(options, e)
|
35
|
+
raise NotImplementedError.new("#{self.class.name} does not have an 'error_message' method.")
|
36
|
+
end
|
37
|
+
|
38
|
+
def local_files_list(options)
|
39
|
+
if options.local_file
|
40
|
+
[options.local_file]
|
41
|
+
else
|
42
|
+
Dir[options.local_path, options.local_pattern]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def options
|
47
|
+
@options
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module EasyDownloader
|
2
|
+
class Downloader < AbstractLoader
|
3
|
+
|
4
|
+
private
|
5
|
+
|
6
|
+
def execute_load
|
7
|
+
case @options.type
|
8
|
+
when :ftp
|
9
|
+
ftp_download(@options)
|
10
|
+
when :http
|
11
|
+
http_download(@options)
|
12
|
+
when :sftp
|
13
|
+
sftp_download(@options)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def error_message(options, e)
|
18
|
+
message = <<-ERROR_MESSAGE
|
19
|
+
There was a problem downloading from #{options.host}.
|
20
|
+
The error we got was:
|
21
|
+
#{e.message}
|
22
|
+
#{e.backtrace.inspect}
|
23
|
+
We tried connecting with:
|
24
|
+
host: #{options.host}
|
25
|
+
user: #{options.user}
|
26
|
+
pass: [filtered]
|
27
|
+
directory_path: #{options.remote_path}
|
28
|
+
file_pattern: #{options.remote_pattern}
|
29
|
+
destination: #{options.local_path}
|
30
|
+
ERROR_MESSAGE
|
31
|
+
message
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'net/ftp'
|
2
|
+
module EasyDownloader
|
3
|
+
module Ftp
|
4
|
+
def ftp_download(options)
|
5
|
+
open_ftp do |ftp|
|
6
|
+
|
7
|
+
change_remote_dir(ftp)
|
8
|
+
|
9
|
+
files = ftp.nlst.select {|file_name| options.remote_pattern == '*' || file_name =~ Regexp.new(options.remote_pattern) }
|
10
|
+
total = files.size
|
11
|
+
options.result.found(files.size, files)
|
12
|
+
|
13
|
+
files.each do |path|
|
14
|
+
options.result.starting_path(path)
|
15
|
+
ftp.get(path, "#{options.local_path}#{path}")
|
16
|
+
options.load_count = options.load_count + 1
|
17
|
+
options.result.finished_path(path)
|
18
|
+
options.result.files_loaded << "#{options.local_path}#{path}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def ftp_upload(options)
|
24
|
+
open_ftp do |ftp|
|
25
|
+
|
26
|
+
change_remote_dir(ftp)
|
27
|
+
|
28
|
+
files = local_files_list(options)
|
29
|
+
options.result.found(files.size, files)
|
30
|
+
|
31
|
+
files.each do |path|
|
32
|
+
options.result.starting_path(path)
|
33
|
+
if options.remote_file
|
34
|
+
ftp.put(path, options.remote_file)
|
35
|
+
options.result.files_loaded << options.remote_file
|
36
|
+
else
|
37
|
+
ftp.put(path)
|
38
|
+
options.result.files_loaded << File.basename(path)
|
39
|
+
end
|
40
|
+
options.load_count= options.load_count + 1
|
41
|
+
options.result.finished_path(path)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def open_ftp(&block)
|
47
|
+
Net::FTP.open(options.host,
|
48
|
+
options.user,
|
49
|
+
ftp_password_option(options.password)) do |ftp|
|
50
|
+
yield(ftp)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def change_remote_dir(ftp)
|
55
|
+
if options.remote_path.present?
|
56
|
+
begin
|
57
|
+
ftp.chdir(options.remote_path)
|
58
|
+
rescue InvalidRemoteDirectory
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def ftp_password_option(password)
|
64
|
+
password ? password : nil
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def remote_files_list(options)
|
69
|
+
if options.remote_file
|
70
|
+
[options.remote_file]
|
71
|
+
else
|
72
|
+
Dir[options.remote_path, options.remote_pattern]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module EasyDownloader
|
2
|
+
module Http
|
3
|
+
def http_download(options)
|
4
|
+
#result = options.result
|
5
|
+
#result.started
|
6
|
+
#Net::SFTP.start(options.host,
|
7
|
+
# options.user,
|
8
|
+
# password_option(options.password)) do |sftp|
|
9
|
+
|
10
|
+
# files = sftp.dir.glob(options.remote_path, options.remote_pattern)
|
11
|
+
# total = files.size
|
12
|
+
# result.found(files.size, files.map(&:name))
|
13
|
+
|
14
|
+
# files.map(&:name).each do |path|
|
15
|
+
# result.starting_path(path)
|
16
|
+
# download_count += 1 if sftp.download!("#{options.remote_path}#{path}", "#{options.destination_dir}#{path}")
|
17
|
+
# result.finished_path(path)
|
18
|
+
# files_downloaded << "#{options.destination_dir}#{path}"
|
19
|
+
# end
|
20
|
+
#end
|
21
|
+
|
22
|
+
#result.downloaded(download_count)
|
23
|
+
#result.finished
|
24
|
+
end
|
25
|
+
|
26
|
+
def password_option(password)
|
27
|
+
password ?
|
28
|
+
{:password => password} :
|
29
|
+
Hash.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,15 +1,17 @@
|
|
1
1
|
require 'active_support/core_ext/array/extract_options'
|
2
2
|
module EasyDownloader
|
3
3
|
class Options
|
4
|
-
attr_accessor :files, :successful, :result, :
|
5
|
-
:type, :host, :user, :password,
|
6
|
-
:
|
4
|
+
attr_accessor :files, :successful, :result, :load_count,
|
5
|
+
:type, :host, :user, :password,
|
6
|
+
:local_path, :remote_path,
|
7
|
+
:local_pattern, :remote_pattern,
|
8
|
+
:local_file, :remote_file
|
7
9
|
|
8
10
|
def initialize(*options)
|
9
11
|
@files = []
|
10
12
|
@successful = false
|
11
13
|
@result = Result.new
|
12
|
-
@
|
14
|
+
@load_count = 0
|
13
15
|
@options = options
|
14
16
|
|
15
17
|
options.extract_options!.each do |key, value|
|
@@ -21,10 +23,20 @@ module EasyDownloader
|
|
21
23
|
@type.to_sym
|
22
24
|
end
|
23
25
|
|
26
|
+
def remote_path
|
27
|
+
to_dir_path(@remote_path)
|
28
|
+
end
|
29
|
+
|
24
30
|
def local_path
|
25
|
-
@local_path
|
26
|
-
|
27
|
-
|
31
|
+
to_dir_path(@local_path)
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_dir_path(path)
|
35
|
+
if path
|
36
|
+
path =~ /\/$/ ? path : path + '/'
|
37
|
+
else
|
38
|
+
''
|
39
|
+
end
|
28
40
|
end
|
29
41
|
end
|
30
42
|
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module EasyDownloader
|
2
2
|
class Result
|
3
|
-
attr_accessor :errors, :
|
3
|
+
attr_accessor :errors, :files_loaded
|
4
4
|
|
5
5
|
def initialize
|
6
6
|
@header, @started, @finished, @errors= ''
|
7
|
-
@
|
7
|
+
@files_loaded = []
|
8
8
|
@progress = ["Progress:"]
|
9
9
|
end
|
10
10
|
|
@@ -20,7 +20,7 @@ module EasyDownloader
|
|
20
20
|
|
21
21
|
def found(total_found, file_names)
|
22
22
|
@found = total_found
|
23
|
-
@header= "We found #{total_found} file(s) to
|
23
|
+
@header= "We found #{total_found} file(s) to load with the following names: \n"
|
24
24
|
@found_list = file_names
|
25
25
|
end
|
26
26
|
|
@@ -28,21 +28,31 @@ module EasyDownloader
|
|
28
28
|
@started= Time.now
|
29
29
|
end
|
30
30
|
|
31
|
+
def started_at; @started; end
|
32
|
+
|
31
33
|
def finished
|
32
34
|
@finished= Time.now
|
33
35
|
end
|
34
36
|
|
35
|
-
def
|
36
|
-
|
37
|
-
|
37
|
+
def finished_at; @finished; end
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
def loaded(total = false)
|
42
|
+
if total
|
43
|
+
@loaded = total
|
44
|
+
@footer= "Loaded #{total} file(s)"
|
45
|
+
else
|
46
|
+
@loaded
|
47
|
+
end
|
38
48
|
end
|
39
49
|
|
40
50
|
def starting_path(path)
|
41
|
-
@progress << "Starting to
|
51
|
+
@progress << "Starting to load #{path}"
|
42
52
|
end
|
43
53
|
|
44
54
|
def finished_path(path)
|
45
|
-
@progress << "Finished
|
55
|
+
@progress << "Finished loading #{path}"
|
46
56
|
end
|
47
57
|
|
48
58
|
private
|
@@ -60,11 +70,11 @@ module EasyDownloader
|
|
60
70
|
end
|
61
71
|
|
62
72
|
def started_string
|
63
|
-
"Started
|
73
|
+
"Started loading at #{@started}"
|
64
74
|
end
|
65
75
|
|
66
76
|
def finished_string
|
67
|
-
"Finished
|
77
|
+
"Finished loading at #{@finished}"
|
68
78
|
end
|
69
79
|
|
70
80
|
end
|
@@ -1,27 +1,20 @@
|
|
1
1
|
module EasyDownloader
|
2
|
-
module
|
2
|
+
module Sftp
|
3
3
|
def sftp_download(options)
|
4
|
-
result = options.result
|
5
|
-
result.started
|
6
|
-
|
7
4
|
Net::SFTP.start(options.host,
|
8
5
|
options.user,
|
9
6
|
sftp_password_option(options.password)) do |sftp|
|
10
7
|
|
11
8
|
files = sftp.dir.glob(options.remote_path, options.remote_pattern)
|
12
|
-
|
13
|
-
result.found(files.size, files.map(&:name))
|
9
|
+
options.result.found(files.size, files.map(&:name))
|
14
10
|
|
15
11
|
files.map(&:name).each do |path|
|
16
|
-
result.starting_path(path)
|
12
|
+
options.result.starting_path(path)
|
17
13
|
options.download_count += 1 if sftp.download!("#{options.remote_path}#{path}", "#{options.local_path}#{path}")
|
18
|
-
result.finished_path(path)
|
19
|
-
result.files_downloaded << "#{options.local_path}#{path}"
|
14
|
+
options.result.finished_path(path)
|
15
|
+
options.result.files_downloaded << "#{options.local_path}#{path}"
|
20
16
|
end
|
21
17
|
end
|
22
|
-
|
23
|
-
result.downloaded(options.download_count)
|
24
|
-
result.finished
|
25
18
|
end
|
26
19
|
|
27
20
|
def sftp_password_option(password)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module EasyDownloader
|
2
|
+
class Uploader < AbstractLoader
|
3
|
+
|
4
|
+
private
|
5
|
+
|
6
|
+
def execute_load
|
7
|
+
[:ftp, :http, :sftp].include?(@options.type) ?
|
8
|
+
send("#{@options.type.to_s}_upload".to_sym, @options) :
|
9
|
+
raise(NotImplementedError.new("we don't have an uploader of this type."))
|
10
|
+
end
|
11
|
+
|
12
|
+
def error_message(options, e)
|
13
|
+
message = <<-ERROR_MESSAGE
|
14
|
+
There was a problem uploading to #{options.host}.
|
15
|
+
The error we got was:
|
16
|
+
#{e.message}
|
17
|
+
#{e.backtrace.inspect}
|
18
|
+
We tried connecting with:
|
19
|
+
host: #{options.host}
|
20
|
+
user: #{options.user}
|
21
|
+
pass: [filtered]
|
22
|
+
source: #{options.local_path}
|
23
|
+
remote directory path: #{options.remote_path}
|
24
|
+
remote file pattern: #{options.remote_pattern}
|
25
|
+
ERROR_MESSAGE
|
26
|
+
message
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/easy_downloader.rb
CHANGED
@@ -1,73 +1,24 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
1
3
|
require 'easy_downloader/result'
|
2
4
|
require 'easy_downloader/options'
|
3
|
-
require 'easy_downloader/
|
4
|
-
require 'easy_downloader/
|
5
|
-
require 'easy_downloader/
|
5
|
+
require 'easy_downloader/sftp'
|
6
|
+
require 'easy_downloader/ftp'
|
7
|
+
require 'easy_downloader/http'
|
8
|
+
require 'easy_downloader/abstract_loader'
|
9
|
+
require 'easy_downloader/downloader'
|
10
|
+
require 'easy_downloader/uploader'
|
6
11
|
require 'net/sftp'
|
7
12
|
module EasyDownloader
|
8
13
|
|
9
14
|
class InvalidRemoteDirectory < Exception; end
|
15
|
+
|
10
16
|
def self.download(*options)
|
11
|
-
Downloader.new(*options)
|
17
|
+
Downloader.new(*options).execute
|
12
18
|
end
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
include SftpDownloader
|
18
|
-
include FtpDownloader
|
19
|
-
include HttpDownloader
|
20
|
-
|
21
|
-
|
22
|
-
# Set up and immediately download files. The object has only two attributes:
|
23
|
-
# 1. result
|
24
|
-
# 2. files
|
25
|
-
#
|
26
|
-
# @param [Hash, #options] options to use including host, password, source, and destination directories.%
|
27
|
-
# The available keys are:
|
28
|
-
#
|
29
|
-
# :type => (required) The protocal used to download the file. One of :sftp, :ftp or :http.
|
30
|
-
# :host => (required) the domain of the remote server (source)
|
31
|
-
# :remote_path => a relative path to "cd" into when we first access the remote server
|
32
|
-
# :remote_pattern => a glob pattern that will select only the files we want to download.%
|
33
|
-
# see Ruby's core API if you are not familiar with this concept.
|
34
|
-
# :user => a username or login used for authenticating on the server
|
35
|
-
# :password => a password that, in combination with the user, will grant access to the remote server/host
|
36
|
-
def initialize(*options)
|
37
|
-
@options= Options.new(*options)
|
38
|
-
download
|
39
|
-
@result = @options.result
|
40
|
-
@files = @result.files_downloaded
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def download
|
46
|
-
begin
|
47
|
-
case @options.type
|
48
|
-
when :ftp
|
49
|
-
ftp_download(@options)
|
50
|
-
when :http
|
51
|
-
http_download(@options)
|
52
|
-
when :sftp
|
53
|
-
sftp_download(@options)
|
54
|
-
end
|
55
|
-
|
56
|
-
rescue Exception => e
|
57
|
-
@options.result.errors= <<-ERROR_MESSAGE
|
58
|
-
There was a problem downloading from #{@options.host}.
|
59
|
-
The error we got was:
|
60
|
-
#{e.message}
|
61
|
-
#{e.backtrace.inspect}
|
62
|
-
We tried connecting with:
|
63
|
-
host: #{@options.host}
|
64
|
-
user: #{@options.user}
|
65
|
-
pass: [filtered]
|
66
|
-
directory_path: #{@options.remote_path}
|
67
|
-
file_pattern: #{@options.remote_pattern}
|
68
|
-
destination: #{@options.local_path}
|
69
|
-
ERROR_MESSAGE
|
70
|
-
end
|
71
|
-
end
|
20
|
+
def self.upload(*options)
|
21
|
+
Uploader.new(*options).execute
|
72
22
|
end
|
23
|
+
|
73
24
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'easy_downloader/abstract_loader'
|
3
|
+
|
4
|
+
describe EasyDownloader::AbstractLoader do
|
5
|
+
describe "sets options" do
|
6
|
+
it "creates a new options object" do
|
7
|
+
abs = EasyDownloader::AbstractLoader.new(:local_path => 'hi')
|
8
|
+
abs.instance_variable_get(:@options).should be_instance_of(EasyDownloader::Options)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#execute" do
|
13
|
+
subject { EasyDownloader::AbstractLoader.new({:local_path => 'hi'})}
|
14
|
+
before do
|
15
|
+
subject.stub(:execute_load => true)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "sets the start time" do
|
19
|
+
subject.execute
|
20
|
+
subject.result.started_at.should be > (3.seconds.ago)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "executes the load" do
|
24
|
+
subject.should_receive :execute_load
|
25
|
+
subject.execute
|
26
|
+
end
|
27
|
+
|
28
|
+
it "sets the finished time" do
|
29
|
+
subject.execute
|
30
|
+
subject.result.finished_at.should be > (3.seconds.ago)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sets the number of files loaded to 0 when starting out" do
|
34
|
+
subject.execute
|
35
|
+
subject.result.loaded.should == 0
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -4,23 +4,50 @@ require 'easy_downloader/options'
|
|
4
4
|
|
5
5
|
describe EasyDownloader::Options do
|
6
6
|
context 'Accessors' do
|
7
|
-
[:files, :successful, :result, :
|
8
|
-
:host, :user, :password,
|
9
|
-
:
|
7
|
+
[:files, :successful, :result, :load_count,
|
8
|
+
:host, :user, :password,
|
9
|
+
:local_path, :remote_path,
|
10
|
+
:local_pattern, :remote_pattern,
|
11
|
+
:local_file, :remote_file].each do |accessor|
|
10
12
|
specify {subject.should respond_to(accessor)}
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
16
|
describe "exposes options" do
|
15
|
-
[:host, :user, :password, :
|
17
|
+
[:host, :user, :password, :remote_pattern].each_with_index do |exposable_option, index|
|
16
18
|
it "exposes #{exposable_option}" do
|
17
19
|
option = EasyDownloader::Options.new(exposable_option => "hi there #{index}")
|
18
20
|
option.send(exposable_option).should == "hi there #{index}"
|
19
21
|
end
|
20
22
|
end
|
23
|
+
|
21
24
|
it "exposes type as a symbol" do
|
22
25
|
option = EasyDownloader::Options.new(:type => "hithere")
|
23
26
|
option.type.should == :hithere
|
24
27
|
end
|
28
|
+
|
29
|
+
context "exposes local_path with a '/' in the end" do
|
30
|
+
it "even if there isn't one" do
|
31
|
+
option = EasyDownloader::Options.new(:local_path => "hithere")
|
32
|
+
option.send(:local_path).should == "hithere/"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "if there's already one" do
|
36
|
+
option = EasyDownloader::Options.new(:local_path => "hithere/")
|
37
|
+
option.send(:local_path).should == "hithere/"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "exposes remote_path with a '/' in the end" do
|
42
|
+
it "even if there isn't one" do
|
43
|
+
option = EasyDownloader::Options.new(:remote_path => "hithere")
|
44
|
+
option.send(:remote_path).should == "hithere/"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "if there's already one" do
|
48
|
+
option = EasyDownloader::Options.new(:remote_path => "hithere/")
|
49
|
+
option.send(:remote_path).should == "hithere/"
|
50
|
+
end
|
51
|
+
end
|
25
52
|
end
|
26
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_downloader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 296151474
|
5
5
|
prerelease: true
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
9
|
+
- 3
|
10
10
|
- alpha
|
11
|
-
version: 0.0.
|
11
|
+
version: 0.0.3.alpha
|
12
12
|
platform: ruby
|
13
13
|
authors:
|
14
14
|
- Bernardo Telles
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2010-12-
|
19
|
+
date: 2010-12-22 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies:
|
22
22
|
- !ruby/object:Gem::Dependency
|
@@ -159,11 +159,15 @@ files:
|
|
159
159
|
- VERSION
|
160
160
|
- easy_downloader.gemspec
|
161
161
|
- lib/easy_downloader.rb
|
162
|
-
- lib/easy_downloader/
|
163
|
-
- lib/easy_downloader/
|
162
|
+
- lib/easy_downloader/abstract_loader.rb
|
163
|
+
- lib/easy_downloader/downloader.rb
|
164
|
+
- lib/easy_downloader/ftp.rb
|
165
|
+
- lib/easy_downloader/http.rb
|
164
166
|
- lib/easy_downloader/options.rb
|
165
167
|
- lib/easy_downloader/result.rb
|
166
|
-
- lib/easy_downloader/
|
168
|
+
- lib/easy_downloader/sftp.rb
|
169
|
+
- lib/easy_downloader/uploader.rb
|
170
|
+
- spec/easy_downloader/abstract_loader_spec.rb
|
167
171
|
- spec/easy_downloader/options_spec.rb
|
168
172
|
- spec/spec_helper.rb
|
169
173
|
has_rdoc: true
|
@@ -203,5 +207,6 @@ signing_key:
|
|
203
207
|
specification_version: 3
|
204
208
|
summary: A dead simple, one-method downloader, with friendly error messages
|
205
209
|
test_files:
|
210
|
+
- spec/easy_downloader/abstract_loader_spec.rb
|
206
211
|
- spec/easy_downloader/options_spec.rb
|
207
212
|
- spec/spec_helper.rb
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'net/ftp'
|
2
|
-
module EasyDownloader
|
3
|
-
module FtpDownloader
|
4
|
-
def ftp_download(options)
|
5
|
-
download_count = options.download_count
|
6
|
-
result = options.result
|
7
|
-
result.started
|
8
|
-
Net::FTP.open(options.host,
|
9
|
-
options.user,
|
10
|
-
ftp_password_option(options.password)) do |ftp|
|
11
|
-
|
12
|
-
begin
|
13
|
-
ftp.chdir(options.remote_path)
|
14
|
-
rescue InvalidRemoteDirectory
|
15
|
-
end
|
16
|
-
|
17
|
-
files = ftp.nlst.select {|file_name| options.remote_pattern == '*' || file_name =~ Regexp.new(options.remote_pattern) }
|
18
|
-
puts files.join("\n")
|
19
|
-
total = files.size
|
20
|
-
result.found(files.size, files)
|
21
|
-
|
22
|
-
files.each do |path|
|
23
|
-
result.starting_path(path)
|
24
|
-
ftp.get(path, "#{options.local_path}#{path}")
|
25
|
-
download_count += 1
|
26
|
-
result.finished_path(path)
|
27
|
-
result.files_downloaded << "#{options.local_path}#{path}"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
result.downloaded(download_count)
|
32
|
-
result.finished
|
33
|
-
end
|
34
|
-
|
35
|
-
def ftp_password_option(password)
|
36
|
-
password ? password : nil
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module HttpDownloader
|
2
|
-
def http_download(options)
|
3
|
-
#result = options.result
|
4
|
-
#result.started
|
5
|
-
#Net::SFTP.start(options.host,
|
6
|
-
# options.user,
|
7
|
-
# password_option(options.password)) do |sftp|
|
8
|
-
|
9
|
-
# files = sftp.dir.glob(options.remote_path, options.remote_pattern)
|
10
|
-
# total = files.size
|
11
|
-
# result.found(files.size, files.map(&:name))
|
12
|
-
|
13
|
-
# files.map(&:name).each do |path|
|
14
|
-
# result.starting_path(path)
|
15
|
-
# download_count += 1 if sftp.download!("#{options.remote_path}#{path}", "#{options.destination_dir}#{path}")
|
16
|
-
# result.finished_path(path)
|
17
|
-
# files_downloaded << "#{options.destination_dir}#{path}"
|
18
|
-
# end
|
19
|
-
#end
|
20
|
-
|
21
|
-
#result.downloaded(download_count)
|
22
|
-
#result.finished
|
23
|
-
end
|
24
|
-
|
25
|
-
def password_option(password)
|
26
|
-
password ?
|
27
|
-
{:password => password} :
|
28
|
-
Hash.new
|
29
|
-
end
|
30
|
-
end
|