class Libis::Format::Tool::Fido

Attributes

formats[RW]

Public Class Methods

add_formats(formats_file) click to toggle source
# File lib/libis/format/tool/fido.rb, line 15
def self.add_formats(formats_file)
  self.instance.formats << formats_file unless self.instance.formats.include?(formats_file)
end
del_formats(formats_file) click to toggle source
# File lib/libis/format/tool/fido.rb, line 19
def self.del_formats(formats_file)
  self.instance.formats.delete(formats_file)
end
new() click to toggle source
# File lib/libis/format/tool/fido.rb, line 47
def initialize
  super
  @formats = Libis::Format::Config[:fido_formats].dup
  bad_mimetype('application/vnd.oasis.opendocument.text')
  bad_mimetype('application/vnd.oasis.opendocument.spreadsheet')
end

Public Instance Methods

run(file, options = {}) click to toggle source
# File lib/libis/format/tool/fido.rb, line 40
def run(file, options = {})
  output = runner(file, options)
  process_output(output)
end
run_dir(dir, recursive = true, options = {}) click to toggle source
# File lib/libis/format/tool/fido.rb, line 32
def run_dir(dir, recursive = true, options = {})
  args = []
  args << '-recurse' if recursive
  args << options
  output = runner(dir, *args)
  process_output(output)
end
run_list(filelist, options = {}) click to toggle source
# File lib/libis/format/tool/fido.rb, line 25
def run_list(filelist, options = {})
  create_list_file(filelist) do |list_file|
    output = runner(nil, '-input', list_file.escape_for_string, options)
    process_output(output)
  end
end

Protected Instance Methods

runner(filename, *args) click to toggle source
# File lib/libis/format/tool/fido.rb, line 56
def runner(filename, *args)
  options = {}
  options = args.pop if args.last.is_a?(Hash)
  # Load custome format definitions if present
  args << '-loadformats' << "#{formats.join(',')}" unless formats.empty?

  # Workaround for Fido performance bug
  args << '-bufsize' << (options[:bufsize] || 1000).to_s

  # Other options
  args << '-container_bufsize' << options[:container_bufsize].to_s if options[:container_bufsize]
  args << '-pronom_only' if options[:pronom_only]
  args << '-nocontainer' if options[:nocontainer]

  # Add filename to argument list (optional)
  args << "#{filename.escape_for_string}" if filename

  # No header output
  args << '-q'

  # Run command and capture results
  timeout = Libis::Format::Config[:timeouts][:fido]
  result = ::Libis::Tools::Command.run(
      Libis::Format::Config[:fido_cmd], *args,
      timeout: timeout,
      kill_after: timeout * 2
  )

  # Log warning if needed
  raise RuntimeError, "#{self.class} took too long (> #{timeout} seconds) to complete" if result[:timeout]
  raise RuntimeError, "#{self.class} errors: #{result[:err].join("\n")}" unless result[:status] == 0 && result[:err].empty?

  # Parse output (CSV) text into array and return result
  keys = [:status, :time, :puid, :format_name, :format_version, :filesize, :filepath, :mimetype, :matchtype]
  data = CSV.parse(result[:out].join("\n"))
               .map {|a| Hash[keys.zip(a)]}
               .select {|a| a[:status] == 'OK'}
  data.each do |r|
    r.delete(:time)
    r.delete(:status)
    r.delete(:filesize)
    r[:tool] = :fido
  end
end