Class: Zipline::ZipGenerator
- Inherits:
-
Object
- Object
- Zipline::ZipGenerator
- Defined in:
- lib/zipline/zip_generator.rb
Instance Method Summary collapse
- #each(&block) ⇒ Object
- #handle_file(streamer, file, name, options) ⇒ Object
-
#initialize(files, **kwargs_for_new) ⇒ ZipGenerator
constructor
takes an array of pairs [[uploader, filename], … ].
- #is_io?(io_ish) ⇒ Boolean
-
#normalize(file) ⇒ Object
This extracts either a url or a local file from the provided file.
-
#to_s ⇒ Object
this is supposed to be streamed!.
- #write_file(streamer, file, name, options) ⇒ Object
Constructor Details
#initialize(files, **kwargs_for_new) ⇒ ZipGenerator
takes an array of pairs [[uploader, filename], … ]
6 7 8 9 |
# File 'lib/zipline/zip_generator.rb', line 6 def initialize(files, **kwargs_for_new) @files = files @kwargs_for_new = kwargs_for_new end |
Instance Method Details
#each(&block) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/zipline/zip_generator.rb', line 16 def each(&block) fake_io_writer = ZipTricks::BlockWrite.new(&block) # ZipTricks outputs lots of strings in rapid succession, and with # servers it can be beneficial to avoid doing too many tiny writes so that # the number of syscalls is minimized. See https://github.com/WeTransfer/zip_tricks/issues/78 # There is a built-in facility for this in ZipTricks which can be used to implement # some cheap buffering here (it exists both in version 4 and version 5). The buffer is really # tiny and roughly equal to the medium Linux socket buffer size (16 KB). Although output # will be not so immediate with this buffering the overall performance will be better, # especially with multiple clients being serviced at the same time. # Note that the WriteBuffer writes the same, retained String object - but the contents # of that object changes between calls. This should work fine with servers where the # contents of the string gets written to a socket immediately before the execution inside # the WriteBuffer resumes), but if the strings get retained somewhere - like in an Array - # this might pose a problem. Unlikely that it will be an issue here though. write_buffer_size = 16 * 1024 write_buffer = ZipTricks::WriteBuffer.new(fake_io_writer, write_buffer_size) ZipTricks::Streamer.open(write_buffer, **@kwargs_for_new) do |streamer| @files.each do |file, name, = {}| handle_file(streamer, file, name.to_s, ) end end write_buffer.flush! # for any remaining writes end |
#handle_file(streamer, file, name, options) ⇒ Object
41 42 43 44 |
# File 'lib/zipline/zip_generator.rb', line 41 def handle_file(streamer, file, name, ) file = normalize(file) write_file(streamer, file, name, ) end |
#is_io?(io_ish) ⇒ Boolean
104 105 106 |
# File 'lib/zipline/zip_generator.rb', line 104 def is_io?(io_ish) io_ish.respond_to? :read end |
#normalize(file) ⇒ Object
This extracts either a url or a local file from the provided file. Currently support carrierwave and paperclip local and remote storage. returns a hash of the form aUrl or anIoObject
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/zipline/zip_generator.rb', line 49 def normalize(file) if defined?(CarrierWave::Uploader::Base) && file.is_a?(CarrierWave::Uploader::Base) file = file.file end if defined?(Paperclip) && file.is_a?(Paperclip::Attachment) if file.[:storage] == :filesystem {file: File.open(file.path)} else {url: file.expiring_url} end elsif defined?(CarrierWave::Storage::Fog::File) && file.is_a?(CarrierWave::Storage::Fog::File) {url: file.url} elsif defined?(CarrierWave::SanitizedFile) && file.is_a?(CarrierWave::SanitizedFile) {file: File.open(file.path)} elsif is_io?(file) {file: file} elsif defined?(ActiveStorage::Blob) && file.is_a?(ActiveStorage::Blob) {blob: file} elsif (file) || is_active_storage_one?(file) {blob: file.blob} elsif file.respond_to? :url {url: file.url} elsif file.respond_to? :path {file: File.open(file.path)} elsif file.respond_to? :file {file: File.open(file.file)} elsif is_url?(file) {url: file} else raise(ArgumentError, 'Bad File/Stream') end end |
#to_s ⇒ Object
this is supposed to be streamed!
12 13 14 |
# File 'lib/zipline/zip_generator.rb', line 12 def to_s throw "stop!" end |
#write_file(streamer, file, name, options) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/zipline/zip_generator.rb', line 83 def write_file(streamer, file, name, ) streamer.write_deflated_file(name, **.slice(:modification_time)) do |writer_for_file| if file[:url] the_remote_uri = URI(file[:url]) Net::HTTP.get_response(the_remote_uri) do |response| response.read_body do |chunk| writer_for_file << chunk end end elsif file[:file] IO.copy_stream(file[:file], writer_for_file) file[:file].close elsif file[:blob] file[:blob].download { |chunk| writer_for_file << chunk } else raise(ArgumentError, 'Bad File/Stream') end end end |