down 2.3.2 → 2.3.3

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.
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