down 2.3.2 → 2.3.3

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 +36 -4
  3. data/lib/down.rb +28 -14
  4. data/lib/down/version.rb +1 -1
  5. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 351b0f1708bc156090b334caf7ad619cd439dee6
4
- data.tar.gz: 72b4dbb2e6a62358292dddbea558c406477c5167
3
+ metadata.gz: 37212a130ab08cdcb38cbb6bcdd207bd8f3d56ec
4
+ data.tar.gz: eff7327b20920806bc416e469d924c82fa8ea980
5
5
  SHA512:
6
- metadata.gz: c1387a3d10dae8c1c22df454d7dc47d16e6b9a752329168a86f8c9934713dab3e32b079afb6d0231901129dfc6cea5c27eda2129271e9d825c5ca01259362aae
7
- data.tar.gz: 6be19252cc1a7b9439c26ca87da199e4c009e5c5286bd3a3809db8ca9eff9600ad9bdd4bb3c7c8572e864990d03a6b3ba9e4246b140be9a6f58cc1432b931a25
6
+ metadata.gz: 2418a368cc8e8c0118650bf46d23660ecf30cb3aa0da5f8dc78fa84df9d3200e655367a8279f9b030d1be5fd89fa5d946fc5346b3ef3f144fe1e801c6c7b3ed6
7
+ data.tar.gz: f7a4f49dc00a43251582ee8cf0d08c3f217e42ba8e4f6bb944b1e884a99e055c2af92b3c52e4381c9166b9935140a1df9d12681542febaeab6cc1230c0bb2592
data/README.md CHANGED
@@ -127,10 +127,10 @@ tempfile.path #=> "/var/folders/k7/6zx6dx6x7ys3rv3srh0nyfj00000gn/T/down20151116
127
127
 
128
128
  ## Streaming
129
129
 
130
- Down has the ability to stream the remote file as it is being downloaded. The
131
- `Down.open` method returns an IO object which represents the remote file on the
132
- given URL. When you read from it, Down internally downloads chunks of the
133
- remote file, but only how much is needed.
130
+ Down has the ability to access contents of the remote file *as it is being
131
+ downloaded*. The `Down.open` method returns an IO object which represents the
132
+ remote file on the given URL. When you read from it, Down internally downloads
133
+ chunks of the remote file, but only how much is needed.
134
134
 
135
135
  ```rb
136
136
  remote_file = Down.open("http://example.com/image.jpg")
@@ -154,8 +154,40 @@ remote_file = Down.open("http://example.com/image.jpg")
154
154
  remote_file.each_chunk do |chunk|
155
155
  # ...
156
156
  end
157
+ remote_file.close
157
158
  ```
158
159
 
160
+ ### `Down::ChunkedIO`
161
+
162
+ The `Down.open` method uses `Down::ChunkedIO` internally. However,
163
+ `Down::ChunkedIO` is designed to be generic, it can wrap any kind of streaming.
164
+
165
+ ```rb
166
+ Down::ChunkedIO.new(...)
167
+ ```
168
+
169
+ * `:size` – size of the file, if it's known
170
+ * `:chunks` – an `Enumerator` which returns chunks
171
+ * `:on_close` – called when streaming finishes
172
+
173
+ Here is an example of wrapping streaming MongoDB files:
174
+
175
+ ```rb
176
+ mongo = Mongo::Client.new(...)
177
+ bucket = mongo.database.fs
178
+
179
+ content_length = bucket.find(_id: id).first["length"]
180
+ stream = bucket.open_download_stream(id)
181
+
182
+ io = Down::ChunkedIO.new(
183
+ size: content_length,
184
+ chunks: stream.enum_for(:each),
185
+ on_close: -> { stream.close },
186
+ )
187
+ ```
188
+
189
+ ### Down
190
+
159
191
  ## Supported Ruby versions
160
192
 
161
193
  * MRI 1.9.3
@@ -138,9 +138,8 @@ module Down
138
138
  def initialize(options)
139
139
  @size = options.fetch(:size)
140
140
  @chunks = options.fetch(:chunks)
141
- @on_close = options.fetch(:on_close, nil)
141
+ @on_close = options.fetch(:on_close, ->{})
142
142
  @tempfile = Tempfile.new("down", binmode: true)
143
- @eof = false
144
143
  end
145
144
 
146
145
  def size
@@ -148,19 +147,17 @@ module Down
148
147
  end
149
148
 
150
149
  def read(length = nil, outbuf = nil)
151
- loop do
152
- break if length && (@tempfile.pos + length <= @tempfile.size)
153
- next_chunk or break
154
- end
150
+ download_chunk until enough_downloaded?(length) || download_finished?
155
151
  @tempfile.read(length, outbuf)
156
152
  end
157
153
 
158
- def each_chunk(&block)
159
- @chunks.each(&block)
154
+ def each_chunk
155
+ return enum_for(__method__) if !block_given?
156
+ yield download_chunk until download_finished?
160
157
  end
161
158
 
162
159
  def eof?
163
- @eof
160
+ @tempfile.eof? && download_finished?
164
161
  end
165
162
 
166
163
  def rewind
@@ -168,19 +165,36 @@ module Down
168
165
  end
169
166
 
170
167
  def close
171
- @on_close.call if @on_close
168
+ terminate_download
172
169
  @tempfile.close!
173
170
  end
174
171
 
175
172
  private
176
173
 
177
- def next_chunk
174
+ def download_chunk
178
175
  chunk = @chunks.next
179
176
  write(chunk)
177
+ begin
178
+ @chunks.peek
179
+ rescue StopIteration
180
+ terminate_download
181
+ end
180
182
  chunk
181
- rescue StopIteration
182
- @eof = true
183
- nil
183
+ end
184
+
185
+ def enough_downloaded?(length)
186
+ length && (@tempfile.pos + length <= @tempfile.size)
187
+ end
188
+
189
+ def download_finished?
190
+ !@on_close
191
+ end
192
+
193
+ def terminate_download
194
+ if @on_close
195
+ @on_close.call
196
+ @on_close = nil
197
+ end
184
198
  end
185
199
 
186
200
  def write(chunk)
@@ -1,3 +1,3 @@
1
1
  module Down
2
- VERSION = "2.3.2"
2
+ VERSION = "2.3.3"
3
3
  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.3.2
4
+ version: 2.3.3
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-06-22 00:00:00.000000000 Z
11
+ date: 2016-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake