class FilePipeline::FileOperations::FileOperation

This is an abstract class to be subclassed when file operations are implemented.

For the autoloading mechanism in FilePipeline.load to work, it is required that subclasses are in defined in the module FilePipeline::FileOperations.

The constructor (#initialze) must accept a doublesplat argument as the only argument and should call super.

Subclasses must implement an operation method or override the run method.

If the operation results in file type different than that of the file that is passed to run or operation as src_file, the subclass must have a target_extension method that returns the appropriate extension.

If the operation is non-modifying, the subclass must redefine the modifies? methods to return false.

Attributes

options[R]

A Hash; any options used when performing operation.

Public Class Methods

new(opts, defaults = {}) click to toggle source

Returns a new instance and sets options.

This can be called from subclasses.

Arguments
  • defaults - Default options for the subclass (hash).

  • opts - Options passed to the sublass initializer (hash).

# File lib/file_pipeline/file_operations/file_operation.rb, line 36
def initialize(opts, defaults = {})
  opts.transform_keys!(&:to_sym)
  @options = defaults.update(opts)
end

Public Instance Methods

captured_data_tag() click to toggle source

Returns the NO_DATA tag.

If the results returned by a subclass contain data, override this methos to return the appropriate tag for the data. This tag can be used to filter data captured by operations.

Tags are defined in CapturedDataTags.

# File lib/file_pipeline/file_operations/file_operation.rb, line 48
def captured_data_tag
  CapturedDataTags::NO_DATA
end
extension(file) click to toggle source

Returns the extension for file (a string). This should be the extension for the type the file created by operation will have.

If the operation of a subclass will result in a different extension of predictable type, define a target_extension method.

# File lib/file_pipeline/file_operations/file_operation.rb, line 57
def extension(file)
  target_extension || File.extname(file)
end
failure(log_data = nil) click to toggle source

Returns a Results object with the Results#success set to false and any information returned by the operation in log_data (a string error, array, or hash).

# File lib/file_pipeline/file_operations/file_operation.rb, line 64
def failure(log_data = nil)
  results false, log_data
end
modifies?() click to toggle source

Returns true if the FIleOperation will create a new version. Default: true.

# File lib/file_pipeline/file_operations/file_operation.rb, line 70
def modifies?
  true
end
name() click to toggle source

Returns the class name (string) of self without the names of the modules that the class is nested in.

# File lib/file_pipeline/file_operations/file_operation.rb, line 76
def name
  self.class.name.split('::').last
end
operation(src_file, out_file, original = nil) click to toggle source

To be implemented in subclasses. Should return any logged errors or data produced (a string, error, array, or hash) or nil.

Arguments
  • src_file - Path for the file the operation will use as the basis for the new version it will create.

  • out_file - Path the file created by the operation will be written to.

  • original - Path to the original, unmodified, file (optional).

# File lib/file_pipeline/file_operations/file_operation.rb, line 92
def operation(*_)
  raise 'not implemented'
end
results(success, log_data = nil) click to toggle source

Returns a new Results object with the descrip1tion of self, success, and any information returned by the operation as log_data (a string, error, array, or hash.)

Examples
error = StandardError.new
warning = 'a warning occurred'
log = [error, warning]
data = { mime_type: 'image/jpeg' }

my_op = MyOperation.new

my_op.results(false, error)
# => <Results @data=nil, @log=[error], ..., @success=false>

my_op.results(true, warning)
# => <Results @data=nil, @log=[warning], ..., @success=true>

my_op.results(true, data)
# => <Results @data=data, @log=[], ..., @success=true>

my_op.results(true, [warning, data])
# => <Results @data=data, @log=[warning], ..., @success=true>

my_op.results(false, log)
# => <Results @data=nil, @log=[error, warning], ..., @success=false>

my_op.results(false, [log, data])
# => <Results @data=data, @log=[error, warning], ..., @success=false>
# File lib/file_pipeline/file_operations/file_operation.rb, line 127
def results(success, log_data = nil)
  Results.new(self, success, log_data)
end
run(src_file, directory, original = nil) click to toggle source

Runs the operation on src_file and retunes an array with a path for the file created by the operation and a Results object.

Subclasses of FileOperation must either implement an operation method, or override the run method, making sure it has the same signature and kind of return value.

The method will create a new path for the file produced by operation to be written to. This path will consist of directory and a new basename.

The optional original argument can be used to reference another file, e.g. when exif metadata tags missing in the src_file are to be copied over from another file.

# File lib/file_pipeline/file_operations/file_operation.rb, line 144
def run(src_file, directory, original = nil)
  out_file = target directory, extension(src_file) if modifies?
  log_data = operation src_file, out_file, original
  [out_file, success(log_data)]
rescue StandardError => e
  FileUtils.rm out_file if out_file && File.exist?(out_file)
  [out_file, failure(e)]
end
success(log_data = nil) click to toggle source

Returns a Results object with the Results#success set to true and any information returned by the operation in log_data (a string error, array, or hash).

# File lib/file_pipeline/file_operations/file_operation.rb, line 156
def success(log_data = nil)
  results true, log_data
end
target(directory, extension, kind = :timestamp) click to toggle source

Returns a new path to which the file created by the operation can be written. The path will be in directory, with a new basename determined by kind and have the specified file extension.

There are two options for the kind of basename to be created:

  • :timestamp (default) - Creates a timestamp basename.

  • :random - Creates a UUID basename.

The timestamp format is YYYY-MM-DDTHH:MM:SS.NNNNNNNNN.

Examples
file_operation.target('path/to/dir', '.png', :timestamp)
# => 'path/to/dir/2019-07-24T09:30:12:638935761.png'

file_operation.target('path/to/dir', '.png', :random)
# => 'path/to/dir/123e4567-e89b-12d3-a456-426655440000.png'
# File lib/file_pipeline/file_operations/file_operation.rb, line 177
def target(directory, extension, kind = :timestamp)
  filename = FilePipeline.new_basename(kind) + extension
  File.join directory, filename
end
target_extension() click to toggle source

Returns nil.

If the operation of a subclass will result in a different extension of predictable type, override this method to return the appropriate type.

If, for instance, the operation will always create a TIFF file, the implementation could be:

# Returns '.tiff'
def target_extension
  '.tiff'
end
# File lib/file_pipeline/file_operations/file_operation.rb, line 195
def target_extension; end