Skip to content

Commit

Permalink
Feature : Allow resizing of files before downloading (#22)
Browse files Browse the repository at this point in the history
* chore: Update `bundler`, `rake` and `Gemfile.lock`

Updates the gem dependencies.
Update bundler and rake.

* feat: Add resize_to_limit filter

Allow resizing of zipped files before downloading.

* fix: Fix dependency on `service_url`

According to the documentation, `service_url` shouldn't be used
directly. Replace the call to `service_url` with `url_for`.

* fix: send `url_for` isn't supported by all services

Sending the `url_for` method isn't supported by all services.

* chore: Update `CHANGELOG.yml`

Update the `CHANGELOG.yml` for version 0.3.4 with the resize feature.

* chore: Update `README.md`

Update the `README.md` with details on how to use the resize feature.

* chore: Bump version number

Increase the version number to 0.3.4.
Add my name to the authors.

* chore: Document `resize_to_limit` filter

Document the `resize_to_limit` filter that can be applied to images
before being zipped.

* feat: Add a test for `resize_to_limit`

Add a test to ensure the behavior of resize_to_limit is working.
  • Loading branch information
biximilien authored Jul 26, 2020
1 parent 84311be commit 18b7443
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 78 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
0.3.4:
- add resize before download capability
0.3.2:
- correct rubyzip dependency
0.3.1:
Expand Down
134 changes: 67 additions & 67 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8,116 +8,116 @@ PATH
GEM
remote: https://rubygems.org/
specs:
actioncable (6.0.2.1)
actionpack (= 6.0.2.1)
actioncable (6.0.3.2)
actionpack (= 6.0.3.2)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
actionmailbox (6.0.2.1)
actionpack (= 6.0.2.1)
activejob (= 6.0.2.1)
activerecord (= 6.0.2.1)
activestorage (= 6.0.2.1)
activesupport (= 6.0.2.1)
actionmailbox (6.0.3.2)
actionpack (= 6.0.3.2)
activejob (= 6.0.3.2)
activerecord (= 6.0.3.2)
activestorage (= 6.0.3.2)
activesupport (= 6.0.3.2)
mail (>= 2.7.1)
actionmailer (6.0.2.1)
actionpack (= 6.0.2.1)
actionview (= 6.0.2.1)
activejob (= 6.0.2.1)
actionmailer (6.0.3.2)
actionpack (= 6.0.3.2)
actionview (= 6.0.3.2)
activejob (= 6.0.3.2)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (6.0.2.1)
actionview (= 6.0.2.1)
activesupport (= 6.0.2.1)
actionpack (6.0.3.2)
actionview (= 6.0.3.2)
activesupport (= 6.0.3.2)
rack (~> 2.0, >= 2.0.8)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actiontext (6.0.2.1)
actionpack (= 6.0.2.1)
activerecord (= 6.0.2.1)
activestorage (= 6.0.2.1)
activesupport (= 6.0.2.1)
actiontext (6.0.3.2)
actionpack (= 6.0.3.2)
activerecord (= 6.0.3.2)
activestorage (= 6.0.3.2)
activesupport (= 6.0.3.2)
nokogiri (>= 1.8.5)
actionview (6.0.2.1)
activesupport (= 6.0.2.1)
actionview (6.0.3.2)
activesupport (= 6.0.3.2)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activejob (6.0.2.1)
activesupport (= 6.0.2.1)
activejob (6.0.3.2)
activesupport (= 6.0.3.2)
globalid (>= 0.3.6)
activemodel (6.0.2.1)
activesupport (= 6.0.2.1)
activerecord (6.0.2.1)
activemodel (= 6.0.2.1)
activesupport (= 6.0.2.1)
activestorage (6.0.2.1)
actionpack (= 6.0.2.1)
activejob (= 6.0.2.1)
activerecord (= 6.0.2.1)
activemodel (6.0.3.2)
activesupport (= 6.0.3.2)
activerecord (6.0.3.2)
activemodel (= 6.0.3.2)
activesupport (= 6.0.3.2)
activestorage (6.0.3.2)
actionpack (= 6.0.3.2)
activejob (= 6.0.3.2)
activerecord (= 6.0.3.2)
marcel (~> 0.3.1)
activesupport (6.0.2.1)
activesupport (6.0.3.2)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2)
zeitwerk (~> 2.2, >= 2.2.2)
builder (3.2.4)
concurrent-ruby (1.1.6)
crass (1.0.6)
erubi (1.9.0)
globalid (0.4.2)
activesupport (>= 4.2.0)
i18n (1.8.2)
i18n (1.8.5)
concurrent-ruby (~> 1.0)
loofah (2.4.0)
loofah (2.6.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.1)
mini_mime (>= 0.1.1)
marcel (0.3.3)
mimemagic (~> 0.3.2)
method_source (0.9.2)
mimemagic (0.3.4)
method_source (1.0.0)
mimemagic (0.3.5)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.14.0)
minitest (5.14.1)
nio4r (2.5.2)
nokogiri (1.10.8)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
rack (2.2.2)
rack (2.2.3)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (6.0.2.1)
actioncable (= 6.0.2.1)
actionmailbox (= 6.0.2.1)
actionmailer (= 6.0.2.1)
actionpack (= 6.0.2.1)
actiontext (= 6.0.2.1)
actionview (= 6.0.2.1)
activejob (= 6.0.2.1)
activemodel (= 6.0.2.1)
activerecord (= 6.0.2.1)
activestorage (= 6.0.2.1)
activesupport (= 6.0.2.1)
rails (6.0.3.2)
actioncable (= 6.0.3.2)
actionmailbox (= 6.0.3.2)
actionmailer (= 6.0.3.2)
actionpack (= 6.0.3.2)
actiontext (= 6.0.3.2)
actionview (= 6.0.3.2)
activejob (= 6.0.3.2)
activemodel (= 6.0.3.2)
activerecord (= 6.0.3.2)
activestorage (= 6.0.3.2)
activesupport (= 6.0.3.2)
bundler (>= 1.3.0)
railties (= 6.0.2.1)
railties (= 6.0.3.2)
sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.3.0)
loofah (~> 2.3)
railties (6.0.2.1)
actionpack (= 6.0.2.1)
activesupport (= 6.0.2.1)
railties (6.0.3.2)
actionpack (= 6.0.3.2)
activesupport (= 6.0.3.2)
method_source
rake (>= 0.8.7)
thor (>= 0.20.3, < 2.0)
rake (13.0.1)
rubyzip (2.2.0)
sprockets (4.0.0)
rubyzip (2.3.0)
sprockets (4.0.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.1)
Expand All @@ -126,21 +126,21 @@ GEM
sprockets (>= 3.0.0)
thor (1.0.1)
thread_safe (0.3.6)
tzinfo (1.2.6)
tzinfo (1.2.7)
thread_safe (~> 0.1)
websocket-driver (0.7.1)
websocket-driver (0.7.3)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.4)
zeitwerk (2.2.2)
websocket-extensions (0.1.5)
zeitwerk (2.4.0)

