down 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -19
  3. data/down.gemspec +1 -1
  4. data/lib/down.rb +40 -6
  5. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bba011a45e65446c7b79dbbaf9995b169cd00457
4
- data.tar.gz: cef8bd02a77da2e1274fdc2fe16247c11b97fe77
3
+ metadata.gz: 932ad54eb266b7cc369a8afa2b71eb6a8d70e289
4
+ data.tar.gz: 1976c429007e474fa59221ad90d82da674a875e3
5
5
  SHA512:
6
- metadata.gz: f4cd2ee72598b550d1ec39c57472aadcd31b37f825a168f32ccefb2d7c11dbd3b86aeeb4f14d6dd1bb750b27dc0282c18c2c2214f461274bee542c1a6f2a90e6
7
- data.tar.gz: e3254ce5537d4fc99b870057f8ea647a51af92dfe1d232403d7e72be5b445a012e46306e3a271dbb95228c955804c0d814401d9669cf07f7bbc07c75d7e20f28
6
+ metadata.gz: ff49b59cd8b661135b58070a9079b7989d4ba90ee9727888d050df55e75ab820e0f498b1454470a3696f0bf7abfc31f9ce0bd145cdb93a3e0bf739e29514fe74
7
+ data.tar.gz: 6a158be107f0cc7eecfcecb582e4481c03a255706f4184adcda34bde57ce19715b9ac11c4a09fbc3ec53b9197398c03be30e165e6d04ba1be90a937696eccff8
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Down
2
2
 
3
- Down is a wrapper around `open-uri` for safe downloading of remote files.
3
+ Down is a wrapper around [open-uri] standard library for safe downloading of
4
+ remote files.
4
5
 
5
6
  ## Installation
6
7
 
@@ -66,16 +67,6 @@ terminates the download very early, as soon as it gets the `Content-Length`
66
67
  header. And if the `Content-Length` header is missing, Down will terminate the
67
68
  download as soon as it receives a chunk which surpasses the maximum size.
68
69
 
69
- ### Progress
70
-
71
- You can also tie into the progress of downloading, if you maybe want to display
72
- a progress bar:
73
-
74
- ```rb
75
- Down.download "http://example.com/image.jpg",
76
- progress: ->(size) { ... } # called on each chunk
77
- ```
78
-
79
70
  ### Download errors
80
71
 
81
72
  There are a lot of ways in which a download can fail:
@@ -100,23 +91,29 @@ rescue Down::Error => error
100
91
  end
101
92
  ```
102
93
 
103
- ### Timeout
94
+ ### Additional options
104
95
 
105
- You can specify the time after the request will time out:
96
+ Any additional options will be forwarded to [open-uri], so you can for example
97
+ add basic authentication or a timeout:
106
98
 
107
99
  ```rb
108
- Down.download "http://example.com/image.jpg", timeout: 5
100
+ Down.download "http://example.com/image.jpg",
101
+ http_basic_authentication: ['john', 'secret'],
102
+ read_timeout: 5
109
103
  ```
110
104
 
111
- ### Additional options
105
+ ### Streaming
112
106
 
113
- Any additional options will be forwarded to open-uri, so you can for example
114
- add basic authentication:
107
+ Down has the ability to stream remote files, yielding chunks when they're
108
+ received:
115
109
 
116
110
  ```rb
117
- Down.download "http://example.com/image.jpg", http_basic_authentication: ['john', 'secret']
111
+ Down.stream("http://example.com/image.jpg") { |chunk, content_length| ... }
118
112
  ```
119
113
 
114
+ The `content_length` argument is set from the `Content-Length` response header
115
+ if it's present.
116
+
120
117
  ### Copying to tempfile
121
118
 
122
119
  Down has another "hidden" utility method, `#copy_to_tempfile`, which creates
@@ -124,7 +121,8 @@ a Tempfile out of the given file. The `#download` method uses it internally,
124
121
  but it's also publicly available for direct use:
125
122
 
126
123
  ```rb
127
- tempfile = Down.copy_to_tempfile "path/to/file.jpg"
124
+ io # IO object that you want to copy to tempfile
125
+ tempfile = Down.copy_to_tempfile "basename.jpg", io
128
126
  tempfile.path #=> "/var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/down20151116-77262-jgcx65.jpg"
129
127
  ```
130
128
 
@@ -152,3 +150,5 @@ $ bin/test-versions
152
150
  ## License
153
151
 
154
152
  [MIT](LICENSE.txt)
