zipline 1.5.0 → 2.0.0
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.
- checksums.yaml +4 -4
- data/Gemfile +0 -11
- data/README.md +3 -3
- data/lib/zipline/version.rb +1 -1
- data/lib/zipline/{zip_generator.rb → zip_handler.rb} +18 -43
- data/lib/zipline.rb +15 -11
- data/spec/lib/zipline/{zip_generator_spec.rb → zip_handler_spec.rb} +14 -101
- data/spec/lib/zipline/zipline_spec.rb +63 -19
- data/spec/spec_helper.rb +6 -7
- data/zipline.gemspec +9 -2
- metadata +105 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 954c769aaf6aa7780a8770fcc9991a1beea5b326f1920b6bfdcc921dcef1a34d
|
4
|
+
data.tar.gz: 7e40d818c5b4e7da8c8167f42e9318d0d7cfee2384657a84fa3ee294184f9819
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a39143123fc75b44b94d88ca0e8d31a41e2b63f9368ff70692c502c21171baf406e4eb8bb7a9f9ef0885d2883d8c5e5d40995499068a2a0a9a9906c9135bc68
|
7
|
+
data.tar.gz: 84c7b320023d7195f619638b87acaa14121852a643a727a9ba5c1d848ed3d4bc045832347586ca3b454dfb753ad189f2bfe96d5e97bd6140065a1fa0ef4675b8
|
data/Gemfile
CHANGED
@@ -2,14 +2,3 @@ source 'https://rubygems.org'
|
|
2
2
|
|
3
3
|
# Specify your gem's dependencies in zipline.gemspec
|
4
4
|
gemspec
|
5
|
-
|
6
|
-
group :development, :test do
|
7
|
-
gem 'rspec', '~> 3'
|
8
|
-
gem 'fog-aws'
|
9
|
-
gem 'activesupport'
|
10
|
-
gem 'actionpack'
|
11
|
-
gem 'aws-sdk-s3'
|
12
|
-
gem 'carrierwave'
|
13
|
-
gem 'paperclip'
|
14
|
-
gem 'rake'
|
15
|
-
end
|
data/README.md
CHANGED
@@ -7,7 +7,7 @@ A gem to stream dynamically generated zip files from a rails application. Unlike
|
|
7
7
|
- Removes need for large disk space or memory allocation to generate zips, even huge zips. So it works on Heroku.
|
8
8
|
- The user begins downloading immediately, which decreaceses latency, download time, and timeouts on Heroku.
|
9
9
|
|
10
|
-
Zipline now depends on [
|
10
|
+
Zipline now depends on [zip_kit](https://github.com/julik/zip_kit), and you might want to just use that directly if you have more advanced use cases.
|
11
11
|
|
12
12
|
## Installation
|
13
13
|
|
@@ -43,7 +43,7 @@ class MyController < ApplicationController
|
|
43
43
|
files = users.map{ |user| [user.avatar, "#{user.username}.png", modification_time: 1.day.ago] }
|
44
44
|
|
45
45
|
# we can force duplicate file names to be renamed, or raise an error
|
46
|
-
# we can also pass in our own writer if required to conform with the
|
46
|
+
# we can also pass in our own writer if required to conform with the delegated [ZipKit::Streamer object](https://github.com/julik/zip_kit/blob/main/lib/zip_kit/streamer.rb#L147) object.
|
47
47
|
zipline(files, 'avatars.zip', auto_rename_duplicate_filenames: true)
|
48
48
|
end
|
49
49
|
end
|
@@ -93,7 +93,7 @@ For directories, just give the files names like "directory/file".
|
|
93
93
|
|
94
94
|
```Ruby
|
95
95
|
avatars = [
|
96
|
-
# remote_url zip_path
|
96
|
+
# remote_url zip_path write_file options for Streamer
|
97
97
|
[ 'http://www.example.com/user1.png', 'avatars/user1.png', modification_time: Time.now.utc ]
|
98
98
|
[ 'http://www.example.com/user2.png', 'avatars/user2.png', modification_time: 1.day.ago ]
|
99
99
|
[ 'http://www.example.com/user3.png', 'avatars/user3.png' ]
|
data/lib/zipline/version.rb
CHANGED
@@ -1,46 +1,21 @@
|
|
1
|
-
# this class acts as a streaming body for rails
|
2
|
-
# initialize it with an array of the files you want to zip
|
3
1
|
module Zipline
|
4
|
-
class
|
2
|
+
class ZipHandler
|
5
3
|
# takes an array of pairs [[uploader, filename], ... ]
|
6
|
-
def initialize(
|
7
|
-
@
|
8
|
-
@
|
4
|
+
def initialize(streamer, logger)
|
5
|
+
@streamer = streamer
|
6
|
+
@logger = logger
|
9
7
|
end
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# There is a built-in facility for this in ZipTricks which can be used to implement
|
22
|
-
# some cheap buffering here (it exists both in version 4 and version 5). The buffer is really
|
23
|
-
# tiny and roughly equal to the medium Linux socket buffer size (16 KB). Although output
|
24
|
-
# will be not so immediate with this buffering the overall performance will be better,
|
25
|
-
# especially with multiple clients being serviced at the same time.
|
26
|
-
# Note that the WriteBuffer writes the same, retained String object - but the contents
|
27
|
-
# of that object changes between calls. This should work fine with servers where the
|
28
|
-
# contents of the string gets written to a socket immediately before the execution inside
|
29
|
-
# the WriteBuffer resumes), but if the strings get retained somewhere - like in an Array -
|
30
|
-
# this might pose a problem. Unlikely that it will be an issue here though.
|
31
|
-
write_buffer_size = 16 * 1024
|
32
|
-
write_buffer = ZipTricks::WriteBuffer.new(fake_io_writer, write_buffer_size)
|
33
|
-
ZipTricks::Streamer.open(write_buffer, **@kwargs_for_new) do |streamer|
|
34
|
-
@files.each do |file, name, options = {}|
|
35
|
-
handle_file(streamer, file, name.to_s, options)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
write_buffer.flush! # for any remaining writes
|
39
|
-
end
|
40
|
-
|
41
|
-
def handle_file(streamer, file, name, options)
|
42
|
-
file = normalize(file)
|
43
|
-
write_file(streamer, file, name, options)
|
9
|
+
def handle_file(file, name, options)
|
10
|
+
normalized_file = normalize(file)
|
11
|
+
write_file(normalized_file, name, options)
|
12
|
+
rescue => e
|
13
|
+
# Since most APM packages do not trace errors occurring within streaming
|
14
|
+
# Rack bodies, it can be helpful to print the error to the Rails log at least
|
15
|
+
error_message = "zipline: an exception (#{e.inspect}) was raised when serving the ZIP body."
|
16
|
+
error_message += " The error occurred when handling file #{name.inspect}"
|
17
|
+
@logger.error(error_message) if @logger
|
18
|
+
raise
|
44
19
|
end
|
45
20
|
|
46
21
|
# This extracts either a url or a local file from the provided file.
|
@@ -80,8 +55,8 @@ module Zipline
|
|
80
55
|
end
|
81
56
|
end
|
82
57
|
|
83
|
-
def write_file(
|
84
|
-
streamer.
|
58
|
+
def write_file(file, name, options)
|
59
|
+
@streamer.write_file(name, **options.slice(:modification_time)) do |writer_for_file|
|
85
60
|
if file[:url]
|
86
61
|
the_remote_uri = URI(file[:url])
|
87
62
|
|
@@ -101,12 +76,12 @@ module Zipline
|
|
101
76
|
end
|
102
77
|
end
|
103
78
|
|
79
|
+
private
|
80
|
+
|
104
81
|
def is_io?(io_ish)
|
105
82
|
io_ish.respond_to? :read
|
106
83
|
end
|
107
84
|
|
108
|
-
private
|
109
|
-
|
110
85
|
def is_active_storage_attachment?(file)
|
111
86
|
defined?(ActiveStorage::Attachment) && file.is_a?(ActiveStorage::Attachment)
|
112
87
|
end
|
data/lib/zipline.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'content_disposition'
|
2
|
-
require
|
3
|
-
require '
|
4
|
-
require
|
2
|
+
require 'zip_kit'
|
3
|
+
require 'zipline/version'
|
4
|
+
require 'zipline/zip_handler'
|
5
5
|
|
6
6
|
# class MyController < ApplicationController
|
7
7
|
# include Zipline
|
@@ -12,13 +12,17 @@ require "zipline/zip_generator"
|
|
12
12
|
# end
|
13
13
|
# end
|
14
14
|
module Zipline
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
def self.included(into_controller)
|
16
|
+
into_controller.include(ZipKit::RailsStreaming)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def zipline(files, zipname = 'zipline.zip', **kwargs_for_zip_kit_stream)
|
21
|
+
zip_kit_stream(filename: zipname, **kwargs_for_zip_kit_stream) do |zip_kit_streamer|
|
22
|
+
handler = Zipline::ZipHandler.new(zip_kit_streamer, logger)
|
23
|
+
files.each do |file, name, options = {}|
|
24
|
+
handler.handle_file(file, name.to_s, options)
|
25
|
+
end
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
@@ -18,7 +18,7 @@ module ActiveStorage
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
describe Zipline::
|
21
|
+
describe Zipline::ZipHandler do
|
22
22
|
before { Fog.mock! }
|
23
23
|
let(:file_attributes){ {
|
24
24
|
key: 'fog_file_tests',
|
@@ -38,21 +38,21 @@ describe Zipline::ZipGenerator do
|
|
38
38
|
let(:file){ directory.files.create(file_attributes) }
|
39
39
|
|
40
40
|
describe '.normalize' do
|
41
|
-
let(:
|
41
|
+
let(:handler){ Zipline::ZipHandler.new(_streamer = double(), _logger = nil)}
|
42
42
|
context "CarrierWave" do
|
43
43
|
context "Remote" do
|
44
44
|
let(:file){ CarrierWave::Storage::Fog::File.new(nil,nil,nil) }
|
45
45
|
it "extracts the url" do
|
46
46
|
allow(file).to receive(:url).and_return('fakeurl')
|
47
47
|
expect(File).not_to receive(:open)
|
48
|
-
expect(
|
48
|
+
expect(handler.normalize(file)).to eq({url: 'fakeurl'})
|
49
49
|
end
|
50
50
|
end
|
51
51
|
context "Local" do
|
52
52
|
let(:file){ CarrierWave::SanitizedFile.new(Tempfile.new('t')) }
|
53
53
|
it "creates a File" do
|
54
54
|
allow(file).to receive(:path).and_return('spec/fakefile.txt')
|
55
|
-
normalized =
|
55
|
+
normalized = handler.normalize(file)
|
56
56
|
expect(normalized.keys).to include(:file)
|
57
57
|
expect(normalized[:file]).to be_a File
|
58
58
|
end
|
@@ -66,7 +66,7 @@ describe Zipline::ZipGenerator do
|
|
66
66
|
allow(uploader).to receive(:file).and_return(file)
|
67
67
|
allow(file).to receive(:url).and_return('fakeurl')
|
68
68
|
expect(File).not_to receive(:open)
|
69
|
-
expect(
|
69
|
+
expect(handler.normalize(uploader)).to eq({url: 'fakeurl'})
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
@@ -75,7 +75,7 @@ describe Zipline::ZipGenerator do
|
|
75
75
|
it "creates a File" do
|
76
76
|
allow(uploader).to receive(:file).and_return(file)
|
77
77
|
allow(file).to receive(:path).and_return('spec/fakefile.txt')
|
78
|
-
normalized =
|
78
|
+
normalized = handler.normalize(uploader)
|
79
79
|
expect(normalized.keys).to include(:file)
|
80
80
|
expect(normalized[:file]).to be_a File
|
81
81
|
end
|
@@ -87,7 +87,7 @@ describe Zipline::ZipGenerator do
|
|
87
87
|
let(:file){ Paperclip::Attachment.new(:name, :instance) }
|
88
88
|
it "creates a File" do
|
89
89
|
allow(file).to receive(:path).and_return('spec/fakefile.txt')
|
90
|
-
normalized =
|
90
|
+
normalized = handler.normalize(file)
|
91
91
|
expect(normalized.keys).to include(:file)
|
92
92
|
expect(normalized[:file]).to be_a File
|
93
93
|
end
|
@@ -97,7 +97,7 @@ describe Zipline::ZipGenerator do
|
|
97
97
|
it "creates a URL" do
|
98
98
|
allow(file).to receive(:expiring_url).and_return('fakeurl')
|
99
99
|
expect(File).to_not receive(:open)
|
100
|
-
expect(
|
100
|
+
expect(handler.normalize(file)).to include(url: 'fakeurl')
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
@@ -107,7 +107,7 @@ describe Zipline::ZipGenerator do
|
|
107
107
|
attached = create_attached_one
|
108
108
|
allow_any_instance_of(Object).to receive(:defined?).and_return(true)
|
109
109
|
|
110
|
-
normalized =
|
110
|
+
normalized = handler.normalize(attached)
|
111
111
|
|
112
112
|
expect(normalized.keys).to include(:blob)
|
113
113
|
expect(normalized[:blob]).to be_a(ActiveStorage::Blob)
|
@@ -119,7 +119,7 @@ describe Zipline::ZipGenerator do
|
|
119
119
|
attachment = create_attachment
|
120
120
|
allow_any_instance_of(Object).to receive(:defined?).and_return(true)
|
121
121
|
|
122
|
-
normalized =
|
122
|
+
normalized = handler.normalize(attachment)
|
123
123
|
|
124
124
|
expect(normalized.keys).to include(:blob)
|
125
125
|
expect(normalized[:blob]).to be_a(ActiveStorage::Blob)
|
@@ -131,7 +131,7 @@ describe Zipline::ZipGenerator do
|
|
131
131
|
blob = create_blob
|
132
132
|
allow_any_instance_of(Object).to receive(:defined?).and_return(true)
|
133
133
|
|
134
|
-
normalized =
|
134
|
+
normalized = handler.normalize(blob)
|
135
135
|
|
136
136
|
expect(normalized.keys).to include(:blob)
|
137
137
|
expect(normalized[:blob]).to be_a(ActiveStorage::Blob)
|
@@ -169,107 +169,20 @@ describe Zipline::ZipGenerator do
|
|
169
169
|
it "extracts url" do
|
170
170
|
allow(file).to receive(:url).and_return('fakeurl')
|
171
171
|
expect(File).not_to receive(:open)
|
172
|
-
expect(
|
172
|
+
expect(handler.normalize(file)).to eq(url: 'fakeurl')
|
173
173
|
end
|
174
174
|
end
|
175
175
|
context "IOStream" do
|
176
176
|
let(:file){ StringIO.new('passthrough')}
|
177
177
|
it "passes through" do
|
178
|
-
expect(
|
178
|
+
expect(handler.normalize(file)).to eq(file: file)
|
179
179
|
end
|
180
180
|
end
|
181
181
|
context "invalid" do
|
182
182
|
let(:file){ Thread.new{} }
|
183
183
|
it "raises error" do
|
184
|
-
expect{
|
184
|
+
expect{handler.normalize(file)}.to raise_error(ArgumentError)
|
185
185
|
end
|
186
186
|
end
|
187
187
|
end
|
188
|
-
|
189
|
-
describe '.write_file' do
|
190
|
-
let(:file) { StringIO.new('passthrough') }
|
191
|
-
|
192
|
-
context 'when passing an ActiveStorage::Filename object as filename' do
|
193
|
-
let(:filename) { ActiveStorage::Filename.new('test') }
|
194
|
-
|
195
|
-
let(:generator) do
|
196
|
-
Zipline::ZipGenerator.new([[file, filename]])
|
197
|
-
end
|
198
|
-
|
199
|
-
it 'passes a string as filename to ZipTricks' do
|
200
|
-
allow(file).to receive(:url).and_return('fakeurl')
|
201
|
-
expect_any_instance_of(ZipTricks::Streamer).to receive(:write_deflated_file)
|
202
|
-
.with('test')
|
203
|
-
generator.each { |_| 'Test' }
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
describe 'passing an options hash' do
|
209
|
-
let(:file) { StringIO.new('passthrough') }
|
210
|
-
|
211
|
-
context 'with optional arguments' do
|
212
|
-
let(:mtime) { 1.day.ago }
|
213
|
-
let(:generator) do
|
214
|
-
Zipline::ZipGenerator.new([[file, 'test', modification_time: mtime]])
|
215
|
-
end
|
216
|
-
|
217
|
-
it 'passes the options hash through handle_file' do
|
218
|
-
expect(generator).to receive(:handle_file)
|
219
|
-
.with(anything, anything, anything, { modification_time: mtime })
|
220
|
-
generator.each { |_| 'Test' }
|
221
|
-
end
|
222
|
-
|
223
|
-
it 'passes the options hash to ZipTricks as kwargs' do
|
224
|
-
allow(file).to receive(:url).and_return('fakeurl')
|
225
|
-
expect_any_instance_of(ZipTricks::Streamer).to receive(:write_deflated_file)
|
226
|
-
.with(anything, modification_time: mtime)
|
227
|
-
generator.each { |_| 'Test' }
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
context 'without optional arguments' do
|
232
|
-
let(:generator) do
|
233
|
-
Zipline::ZipGenerator.new([[file, 'test']])
|
234
|
-
end
|
235
|
-
|
236
|
-
it 'passes the options hash through handle_file' do
|
237
|
-
expect(generator).to receive(:handle_file)
|
238
|
-
.with(anything, anything, anything, {})
|
239
|
-
generator.each { |_| 'Test' }
|
240
|
-
end
|
241
|
-
|
242
|
-
it 'passes the options hash to ZipTricks as kwargs' do
|
243
|
-
allow(file).to receive(:url).and_return('fakeurl')
|
244
|
-
expect_any_instance_of(ZipTricks::Streamer).to receive(:write_deflated_file)
|
245
|
-
.with(anything)
|
246
|
-
generator.each { |_| 'Test' }
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
context 'with extra invalid options' do
|
251
|
-
let(:mtime) { 1.day.ago }
|
252
|
-
let(:generator) do
|
253
|
-
Zipline::ZipGenerator.new([[file, 'test', modification_time: mtime, extra: 'invalid']])
|
254
|
-
end
|
255
|
-
|
256
|
-
it 'passes the whole options hash through handle_file' do
|
257
|
-
expect(generator).to receive(:handle_file)
|
258
|
-
.with(anything, anything, anything, { modification_time: mtime, extra: 'invalid' })
|
259
|
-
generator.each { |_| 'Test' }
|
260
|
-
end
|
261
|
-
|
262
|
-
it 'only passes the kwargs to ZipTricks that it expects (i.e., :modification_time)' do
|
263
|
-
allow(file).to receive(:url).and_return('fakeurl')
|
264
|
-
expect_any_instance_of(ZipTricks::Streamer).to receive(:write_deflated_file)
|
265
|
-
.with(anything, modification_time: mtime)
|
266
|
-
generator.each { |_| 'Test' }
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
it 'passes along constructor options to ZipTricks streamer' do
|
271
|
-
expect(ZipTricks::Streamer).to receive(:open).with(anything, { :some => 'options' })
|
272
|
-
generator = Zipline::ZipGenerator.new([file, 'somefile'], :some => 'options')
|
273
|
-
generator.each { |_| 'Test' }
|
274
|
-
end
|
275
188
|
end
|
@@ -1,29 +1,73 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require '
|
2
|
+
require 'action_controller'
|
3
3
|
|
4
4
|
describe Zipline do
|
5
|
-
before
|
5
|
+
before do
|
6
|
+
Fog.mock!
|
7
|
+
FakeController.logger = nil
|
8
|
+
end
|
6
9
|
|
7
|
-
|
8
|
-
|
10
|
+
class FakeController < ActionController::Base
|
11
|
+
include Zipline
|
12
|
+
def download_zip
|
13
|
+
files = [
|
14
|
+
[StringIO.new("File content goes here"), "one.txt"],
|
15
|
+
[StringIO.new("Some other content goes here"), "two.txt"]
|
16
|
+
]
|
17
|
+
zipline(files, 'myfiles.zip', auto_rename_duplicate_filenames: false)
|
18
|
+
end
|
9
19
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def initialize
|
14
|
-
@headers = {}
|
15
|
-
@response = OpenStruct.new(:cache_control => {}, :headers => {} )
|
20
|
+
class FailingIO < StringIO
|
21
|
+
def read(*)
|
22
|
+
raise "Something wonky"
|
16
23
|
end
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
24
|
+
end
|
25
|
+
|
26
|
+
def download_zip_with_error_during_streaming
|
27
|
+
files = [
|
28
|
+
[StringIO.new("File content goes here"), "one.txt"],
|
29
|
+
[FailingIO.new("This will fail half-way"), "two.txt"]
|
30
|
+
]
|
31
|
+
zipline(files, 'myfiles.zip', auto_rename_duplicate_filenames: false)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'passes keyword parameters to ZipKit::OutputEnumerator' do
|
36
|
+
fake_rack_env = {
|
37
|
+
"HTTP_VERSION" => "HTTP/1.0",
|
38
|
+
"REQUEST_METHOD" => "GET",
|
39
|
+
"SCRIPT_NAME" => "",
|
40
|
+
"PATH_INFO" => "/download",
|
41
|
+
"QUERY_STRING" => "",
|
42
|
+
"SERVER_NAME" => "host.example",
|
43
|
+
"rack.input" => StringIO.new,
|
44
|
+
}
|
45
|
+
expect(ZipKit::OutputEnumerator).to receive(:new).with(auto_rename_duplicate_filenames: false).and_call_original
|
46
|
+
|
47
|
+
status, headers, body = FakeController.action(:download_zip).call(fake_rack_env)
|
48
|
+
|
49
|
+
expect(headers['Content-Disposition']).to eq("attachment; filename=\"myfiles.zip\"; filename*=UTF-8''myfiles.zip")
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'sends the exception raised in the streaming body to the Rails logger' do
|
53
|
+
fake_rack_env = {
|
54
|
+
"HTTP_VERSION" => "HTTP/1.0",
|
55
|
+
"REQUEST_METHOD" => "GET",
|
56
|
+
"SCRIPT_NAME" => "",
|
57
|
+
"PATH_INFO" => "/download",
|
58
|
+
"QUERY_STRING" => "",
|
59
|
+
"SERVER_NAME" => "host.example",
|
60
|
+
"rack.input" => StringIO.new,
|
61
|
+
}
|
62
|
+
fake_logger = double()
|
63
|
+
allow(fake_logger).to receive(:warn)
|
64
|
+
expect(fake_logger).to receive(:error).with(a_string_matching(/when serving the ZIP/))
|
21
65
|
|
66
|
+
FakeController.logger = fake_logger
|
22
67
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
expect(undertest.headers['Content-Disposition']).to eq("attachment; filename=\"myfiles.zip\"; filename*=UTF-8''myfiles.zip")
|
68
|
+
expect {
|
69
|
+
status, headers, body = FakeController.action(:download_zip_with_error_during_streaming).call(fake_rack_env)
|
70
|
+
body.each { }
|
71
|
+
}.to raise_error(/Something wonky/)
|
28
72
|
end
|
29
73
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -8,17 +8,16 @@ require 'paperclip'
|
|
8
8
|
require 'fog-aws'
|
9
9
|
require 'carrierwave'
|
10
10
|
|
11
|
-
Dir["#{File.expand_path('..', __FILE__)}/support/**/*.rb"].each { |f| require f }
|
11
|
+
Dir["#{File.expand_path('..', __FILE__)}/support/**/*.rb"].sort.each { |f| require f }
|
12
12
|
|
13
13
|
CarrierWave.configure do |config|
|
14
14
|
config.fog_provider = 'fog/aws'
|
15
15
|
config.fog_credentials = {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
provider: 'AWS',
|
17
|
+
aws_access_key_id: 'dummy',
|
18
|
+
aws_secret_access_key: 'data',
|
19
|
+
region: 'us-west-2',
|
20
|
+
}
|
22
21
|
end
|
23
22
|
|
24
23
|
RSpec.configure do |config|
|
data/zipline.gemspec
CHANGED
@@ -20,8 +20,15 @@ Gem::Specification.new do |gem|
|
|
20
20
|
|
21
21
|
gem.add_dependency 'actionpack', ['>= 6.0', '< 8.0']
|
22
22
|
gem.add_dependency 'content_disposition', '~> 1.0'
|
23
|
-
gem.add_dependency '
|
23
|
+
gem.add_dependency 'zip_kit', ['~> 6', '>= 6.2.0', '< 7']
|
24
|
+
|
25
|
+
gem.add_development_dependency 'rspec', '~> 3'
|
26
|
+
gem.add_development_dependency 'fog-aws'
|
27
|
+
gem.add_development_dependency 'aws-sdk-s3'
|
28
|
+
gem.add_development_dependency 'carrierwave'
|
29
|
+
gem.add_development_dependency 'paperclip'
|
30
|
+
gem.add_development_dependency 'rake'
|
24
31
|
|
25
32
|
# https://github.com/rspec/rspec-mocks/issues/1457
|
26
|
-
gem.add_development_dependency 'rspec-mocks', '3.
|
33
|
+
gem.add_development_dependency 'rspec-mocks', '~> 3.12'
|
27
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zipline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ram Dobson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -45,39 +45,129 @@ dependencies:
|
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '1.0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
48
|
+
name: zip_kit
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
50
50
|
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '6'
|
51
54
|
- - ">="
|
52
55
|
- !ruby/object:Gem::Version
|
53
|
-
version:
|
56
|
+
version: 6.2.0
|
54
57
|
- - "<"
|
55
58
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
59
|
+
version: '7'
|
57
60
|
type: :runtime
|
58
61
|
prerelease: false
|
59
62
|
version_requirements: !ruby/object:Gem::Requirement
|
60
63
|
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '6'
|
61
67
|
- - ">="
|
62
68
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
69
|
+
version: 6.2.0
|
64
70
|
- - "<"
|
65
71
|
- !ruby/object:Gem::Version
|
66
|
-
version: '
|
72
|
+
version: '7'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rspec
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '3'
|
80
|
+
type: :development
|
81
|
+
prerelease: false
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - "~>"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '3'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: fog-aws
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
type: :development
|
95
|
+
prerelease: false
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
name: aws-sdk-s3
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: carrierwave
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - ">="
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
type: :development
|
123
|
+
prerelease: false
|
124
|
+
version_requirements: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
- !ruby/object:Gem::Dependency
|
130
|
+
name: paperclip
|
131
|
+
requirement: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
type: :development
|
137
|
+
prerelease: false
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
- !ruby/object:Gem::Dependency
|
144
|
+
name: rake
|
145
|
+
requirement: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - ">="
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
67
157
|
- !ruby/object:Gem::Dependency
|
68
158
|
name: rspec-mocks
|
69
159
|
requirement: !ruby/object:Gem::Requirement
|
70
160
|
requirements:
|
71
|
-
- -
|
161
|
+
- - "~>"
|
72
162
|
- !ruby/object:Gem::Version
|
73
|
-
version: 3.
|
163
|
+
version: '3.12'
|
74
164
|
type: :development
|
75
165
|
prerelease: false
|
76
166
|
version_requirements: !ruby/object:Gem::Requirement
|
77
167
|
requirements:
|
78
|
-
- -
|
168
|
+
- - "~>"
|
79
169
|
- !ruby/object:Gem::Version
|
80
|
-
version: 3.
|
170
|
+
version: '3.12'
|
81
171
|
description: a module for streaming dynamically generated zip files
|
82
172
|
email:
|
83
173
|
- ram.dobson@solsystemscompany.com
|
@@ -92,9 +182,9 @@ files:
|
|
92
182
|
- Rakefile
|
93
183
|
- lib/zipline.rb
|
94
184
|
- lib/zipline/version.rb
|
95
|
-
- lib/zipline/
|
185
|
+
- lib/zipline/zip_handler.rb
|
96
186
|
- spec/fakefile.txt
|
97
|
-
- spec/lib/zipline/
|
187
|
+
- spec/lib/zipline/zip_handler_spec.rb
|
98
188
|
- spec/lib/zipline/zipline_spec.rb
|
99
189
|
- spec/spec_helper.rb
|
100
190
|
- zipline.gemspec
|
@@ -117,12 +207,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
117
207
|
- !ruby/object:Gem::Version
|
118
208
|
version: '0'
|
119
209
|
requirements: []
|
120
|
-
rubygems_version: 3.3.
|
210
|
+
rubygems_version: 3.3.26
|
121
211
|
signing_key:
|
122
212
|
specification_version: 4
|
123
213
|
summary: stream zip files from rails
|
124
214
|
test_files:
|
125
215
|
- spec/fakefile.txt
|
126
|
-
- spec/lib/zipline/
|
216
|
+
- spec/lib/zipline/zip_handler_spec.rb
|
127
217
|
- spec/lib/zipline/zipline_spec.rb
|
128
218
|
- spec/spec_helper.rb
|