PLATFORMS
ruby

DEPENDENCIES
active_storage-send_zip!
bundler (~> 1.17)
bundler
minitest (~> 5.0)
rake (~> 13.0)
rake

BUNDLED WITH
1.17.2
2.1.4
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,34 @@ Will produce a `.zip` archive like this:
└── c.gif
~~~


### Resize images before downloading

You can resize the images before zipping and downloading them :

~~~ruby
# app/controllers/galleries_controller.rb
class GalleriesController < ApplicationController
include ActiveStorage::SendZip

# ...

# GET /galleries/1/download
def download
respond_to do |format|
if params[:format] == 'web_size'
format.zip { send_zip @gallery.photos, resize_to_limit: [1920, 1080] }
elsif params[:format] == 'tiny'
format.zip { send_zip @gallery.photos, resize_to_limit: [480, 270] }
else
format.zip { send_zip @gallery.photos }
end
end
end
end
~~~


## Installation

Add this line to your application's Gemfile:
Expand Down
6 changes: 3 additions & 3 deletions active_storage-send_zip.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require 'active_storage/send_zip/version'
Gem::Specification.new do |spec|
spec.name = 'active_storage-send_zip'
spec.version = ActiveStorage::SendZip::VERSION
spec.authors = ['Alexandre Rousseau']
spec.authors = ['Alexandre Rousseau', 'Maxime `biximilien` Gauthier']
spec.email = ['[email protected]']

