Module: IOStreams
- Defined in:
- lib/io_streams/version.rb,
lib/iostreams.rb,
lib/io_streams/pgp.rb,
lib/io_streams/streams.rb,
lib/io_streams/csv/reader.rb,
lib/io_streams/csv/writer.rb,
lib/io_streams/io_streams.rb,
lib/io_streams/pgp/reader.rb,
lib/io_streams/pgp/writer.rb,
lib/io_streams/zip/reader.rb,
lib/io_streams/zip/writer.rb,
lib/io_streams/file/reader.rb,
lib/io_streams/file/writer.rb,
lib/io_streams/gzip/reader.rb,
lib/io_streams/gzip/writer.rb,
lib/io_streams/sftp/reader.rb,
lib/io_streams/sftp/writer.rb,
lib/io_streams/xlsx/reader.rb,
lib/io_streams/delimited/reader.rb,
lib/io_streams/delimited/writer.rb
Overview
:nodoc
Defined Under Namespace
Modules: CSV, Delimited, File, Gzip, Pgp, SFTP, Xlsx, Zip Classes: Extension, StreamStruct, Streams
Constant Summary collapse
- VERSION =
'0.10.0'
- UTF8_ENCODING =
Encoding.find('UTF-8').freeze
- BINARY_ENCODING =
Encoding.find('BINARY').freeze
- @@extensions =
A registry to hold formats for processing files during upload or download
Concurrent::Hash.new
Class Method Summary collapse
-
.compressed?(file_name) ⇒ Boolean
Returns [true|false] whether the file is compressed Note: Currently only looks at the file name extension.
-
.copy(source_stream, target_stream, buffer_size = 65536) ⇒ Object
Copies the source stream to the target stream Returns [Integer] the number of bytes copied.
-
.delete_stream(stream, streams) ⇒ Object
Deletes the specified stream from the supplied streams if present Returns deleted stream, or nil if not found.
-
.delimited_stream?(streams) ⇒ Boolean
Returns [true|false] whether the stream starts with a delimited reader or writer.
-
.deregister_extension(extension) ⇒ Object
De-Register a file extension.
-
.reader(file_name_or_io, streams = nil, &block) ⇒ Object
Returns a Reader for reading a file / stream.
-
.reader_stream?(file_name_or_io) ⇒ Boolean
Returns [true|false] whether the supplied file_name_or_io is a reader stream.
-
.register_extension(extension, reader_class, writer_class) ⇒ Object
Register a file extension and the reader and writer classes to use to format it.
-
.streams_for_file_name(file_name) ⇒ Object
Returns [Array] the formats required to process the file by looking at its extension(s).
-
.writer(file_name_or_io, streams = nil, &block) ⇒ Object
Returns a Writer for writing to a file / stream.
-
.writer_stream?(file_name_or_io) ⇒ Boolean
Returns [true|false] whether the supplied file_name_or_io is a reader stream.
Class Method Details
.compressed?(file_name) ⇒ Boolean
Returns [true|false] whether the file is compressed Note: Currently only looks at the file name extension
200 201 202 |
# File 'lib/io_streams/io_streams.rb', line 200 def self.compressed?(file_name) !(file_name =~ /\.(zip|gz|gzip|xls.|)\z/i).nil? end |
.copy(source_stream, target_stream, buffer_size = 65536) ⇒ Object
178 179 180 181 182 183 184 185 186 |
# File 'lib/io_streams/io_streams.rb', line 178 def self.copy(source_stream, target_stream, buffer_size=65536) bytes = 0 while data = source_stream.read(buffer_size) break if data.size == 0 bytes += data.size target_stream.write(data) end bytes end |
.delete_stream(stream, streams) ⇒ Object
Deletes the specified stream from the supplied streams if present Returns deleted stream, or nil if not found
206 207 208 209 210 211 212 213 |
# File 'lib/io_streams/io_streams.rb', line 206 def self.delete_stream(stream, streams) raise(ArgumentError, "Argument :stream must be a symbol: #{stream.inspect}") unless stream.is_a?(Symbol) Array(streams).delete_if do |_stream| stream_key = _stream.is_a?(Symbol) ? _stream : _stream.keys.first stream == stream_key end end |
.delimited_stream?(streams) ⇒ Boolean
Returns [true|false] whether the stream starts with a delimited reader or writer
216 217 218 219 220 221 222 |
# File 'lib/io_streams/io_streams.rb', line 216 def self.delimited_stream?(streams) stream = Array(streams).first return false unless stream # TODO Need to figure out a way so that this is not hard-coded [:xlsx, :xlsm, :delimited].include?(stream.is_a?(Symbol) ? stream : stream.keys.first) end |
.deregister_extension(extension) ⇒ Object
De-Register a file extension
Returns [Symbol] the extension removed, or nil if the extension was not registered
Example:
register_extension(:xls)
64 65 66 67 |
# File 'lib/io_streams/io_streams.rb', line 64 def self.deregister_extension(extension) raise(ArgumentError, "Invalid extension #{extension.inspect}") unless extension.to_s =~ /\A\w+\Z/ @@extensions.delete(extension.to_sym) end |
.reader(file_name_or_io, streams = nil, &block) ⇒ Object
Returns a Reader for reading a file / stream
Parameters
file_name_or_io [String|IO]
The file_name of the file to write to, or an IO Stream that implements
#read.
streams [Symbol|Array]
The formats/streams that be used to convert the data whilst it is
being read.
When nil, the file_name will be inspected to try and determine what
streams should be applied.
Default: nil
Stream types / extensions supported:
.zip Zip File [ :zip ]
.gz, .gzip GZip File [ :gzip ]
.enc File Encrypted using symmetric encryption [ :enc ]
other All other extensions will be returned as: [ :file ]
When a file is encrypted, it may also be compressed:
.zip.enc [ :zip, :enc ]
.gz.enc [ :gz, :enc ]
Example: Zip
IOStreams.reader('myfile.zip') do |stream|
puts stream.read
end
Example: Encrypted Zip
IOStreams.reader('myfile.zip.enc') do |stream|
puts stream.read
end
Example: Explicitly set the streams
IOStreams.reader('myfile.zip.enc', [:zip, :enc]) do |stream|
puts stream.read
end
Example: Supply custom options
# Encrypt the file and get Symmetric Encryption to also compress it
IOStreams.reader('myfile.csv.enc', [:enc]) do |stream|
puts stream.read
end
113 114 115 |
# File 'lib/io_streams/io_streams.rb', line 113 def self.reader(file_name_or_io, streams = nil, &block) stream(:reader, file_name_or_io, streams, &block) end |
.reader_stream?(file_name_or_io) ⇒ Boolean
Returns [true|false] whether the supplied file_name_or_io is a reader stream
189 190 191 |
# File 'lib/io_streams/io_streams.rb', line 189 def self.reader_stream?(file_name_or_io) file_name_or_io.respond_to?(:read) end |
.register_extension(extension, reader_class, writer_class) ⇒ Object
Register a file extension and the reader and writer classes to use to format it
Example:
# MyXls::Reader and MyXls::Writer must implement .open
register_extension(:xls, MyXls::Reader, MyXls::Writer)
53 54 55 56 |
# File 'lib/io_streams/io_streams.rb', line 53 def self.register_extension(extension, reader_class, writer_class) raise(ArgumentError, "Invalid extension #{extension.inspect}") unless extension.to_s =~ /\A\w+\Z/ @@extensions[extension.to_sym] = Extension.new(reader_class, writer_class) end |
.streams_for_file_name(file_name) ⇒ Object
Returns [Array] the formats required to process the file by looking at its extension(s)
Extensions supported:
.zip Zip File [ :zip ]
.gz, .gzip GZip File [ :gzip ]
.enc File Encrypted using symmetric encryption [ :enc ]
other All other extensions will be returned as: [ :file ]
When a file is encrypted, it may also be compressed:
.zip.enc [ :zip, :enc ]
.gz.enc [ :gz, :enc ]
Example Zip file:
RocketJob::Formatter::Formats.streams_for_file_name('myfile.zip')
=> [ :zip ]
Example Encrypted Gzip file:
RocketJob::Formatter::Formats.streams_for_file_name('myfile.csv.gz.enc')
=> [ :gz, :enc ]
Example plain text / binary file:
RocketJob::Formatter::Formats.streams_for_file_name('myfile.csv')
=> [ :file ]
33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/io_streams/io_streams.rb', line 33 def self.streams_for_file_name(file_name) raise ArgumentError.new('File name cannot be nil') if file_name.nil? raise ArgumentError.new("File name must be a string: #{file_name.inspect}, class: #{file_name.class}") unless file_name.is_a?(String) parts = file_name.split('.') extensions = [] while extension = parts.pop break unless @@extensions[extension.to_sym] extensions.unshift(extension.to_sym) end extensions << :file if extensions.size == 0 extensions end |
.writer(file_name_or_io, streams = nil, &block) ⇒ Object
Returns a Writer for writing to a file / stream
Parameters
file_name_or_io [String|IO]
The file_name of the file to write to, or an IO Stream that implements
#write.
streams [Symbol|Array]
The formats/streams that be used to convert the data whilst it is
being written.
When nil, the file_name will be inspected to try and determine what
streams should be applied.
Default: nil
Stream types / extensions supported:
.zip Zip File [ :zip ]
.gz, .gzip GZip File [ :gzip ]
.enc File Encrypted using symmetric encryption [ :enc ]
other All other extensions will be returned as: [ :file ]
When a file is encrypted, it may also be compressed:
.zip.enc [ :zip, :enc ]
.gz.enc [ :gz, :enc ]
Example: Zip
IOStreams.writer('myfile.zip') do |stream|
stream.write(data)
end
Example: Encrypted Zip
IOStreams.writer('myfile.zip.enc') do |stream|
stream.write(data)
end
Example: Explicitly set the streams
IOStreams.writer('myfile.zip.enc', [:zip, :enc]) do |stream|
stream.write(data)
end
Example: Supply custom options
IOStreams.writer('myfile.csv.enc', [enc: { compress: true }]) do |stream|
stream.write(data)
end
Example: Set internal filename when creating a zip file
IOStreams.writer('myfile.csv.zip', zip: { zip_file_name: 'myfile.csv' }) do |stream|
stream.write(data)
end
165 166 167 |
# File 'lib/io_streams/io_streams.rb', line 165 def self.writer(file_name_or_io, streams = nil, &block) stream(:writer, file_name_or_io, streams, &block) end |
.writer_stream?(file_name_or_io) ⇒ Boolean
Returns [true|false] whether the supplied file_name_or_io is a reader stream
194 195 196 |
# File 'lib/io_streams/io_streams.rb', line 194 def self.writer_stream?(file_name_or_io) file_name_or_io.respond_to?(:write) end |