153
+
154
+ [open-uri]: http://ruby-doc.org/stdlib-2.3.0/libdoc/open-uri/rdoc/OpenURI.html
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "down"
3
- spec.version = "2.0.1"
3
+ spec.version = "2.1.0"
4
4
  spec.authors = ["Janko Marohnić"]
5
5
  spec.email = ["janko.marohnic@gmail.com"]
6
6
 
@@ -1,7 +1,7 @@
1
1
  require "open-uri"
2
2
  require "tempfile"
3
- require "uri"
4
3
  require "fileutils"
4
+ require "cgi/util"
5
5
 
6
6
  module Down
7
7
  class Error < StandardError; end
@@ -13,9 +13,13 @@ module Down
13
13
  def download(url, options = {})
14
14
  uri = URI.parse(url)
15
15
 
16
- max_size = options.delete(:max_size)
17
- progress = options.delete(:progress)
18
- timeout = options.delete(:timeout)
16
+ warn "Passing :timeout option to `Down.download` is deprecated and will be removed in Down 3. You should use open-uri's :open_timeout and/or :read_timeout." if options.key?(:timeout)
17
+ warn "Passing :progress option to `Down.download` is deprecated and will be removed in Down 3. You should use open-uri's :progress_proc." if options.key?(:progress)
18
+
19
+ max_size = options.delete(:max_size)
20
+ progress_proc = options.delete(:progress_proc) || options.delete(:progress)
21
+ content_length_proc = options.delete(:content_length_proc)
22
+ timeout = options.delete(:timeout)
19
23
 
20
24
  downloaded_file = uri.open({
21
25
  "User-Agent" => "Down/1.0.0",
@@ -23,12 +27,13 @@ module Down
23
27
  if size && max_size && size > max_size
24
28
  raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
25
29
  end
30
+ content_length_proc.call(size) if content_length_proc
26
31
  },
27
32
  progress_proc: proc { |current_size|
28
33
  if max_size && current_size > max_size
29
34
  raise Down::TooLarge, "file is too large (max is #{max_size/1024/1024}MB)"
30
35
  end
31
- progress.call(current_size) if progress
36
+ progress_proc.call(current_size) if progress_proc
32
37
  },
33
38
  read_timeout: timeout,
34
39
  redirect: false,
@@ -51,6 +56,35 @@ module Down
51
56
  raise Down::NotFound, "file not found"
52
57
  end
53
58
 
59
+ def stream(url, options = {})
60
+ uri = URI.parse(url)
61
+ http = Net::HTTP.new(uri.host, uri.port)
62
+
63
+ # taken from open-uri implementation
64
+ if uri.is_a?(URI::HTTPS)
65
+ require "net/https"
66
+ http.use_ssl = true
67
+ http.verify_mode = options[:ssl_verify_mode] || OpenSSL::SSL::VERIFY_PEER
68
+ store = OpenSSL::X509::Store.new
69
+ if options[:ssl_ca_cert]
70
+ Array(options[:ssl_ca_cert]).each do |cert|
71
+ File.directory?(cert) ? store.add_path(cert) : store.add_file(cert)
72
+ end
73
+ else
74
+ store.set_default_paths
75
+ end
76
+ http.cert_store = store
77
+ end
78
+
79
+ http.start do
80
+ req = Net::HTTP::Get.new(uri.to_s)
81
+ http.request(req) do |response|
82
+ content_length = response["Content-Length"].to_i if response["Content-Length"]
83
+ response.read_body { |chunk| yield chunk, content_length }
84
+ end
85
+ end
86
+ end
87
+
54
88
  def copy_to_tempfile(basename, io)
55
89
  tempfile = Tempfile.new(["down", File.extname(basename)], binmode: true)
56
90
  if io.is_a?(OpenURI::Meta) && io.is_a?(Tempfile)
@@ -66,7 +100,7 @@ module Down
66
100
  module DownloadedFile
67
101
  def original_filename
68
102
  path = base_uri.path
69
- path = URI.decode(path)
103
+ path = CGI.unescape(path)
70
104
  File.basename(path) unless path.empty? || path == "/"
71
105
  end
72
106
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: down
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janko Marohnić
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-06 00:00:00.000000000 Z
11
+ date: 2016-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -83,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
83
  version: '0'
84
84
  requirements: []
85
85
  rubyforge_project:
86
- rubygems_version: 2.4.5
86
+ rubygems_version: 2.5.1
87
87
  signing_key:
88
88
  specification_version: 4
89
89
  summary: Robust file download from URL using open-uri.