spec.summary = 'Create a zip from one or more Active Storage objects'
Expand Down Expand Up @@ -37,9 +37,9 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']

spec.add_development_dependency 'bundler', '~> 1.17'
spec.add_development_dependency 'bundler'
spec.add_development_dependency 'minitest', '~> 5.0'
spec.add_development_dependency 'rake', '~> 13.0'
spec.add_development_dependency 'rake'
spec.add_dependency 'rails', '> 5.2'
spec.add_dependency 'rubyzip', '< 3.0'
end
5 changes: 3 additions & 2 deletions lib/active_storage/send_zip.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ module SendZip
#
# @param active_storages [ActiveStorage::Attached::Many] files to save
# @param filename [ActiveStorage::Attached::Many] files to save
def send_zip(active_storages, filename: 'my.zip')
# @param resize_to_limit [Array] resize to limit filter in ImageProcessing format [width, height]
def send_zip(active_storages, filename: 'my.zip', resize_to_limit: nil)
require 'zip'
files = SendZipHelper.save_files_on_server active_storages
files = SendZipHelper.save_files_on_server active_storages, resize_to_limit: resize_to_limit
zip_data = SendZipHelper.create_temporary_zip_file files

send_data(zip_data, type: 'application/zip', filename: filename)
Expand Down
2 changes: 1 addition & 1 deletion lib/active_storage/send_zip/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
module ActiveStorage
module SendZip
# The version of this gem
VERSION = '0.3.3'
VERSION = '0.3.4'
end
end
17 changes: 13 additions & 4 deletions lib/active_storage/send_zip_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ module SendZipHelper
# Download active storage files on server in a temporary folder
#
# @param files [ActiveStorage::Attached::One|ActiveStorage::Attached::Many|Array|Hash] file(s) to save
# @param resize_to_limit [Array] resize to limit filter in ImageProcessing format [width, height]
# @return [String] folder path of saved files
def self.save_files_on_server(files)
def self.save_files_on_server(files, resize_to_limit: nil)
require 'zip'
# get a temporary folder and create it
temp_folder = Dir.mktmpdir 'active_storage-send_zip'

if files.is_a? Hash
filepaths = construct_with_hash(files, temp_folder)
elsif files.respond_to? :each
files.each { |file| save_file_on_server(file, temp_folder) }
files.each { |file| save_file_on_server(file, temp_folder, resize_to_limit: resize_to_limit) }
else
raise ArgumentError, '`files` must be an hash or an iterable object'
end
Expand Down Expand Up @@ -61,8 +62,9 @@ def self.construct_with_hash(files, temp_folder)
#
# @param file [ActiveStorage::Attached] files to save
# @param folder [String] where to store the file
# @param resize_to_limit [Array] resize to limit filter in ImageProcessing format [width, height]
# @return [String] the filepath of file created
def self.save_file_on_server(file, folder, subfolder: nil)
def self.save_file_on_server(file, folder, subfolder: nil, resize_to_limit: nil)
filename = file.filename.to_s

folder = File.join(folder, subfolder) unless subfolder.nil?
Expand All @@ -81,7 +83,14 @@ def self.save_file_on_server(file, folder, subfolder: nil)
filepath = File.join folder, filename
end

File.open(filepath, 'wb') { |f| f.write(file.download) }
# resize images if needed
unless resize_to_limit.nil?
file = file.variant(resize_to_limit: resize_to_limit).processed
end

# write the file on disk
File.open(filepath, 'wb') { |f| f.write(file.service.download(file.key)) }

filepath
end

Expand Down
Loading

0 comments on commit 18b7443

Please sign in to comment.