active_storage-send_zip 0.1.1 → 0.2.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/CHANGELOG.yml +11 -0
- data/Gemfile.lock +1 -1
- data/README.md +62 -21
- data/active_storage-send_zip.gemspec +1 -1
- data/lib/active_storage/send_zip.rb +6 -72
- data/lib/active_storage/send_zip/version.rb +2 -1
- data/lib/active_storage/send_zip_helper.rb +89 -0
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5dbef1dda4a5236e3290d9cd38a23de7e296b5e404356bf222dfbeb0c75197b
|
4
|
+
data.tar.gz: d2558817de8b496c48606c1e3af71df086480eede14b55186ea4a5e7206bfe5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49f3758cc21c8a66dce8f69fe231c679f0802ad8374a222f8a178557ac668b5c2cf3ce7ea4a4f1d0c1e40dcb701a65c200de7bea3e82089cc56a3e20d9495e5f
|
7
|
+
data.tar.gz: 8830d24a60774f277e4576614243a077f661d08313259aaa501692ca5f58cb5bb13ef8975e6659432433d366195211e5f3c38c8bd25e2312feee1352908bf7a6
|
data/CHANGELOG.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
0.2.0:
|
2
|
+
- move some methods to avoid to polute controller methods
|
3
|
+
- `ActiveStorage::SendZip#save_files_on_server` become `ActiveStorage::SendZipHelperSendZip#save_files_on_server`
|
4
|
+
- `SendZip#save_file_on_server` become `ActiveStorage::SendZipHelperSendZip#save_file_on_server`
|
5
|
+
- `SendZip#create_temporary_zip_file` become `ActiveStorage::SendZipHelperSendZip#create_temporary_zip_file`
|
6
|
+
- `send_zip` can now handle an `Hash` param to organize in subfolder
|
7
|
+
0.1.1:
|
8
|
+
- handle double filenames
|
9
|
+
- use a radom folder instead of fixed one (this was problematic qith multiples queries at the same times)
|
10
|
+
0.1.0:
|
11
|
+
- first versions
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,27 +1,14 @@
|
|
1
1
|
# ActiveStorage::SendZip
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/active_storage-send_zip)
|
4
|
+
[](https://opensource.org/licenses/mit-license.php)
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
gem 'active_storage-send_zip'
|
13
|
-
```
|
14
|
-
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install active_storage-send_zip
|
6
|
+
Add a `send_zip` method in your Rails controller to send a `.zip` file containing one or many [ActiveStorage](https://edgeguides.rubyonrails.org/active_storage_overview.html) objects.
|
22
7
|
|
23
8
|
## Usage
|
24
9
|
|
10
|
+
### With `Array`
|
11
|
+
|
25
12
|
Assuming you have an ActiveRecord model with ActiveStorage like this:
|
26
13
|
|
27
14
|
~~~ruby
|
@@ -51,6 +38,64 @@ class UsersController < ApplicationController
|
|
51
38
|
end
|
52
39
|
~~~
|
53
40
|
|
41
|
+
Will produce a `.zip` archive like this:
|
42
|
+
|
43
|
+
~~~
|
44
|
+
├── a.jpg
|
45
|
+
├── b.png
|
46
|
+
└── c.gif
|
47
|
+
~~~
|
48
|
+
|
49
|
+
Ii will also prevent duplicate filename and add an [`SecureRandom.uuid`](https://ruby-doc.org/stdlib-2.3.0/libdoc/securerandom/rdoc/SecureRandom.html) if two files as the same name.
|
50
|
+
|
51
|
+
|
52
|
+
### With `Hash`
|
53
|
+
|
54
|
+
You can also pass an `Hash` parameter at `send_zip` method to organize files in sublfolder:
|
55
|
+
|
56
|
+
~~~ruby
|
57
|
+
# app/controllers/holidays_controller.rb
|
58
|
+
class HolidaysController < ApplicationController
|
59
|
+
include ActiveStorage::SendZip
|
60
|
+
|
61
|
+
def zip
|
62
|
+
send_zip {
|
63
|
+
'Holidays in Lyon <3' => Holidays.where(place: 'lyon').first.pictures,
|
64
|
+
'Holidays in Paris' => Holidays.where(place: 'paris').first.pictures,
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
~~~
|
69
|
+
|
70
|
+
Will produce a `.zip` archive like this:
|
71
|
+
|
72
|
+
~~~
|
73
|
+
├── Holidays in Lyon <3
|
74
|
+
│ ├── a.jpg
|
75
|
+
│ ├── b.png
|
76
|
+
│ └── c.gif
|
77
|
+
└── Holidays in Paris
|
78
|
+
├── a.jpg
|
79
|
+
├── b.png
|
80
|
+
└── c.gif
|
81
|
+
~~~
|
82
|
+
|
83
|
+
## Installation
|
84
|
+
|
85
|
+
Add this line to your application's Gemfile:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
gem 'active_storage-send_zip'
|
89
|
+
```
|
90
|
+
|
91
|
+
And then execute:
|
92
|
+
|
93
|
+
$ bundle
|
94
|
+
|
95
|
+
Or install it yourself as:
|
96
|
+
|
97
|
+
$ gem install active_storage-send_zip
|
98
|
+
|
54
99
|
## Development
|
55
100
|
|
56
101
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -61,10 +106,6 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
61
106
|
|
62
107
|
Bug reports and pull requests are welcome on GitHub at https://github.com/madeindjs/active_storage-send_zip. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
63
108
|
|
64
|
-
## License
|
65
|
-
|
66
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
67
|
-
|
68
109
|
## Code of Conduct
|
69
110
|
|
70
111
|
Everyone interacting in the ActiveStorage::SendZip project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/madeindjs/active_storage-send_zip/blob/master/CODE_OF_CONDUCT.md).
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.email = ['contact@rousseau-alexandre.fr']
|
10
10
|
|
11
11
|
spec.summary = 'Create a zip from one or more Active Storage objects'
|
12
|
-
spec.description = '
|
12
|
+
spec.description = 'Add a `send_zip` method in your Rails controller to send a `.zip` file containing one (or many) ActiveStorage object(s)'
|
13
13
|
spec.homepage = 'https://github.com/madeindjs/active_storage-send_zip'
|
14
14
|
spec.license = 'MIT'
|
15
15
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'active_storage/send_zip/version'
|
2
|
-
require '
|
3
|
-
require 'zip'
|
4
|
-
require 'tempfile'
|
5
|
-
require 'pathname'
|
2
|
+
require 'active_storage/send_zip_helper'
|
6
3
|
|
4
|
+
# I `ActiveStorage` namespace to monkey-path my methods into it
|
7
5
|
module ActiveStorage
|
6
|
+
# This is an `ActiveSupport::Concern` to include into your controller.
|
7
|
+
# The purpose is just to add a `send_zip` method to your controller
|
8
8
|
module SendZip
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
@@ -16,76 +16,10 @@ module ActiveStorage
|
|
16
16
|
# @param filename [ActiveStorage::Attached::Many] files to save
|
17
17
|
def send_zip(active_storages, filename: 'my.zip')
|
18
18
|
require 'zip'
|
19
|
-
files = save_files_on_server active_storages
|
20
|
-
zip_data = create_temporary_zip_file files
|
19
|
+
files = SendZipHelper.save_files_on_server active_storages
|
20
|
+
zip_data = SendZipHelper.create_temporary_zip_file files
|
21
21
|
|
22
22
|
send_data(zip_data, type: 'application/zip', filename: filename)
|
23
23
|
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
# Download active storage files on server in a temporary folder
|
28
|
-
#
|
29
|
-
# @param files [ActiveStorage::Attached::Many] files to save
|
30
|
-
# @return [Array<String>] files paths of saved files
|
31
|
-
def save_files_on_server(files)
|
32
|
-
require 'zip'
|
33
|
-
# get a temporary folder and create it
|
34
|
-
temp_folder = Dir.mktmpdir 'active_storage-send_zip'
|
35
|
-
|
36
|
-
# count each files to avoid duplicates
|
37
|
-
filepaths = []
|
38
|
-
|
39
|
-
# download all ActiveStorage into
|
40
|
-
files.each do |picture|
|
41
|
-
filename = picture.filename.to_s
|
42
|
-
filepath = File.join temp_folder, filename
|
43
|
-
|
44
|
-
# ensure that filename not exists
|
45
|
-
if filepaths.include? filepath
|
46
|
-
# create a new random filenames
|
47
|
-
basename = File.basename filename
|
48
|
-
extension = File.extname filename
|
49
|
-
|
50
|
-
filename = "#{basename}_#{SecureRandom.uuid}#{extension}"
|
51
|
-
filepath = File.join temp_folder, filename
|
52
|
-
end
|
53
|
-
|
54
|
-
File.open(filepath, 'wb') { |f| f.write(picture.download) }
|
55
|
-
|
56
|
-
filepaths << filepath
|
57
|
-
end
|
58
|
-
|
59
|
-
filepaths
|
60
|
-
end
|
61
|
-
|
62
|
-
# Create a temporary zip file & return the content as bytes
|
63
|
-
#
|
64
|
-
# @param filepaths [Array<String>] files paths
|
65
|
-
# @return [String] as content of zip
|
66
|
-
def create_temporary_zip_file(filepaths)
|
67
|
-
temp_file = Tempfile.new('user.zip')
|
68
|
-
|
69
|
-
begin
|
70
|
-
# Initialize the temp file as a zip file
|
71
|
-
Zip::OutputStream.open(temp_file) { |zos| }
|
72
|
-
|
73
|
-
# open the zip
|
74
|
-
Zip::File.open(temp_file.path, Zip::File::CREATE) do |zip|
|
75
|
-
filepaths.each do |filepath|
|
76
|
-
filename = File.basename filepath
|
77
|
-
# add file into the zip
|
78
|
-
zip.add filename, filepath
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
return File.read(temp_file.path)
|
83
|
-
ensure
|
84
|
-
# close all ressources & remove temporary files
|
85
|
-
temp_file.close
|
86
|
-
temp_file.unlink
|
87
|
-
filepaths.each { |filepath| FileUtils.rm(filepath) }
|
88
|
-
end
|
89
|
-
end
|
90
24
|
end
|
91
25
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'zip'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'pathname'
|
5
|
+
|
6
|
+
module ActiveStorage
|
7
|
+
# This module contains some methods usefull for `ActiveStorage::SendZip.send_zip`
|
8
|
+
# method.
|
9
|
+
module SendZipHelper
|
10
|
+
# Download active storage files on server in a temporary folder
|
11
|
+
#
|
12
|
+
# @param files [ActiveStorage::Attached::Many] files to save
|
13
|
+
# @return [Array<String>] files paths of saved files
|
14
|
+
def self.save_files_on_server(files)
|
15
|
+
require 'zip'
|
16
|
+
# get a temporary folder and create it
|
17
|
+
temp_folder = Dir.mktmpdir 'active_storage-send_zip'
|
18
|
+
|
19
|
+
if files.is_a? Array
|
20
|
+
return files.map { |file| save_file_on_server(file, temp_folder) }
|
21
|
+
elsif files.is_a? Hash
|
22
|
+
filepaths = []
|
23
|
+
|
24
|
+
files.each do |subfolder, filesHash|
|
25
|
+
filesHash.each { |f| filepaths << save_file_on_server(f, temp_folder, subfolder: subfolder) }
|
26
|
+
end
|
27
|
+
|
28
|
+
return filepaths
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Save the given file on the server
|
33
|
+
#
|
34
|
+
# @param file [ActiveStorage::Attached] files to save
|
35
|
+
# @param folder [String] where to store the file
|
36
|
+
# @return [String] the filepath of file created
|
37
|
+
def self.save_file_on_server(file, folder, subfolder: nil)
|
38
|
+
filename = file.filename.to_s
|
39
|
+
|
40
|
+
folder = File.join(folder, subfolder) unless subfolder.nil?
|
41
|
+
Dir.mkdir(folder) unless Dir.exist?(folder)
|
42
|
+
|
43
|
+
# build filepath & create path if not exists
|
44
|
+
filepath = File.join(folder, filename)
|
45
|
+
|
46
|
+
# Ensure that filename not already exists
|
47
|
+
if File.exist? filepath
|
48
|
+
# create a new random filenames
|
49
|
+
basename = File.basename filename
|
50
|
+
extension = File.extname filename
|
51
|
+
|
52
|
+
filename = "#{basename}_#{SecureRandom.uuid}#{extension}"
|
53
|
+
filepath = File.join folder, filename
|
54
|
+
end
|
55
|
+
|
56
|
+
File.open(filepath, 'wb') { |f| f.write(file.download) }
|
57
|
+
filepath
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create a temporary zip file & return the content as bytes
|
61
|
+
#
|
62
|
+
# @param filepaths [Array<String>] files paths
|
63
|
+
# @return [String] as content of zip
|
64
|
+
def self.create_temporary_zip_file(filepaths)
|
65
|
+
temp_file = Tempfile.new('user.zip')
|
66
|
+
|
67
|
+
begin
|
68
|
+
# Initialize the temp file as a zip file
|
69
|
+
Zip::OutputStream.open(temp_file) { |zos| }
|
70
|
+
|
71
|
+
# open the zip
|
72
|
+
Zip::File.open(temp_file.path, Zip::File::CREATE) do |zip|
|
73
|
+
filepaths.each do |filepath|
|
74
|
+
filename = File.basename filepath
|
75
|
+
# add file into the zip
|
76
|
+
zip.add filename, filepath
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
return File.read(temp_file.path)
|
81
|
+
ensure
|
82
|
+
# close all ressources & remove temporary files
|
83
|
+
temp_file.close
|
84
|
+
temp_file.unlink
|
85
|
+
filepaths.each { |filepath| FileUtils.rm(filepath) }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_storage-send_zip
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexandre Rousseau
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-12-
|
11
|
+
date: 2018-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,8 +52,8 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10.0'
|
55
|
-
description:
|
56
|
-
|
55
|
+
description: Add a `send_zip` method in your Rails controller to send a `.zip` file
|
56
|
+
containing one (or many) ActiveStorage object(s)
|
57
57
|
email:
|
58
58
|
- contact@rousseau-alexandre.fr
|
59
59
|
executables: []
|
@@ -62,6 +62,7 @@ extra_rdoc_files: []
|
|
62
62
|
files:
|
63
63
|
- ".gitignore"
|
64
64
|
- ".travis.yml"
|
65
|
+
- CHANGELOG.yml
|
65
66
|
- CODE_OF_CONDUCT.md
|
66
67
|
- Gemfile
|
67
68
|
- Gemfile.lock
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- bin/setup
|
74
75
|
- lib/active_storage/send_zip.rb
|
75
76
|
- lib/active_storage/send_zip/version.rb
|
77
|
+
- lib/active_storage/send_zip_helper.rb
|
76
78
|
homepage: https://github.com/madeindjs/active_storage-send_zip
|
77
79
|
licenses:
|
78
80
|
- MIT
|