zipline 1.3.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +26 -0
- data/Gemfile +1 -0
- data/README.md +5 -2
- data/lib/zipline/version.rb +1 -1
- data/lib/zipline/zip_generator.rb +4 -3
- data/lib/zipline.rb +4 -3
- data/spec/lib/zipline/zip_generator_spec.rb +30 -5
- data/spec/lib/zipline/zipline_spec.rb +29 -0
- data/spec/spec_helper.rb +2 -0
- data/zipline.gemspec +7 -1
- metadata +39 -9
- data/.travis.yml +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8735b5a6429dcffa8672a1a970cc37145eadfd5e5ff13e2cb5b3f08166895d14
|
4
|
+
data.tar.gz: a4555919f140b0661cb12fd0e6f92900e419319ebf7ec7c376ce19034dffd9a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 758292743ee475bc2a276bd00d953fa4f0b1cb1c4ccd2ceae7b2c7dbeced0e1a901a609d183a68c6eeaa898693045f3d5f4ee23bfece0c35b379fb7ce170cdc2
|
7
|
+
data.tar.gz: 7383e439111008fa964a2d762f6855351d3a0372df973d453e0b205aee57f53d9fc8aea54e4f7efed6719b3b8318768f8d125e314ad277f2855bac29fa63c5e2
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: Tests
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
name: Test (${{ matrix.ruby-version }})
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby-version:
|
14
|
+
- '3.1'
|
15
|
+
- '3.0'
|
16
|
+
- '2.7'
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- uses: actions/checkout@v2
|
20
|
+
- name: Set up Ruby ${{ matrix.ruby-version }}
|
21
|
+
uses: ruby/setup-ruby@v1
|
22
|
+
with:
|
23
|
+
ruby-version: ${{ matrix.ruby-version }}
|
24
|
+
bundler-cache: true # 'bundle install' and cache
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rake
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Zipline
|
2
|
-
[![
|
2
|
+
[![Tests](https://github.com/fringd/zipline/actions/workflows/ci.yml/badge.svg)](https://github.com/fringd/zipline/actions/workflows/ci.yml)
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/zipline.svg)](https://badge.fury.io/rb/zipline)
|
4
4
|
|
5
5
|
A gem to stream dynamically generated zip files from a rails application. Unlike other solutions that generate zips for user download, zipline does not wait for the entire zip file to be created (or even for the entire input file in the cloud to be downloaded) before it begins sending the zip file to the user. It does this by never seeking backwards during zip creation, and streaming the zip file over http as it is constructed. The advantages of this are:
|
@@ -41,7 +41,10 @@ class MyController < ApplicationController
|
|
41
41
|
# responds to :url, :path or :file.
|
42
42
|
# :modification_time is an optional third argument you can use.
|
43
43
|
files = users.map{ |user| [user.avatar, "#{user.username}.png", modification_time: 1.day.ago] }
|
44
|
-
|
44
|
+
|
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 Delegated [ZipTricks::Streamer object](https://github.com/WeTransfer/zip_tricks/blob/main/lib/zip_tricks/streamer.rb#L147) object.
|
47
|
+
zipline(files, 'avatars.zip', auto_rename_duplicate_filenames: true)
|
45
48
|
end
|
46
49
|
end
|
47
50
|
```
|
data/lib/zipline/version.rb
CHANGED
@@ -3,8 +3,9 @@
|
|
3
3
|
module Zipline
|
4
4
|
class ZipGenerator
|
5
5
|
# takes an array of pairs [[uploader, filename], ... ]
|
6
|
-
def initialize(files)
|
6
|
+
def initialize(files, **kwargs_for_new)
|
7
7
|
@files = files
|
8
|
+
@kwargs_for_new = kwargs_for_new
|
8
9
|
end
|
9
10
|
|
10
11
|
#this is supposed to be streamed!
|
@@ -29,7 +30,7 @@ module Zipline
|
|
29
30
|
# this might pose a problem. Unlikely that it will be an issue here though.
|
30
31
|
write_buffer_size = 16 * 1024
|
31
32
|
write_buffer = ZipTricks::WriteBuffer.new(fake_io_writer, write_buffer_size)
|
32
|
-
ZipTricks::Streamer.open(write_buffer) do |streamer|
|
33
|
+
ZipTricks::Streamer.open(write_buffer, **@kwargs_for_new) do |streamer|
|
33
34
|
@files.each do |file, name, options = {}|
|
34
35
|
handle_file(streamer, file, name.to_s, options)
|
35
36
|
end
|
@@ -80,7 +81,7 @@ module Zipline
|
|
80
81
|
end
|
81
82
|
|
82
83
|
def write_file(streamer, file, name, options)
|
83
|
-
streamer.write_deflated_file(name, options) do |writer_for_file|
|
84
|
+
streamer.write_deflated_file(name, **options.slice(:modification_time)) do |writer_for_file|
|
84
85
|
if file[:url]
|
85
86
|
the_remote_uri = URI(file[:url])
|
86
87
|
|
data/lib/zipline.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'content_disposition'
|
1
2
|
require "zipline/version"
|
2
3
|
require 'zip_tricks'
|
3
4
|
require "zipline/zip_generator"
|
@@ -11,9 +12,9 @@ require "zipline/zip_generator"
|
|
11
12
|
# end
|
12
13
|
# end
|
13
14
|
module Zipline
|
14
|
-
def zipline(files, zipname = 'zipline.zip')
|
15
|
-
zip_generator = ZipGenerator.new(files)
|
16
|
-
headers['Content-Disposition'] =
|
15
|
+
def zipline(files, zipname = 'zipline.zip', **kwargs_for_new)
|
16
|
+
zip_generator = ZipGenerator.new(files, **kwargs_for_new)
|
17
|
+
headers['Content-Disposition'] = ContentDisposition.format(disposition: 'attachment', filename: zipname)
|
17
18
|
headers['Content-Type'] = Mime::Type.lookup_by_extension('zip').to_s
|
18
19
|
response.sending_file = true
|
19
20
|
response.cache_control[:public] ||= false
|
@@ -199,7 +199,7 @@ describe Zipline::ZipGenerator do
|
|
199
199
|
it 'passes a string as filename to ZipTricks' do
|
200
200
|
allow(file).to receive(:url).and_return('fakeurl')
|
201
201
|
expect_any_instance_of(ZipTricks::Streamer).to receive(:write_deflated_file)
|
202
|
-
.with('test'
|
202
|
+
.with('test')
|
203
203
|
generator.each { |_| 'Test' }
|
204
204
|
end
|
205
205
|
end
|
@@ -216,11 +216,11 @@ describe Zipline::ZipGenerator do
|
|
216
216
|
|
217
217
|
it 'passes the options hash through handle_file' do
|
218
218
|
expect(generator).to receive(:handle_file)
|
219
|
-
.with(anything, anything, anything, modification_time: mtime)
|
219
|
+
.with(anything, anything, anything, { modification_time: mtime })
|
220
220
|
generator.each { |_| 'Test' }
|
221
221
|
end
|
222
222
|
|
223
|
-
it 'passes the options hash to ZipTricks' do
|
223
|
+
it 'passes the options hash to ZipTricks as kwargs' do
|
224
224
|
allow(file).to receive(:url).and_return('fakeurl')
|
225
225
|
expect_any_instance_of(ZipTricks::Streamer).to receive(:write_deflated_file)
|
226
226
|
.with(anything, modification_time: mtime)
|
@@ -239,12 +239,37 @@ describe Zipline::ZipGenerator do
|
|
239
239
|
generator.each { |_| 'Test' }
|
240
240
|
end
|
241
241
|
|
242
|
-
it 'passes the options hash to ZipTricks' do
|
242
|
+
it 'passes the options hash to ZipTricks as kwargs' do
|
243
243
|
allow(file).to receive(:url).and_return('fakeurl')
|
244
244
|
expect_any_instance_of(ZipTricks::Streamer).to receive(:write_deflated_file)
|
245
|
-
.with(anything
|
245
|
+
.with(anything)
|
246
246
|
generator.each { |_| 'Test' }
|
247
247
|
end
|
248
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' }
|
249
274
|
end
|
250
275
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe Zipline do
|
5
|
+
before { Fog.mock! }
|
6
|
+
|
7
|
+
let (:undertest) {
|
8
|
+
class TestZipline
|
9
|
+
|
10
|
+
attr_accessor :headers
|
11
|
+
attr_accessor :response
|
12
|
+
attr_accessor :response_body
|
13
|
+
def initialize
|
14
|
+
@headers = {}
|
15
|
+
@response = OpenStruct.new(:cache_control => {}, :headers => {} )
|
16
|
+
end
|
17
|
+
include Zipline
|
18
|
+
end
|
19
|
+
return TestZipline.new()
|
20
|
+
}
|
21
|
+
|
22
|
+
|
23
|
+
it 'passes arguments along' do
|
24
|
+
expect(Zipline::ZipGenerator).to receive(:new)
|
25
|
+
.with(['some', 'fake', 'files'], { some: 'options' })
|
26
|
+
undertest.zipline(['some', 'fake', 'files'], 'myfiles.zip', some: 'options')
|
27
|
+
expect(undertest.headers['Content-Disposition']).to eq("attachment; filename=\"myfiles.zip\"; filename*=UTF-8''myfiles.zip")
|
28
|
+
end
|
29
|
+
end
|
data/spec/spec_helper.rb
CHANGED
data/zipline.gemspec
CHANGED
@@ -16,6 +16,12 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.version = Zipline::VERSION
|
17
17
|
gem.licenses = ['MIT']
|
18
18
|
|
19
|
-
gem.
|
19
|
+
gem.required_ruby_version = ">= 2.7"
|
20
|
+
|
21
|
+
gem.add_dependency 'actionpack', ['>= 6.0', '< 8.0']
|
22
|
+
gem.add_dependency 'content_disposition', '~> 1.0'
|
20
23
|
gem.add_dependency 'zip_tricks', ['>= 4.2.1', '< 6.0']
|
24
|
+
|
25
|
+
# https://github.com/rspec/rspec-mocks/issues/1457
|
26
|
+
gem.add_development_dependency 'rspec-mocks', '3.10.2'
|
21
27
|
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: 1.
|
4
|
+
version: 1.5.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: 2022-10-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -16,20 +16,34 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '6.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '8.0'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version:
|
29
|
+
version: '6.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '8.0'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: content_disposition
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '1.0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.0'
|
33
47
|
- !ruby/object:Gem::Dependency
|
34
48
|
name: zip_tricks
|
35
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,6 +64,20 @@ dependencies:
|
|
50
64
|
- - "<"
|
51
65
|
- !ruby/object:Gem::Version
|
52
66
|
version: '6.0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rspec-mocks
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - '='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 3.10.2
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - '='
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 3.10.2
|
53
81
|
description: a module for streaming dynamically generated zip files
|
54
82
|
email:
|
55
83
|
- ram.dobson@solsystemscompany.com
|
@@ -57,7 +85,7 @@ executables: []
|
|
57
85
|
extensions: []
|
58
86
|
extra_rdoc_files: []
|
59
87
|
files:
|
60
|
-
- ".
|
88
|
+
- ".github/workflows/ci.yml"
|
61
89
|
- Gemfile
|
62
90
|
- LICENSE
|
63
91
|
- README.md
|
@@ -67,6 +95,7 @@ files:
|
|
67
95
|
- lib/zipline/zip_generator.rb
|
68
96
|
- spec/fakefile.txt
|
69
97
|
- spec/lib/zipline/zip_generator_spec.rb
|
98
|
+
- spec/lib/zipline/zipline_spec.rb
|
70
99
|
- spec/spec_helper.rb
|
71
100
|
- zipline.gemspec
|
72
101
|
homepage: http://github.com/fringd/zipline
|
@@ -81,18 +110,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
110
|
requirements:
|
82
111
|
- - ">="
|
83
112
|
- !ruby/object:Gem::Version
|
84
|
-
version: '
|
113
|
+
version: '2.7'
|
85
114
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
115
|
requirements:
|
87
116
|
- - ">="
|
88
117
|
- !ruby/object:Gem::Version
|
89
118
|
version: '0'
|
90
119
|
requirements: []
|
91
|
-
rubygems_version: 3.
|
120
|
+
rubygems_version: 3.3.11
|
92
121
|
signing_key:
|
93
122
|
specification_version: 4
|
94
123
|
summary: stream zip files from rails
|
95
124
|
test_files:
|
96
125
|
- spec/fakefile.txt
|
97
126
|
- spec/lib/zipline/zip_generator_spec.rb
|
127
|
+
- spec/lib/zipline/zipline_spec.rb
|
98
128
|
- spec/spec_helper.rb
|