libis-format 1.2.9 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/Gemfile +2 -0
 - data/data/types.yml +1 -1
 - data/lib/libis/format/command_line.rb +2 -3
 - data/lib/libis/format/config.rb +18 -19
 - data/lib/libis/format/converter/base.rb +9 -16
 - data/lib/libis/format/converter/chain.rb +36 -28
 - data/lib/libis/format/converter/email_converter.rb +5 -8
 - data/lib/libis/format/converter/fop_pdf_converter.rb +4 -6
 - data/lib/libis/format/converter/image_converter.rb +51 -58
 - data/lib/libis/format/converter/jp2_converter.rb +33 -35
 - data/lib/libis/format/converter/office_converter.rb +19 -23
 - data/lib/libis/format/converter/pdf_converter.rb +22 -28
 - data/lib/libis/format/converter/repository.rb +7 -13
 - data/lib/libis/format/converter/spreadsheet_converter.rb +7 -11
 - data/lib/libis/format/converter/video_converter.rb +41 -55
 - data/lib/libis/format/converter/xslt_converter.rb +14 -13
 - data/lib/libis/format/converter.rb +1 -1
 - data/lib/libis/format/identifier.rb +41 -43
 - data/lib/libis/format/tool/droid.rb +29 -30
 - data/lib/libis/format/tool/ff_mpeg.rb +11 -13
 - data/lib/libis/format/tool/fido.rb +1 -1
 - data/lib/libis/format/tool/pdf_copy.rb +17 -18
 - data/lib/libis/format/tool/pdf_merge.rb +17 -17
 - data/lib/libis/format/tool/pdf_optimizer.rb +18 -20
 - data/lib/libis/format/tool/spreadsheet_to_ods.rb +23 -20
 - data/lib/libis/format/tool.rb +2 -2
 - data/lib/libis/format/type_database.rb +51 -28
 - data/lib/libis/format/type_database_impl.rb +57 -24
 - data/lib/libis/format/version.rb +1 -1
 - data/lib/libis/format.rb +3 -2
 - data/lib/libis-format.rb +2 -0
 - metadata +3 -3
 
| 
         @@ -1,4 +1,6 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'base'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            module Libis
         
     | 
| 
       4 
6 
     | 
    
         
             
              module Format
         
     | 
| 
         @@ -9,10 +11,9 @@ module Libis 
     | 
|
| 
       9 
11 
     | 
    
         
             
                    end
         
     | 
| 
       10 
12 
     | 
    
         | 
| 
       11 
13 
     | 
    
         
             
                    def self.output_types(format = nil)
         
     | 
| 
       12 
     | 
    
         
            -
                      if format
         
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
                       
     | 
| 
       15 
     | 
    
         
            -
                      [:XML, :HTML, :TXT]
         
     | 
| 
      
 14 
     | 
    
         
            +
                      return [] if format && !input_types.include?(format)
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                      %i[XML HTML TXT]
         
     | 
| 
       16 
17 
     | 
    
         
             
                    end
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
19 
     | 
    
         
             
                    def xsl_file(file_path)
         
     | 
| 
         @@ -28,20 +29,20 @@ module Libis 
     | 
|
| 
       28 
29 
     | 
    
         
             
                      end
         
     | 
| 
       29 
30 
     | 
    
         | 
| 
       30 
31 
     | 
    
         
             
                      unless @options[:xsl_file]
         
     | 
| 
       31 
     | 
    
         
            -
                        error  
     | 
| 
      
 32 
     | 
    
         
            +
                        error 'No xsl_file supplied'
         
     | 
| 
       32 
33 
     | 
    
         
             
                        return nil
         
     | 
| 
       33 
34 
     | 
    
         
             
                      end
         
     | 
| 
       34 
35 
     | 
    
         | 
| 
       35 
36 
     | 
    
         
             
                      FileUtils.mkpath(File.dirname(target))
         
     | 
| 
       36 
37 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
                      if RUBY_PLATFORM ==  
     | 
| 
       38 
     | 
    
         
            -
                        require  
     | 
| 
      
 38 
     | 
    
         
            +
                      if RUBY_PLATFORM == 'java'
         
     | 
| 
      
 39 
     | 
    
         
            +
                        require 'saxon-xslt'
         
     | 
| 
       39 
40 
     | 
    
         
             
                        xsl = Saxon.XSLT(File.open(@options[:xsl_file]))
         
     | 
| 
       40 
41 
     | 
    
         
             
                        xml = Saxon.XML(File.open(source))
         
     | 
| 
       41 
42 
     | 
    
         
             
                        result = xsl.transform(xml)
         
     | 
| 
       42 
43 
     | 
    
         
             
                        File.write(target, result.to_s)
         
     | 
| 
       43 
44 
     | 
    
         
             
                      else
         
     | 
| 
       44 
     | 
    
         
            -
                        require  
     | 
| 
      
 45 
     | 
    
         
            +
                        require 'nokogiri'
         
     | 
| 
       45 
46 
     | 
    
         | 
| 
       46 
47 
     | 
    
         
             
                        doc = nil
         
     | 
| 
       47 
48 
     | 
    
         
             
                        begin
         
     | 
| 
         @@ -65,7 +66,7 @@ module Libis 
     | 
|
| 
       65 
66 
     | 
    
         
             
                        xsl = nil
         
     | 
| 
       66 
67 
     | 
    
         | 
| 
       67 
68 
     | 
    
         
             
                        begin
         
     | 
| 
       68 
     | 
    
         
            -
                          fp = File.open(file,  
     | 
| 
      
 69 
     | 
    
         
            +
                          fp = File.open(file, 'r')
         
     | 
| 
       69 
70 
     | 
    
         
             
                          xsl = Nokogiri::XSLT(fp) do |config|
         
     | 
| 
       70 
71 
     | 
    
         
             
                            config.options = Nokogiri::XML::ParseOptions::STRICT | Nokogiri::XML::ParseOptions::NOBLANKS
         
     | 
| 
       71 
72 
     | 
    
         
             
                          end
         
     | 
| 
         @@ -80,17 +81,17 @@ module Libis 
     | 
|
| 
       80 
81 
     | 
    
         | 
| 
       81 
82 
     | 
    
         
             
                        begin
         
     | 
| 
       82 
83 
     | 
    
         
             
                          target_xml = xsl.transform(doc)
         
     | 
| 
       83 
     | 
    
         
            -
                          fp = File.open(target,  
     | 
| 
      
 84 
     | 
    
         
            +
                          fp = File.open(target, 'w')
         
     | 
| 
       84 
85 
     | 
    
         
             
                          fp.write(target_xml)
         
     | 
| 
       85 
86 
     | 
    
         
             
                        rescue Exception => e
         
     | 
| 
       86 
87 
     | 
    
         
             
                          error "Error transforming '#{source}' with '#{file}': #{e.message} @ #{e.backtrace[0]}"
         
     | 
| 
       87 
88 
     | 
    
         
             
                          return nil
         
     | 
| 
       88 
89 
     | 
    
         
             
                        ensure
         
     | 
| 
       89 
     | 
    
         
            -
                          fp.close unless fp.nil?  
     | 
| 
      
 90 
     | 
    
         
            +
                          fp.close unless fp.nil? || fp.closed?
         
     | 
| 
       90 
91 
     | 
    
         
             
                        end
         
     | 
| 
       91 
92 
     | 
    
         | 
| 
       92 
93 
     | 
    
         
             
                        {
         
     | 
| 
       93 
     | 
    
         
            -
                          command: {status: 0},
         
     | 
| 
      
 94 
     | 
    
         
            +
                          command: { status: 0 },
         
     | 
| 
       94 
95 
     | 
    
         
             
                          files: [target]
         
     | 
| 
       95 
96 
     | 
    
         
             
                        }
         
     | 
| 
       96 
97 
     | 
    
         | 
| 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #  
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            require 'singleton'
         
     | 
| 
       4 
4 
     | 
    
         
             
            require 'pathname'
         
     | 
| 
         @@ -7,7 +7,6 @@ require 'libis-tools' 
     | 
|
| 
       7 
7 
     | 
    
         
             
            require 'libis/tools/extend/hash'
         
     | 
| 
       8 
8 
     | 
    
         
             
            require 'libis/tools/extend/string'
         
     | 
| 
       9 
9 
     | 
    
         
             
            require 'libis/tools/extend/empty'
         
     | 
| 
       10 
     | 
    
         
            -
            require 'nori/core_ext/object'
         
     | 
| 
       11 
10 
     | 
    
         | 
| 
       12 
11 
     | 
    
         
             
            require 'libis/format/type_database'
         
     | 
| 
       13 
12 
     | 
    
         | 
| 
         @@ -19,13 +18,10 @@ require_relative 'tool/extension_identification' 
     | 
|
| 
       19 
18 
     | 
    
         | 
| 
       20 
19 
     | 
    
         
             
            module Libis
         
     | 
| 
       21 
20 
     | 
    
         
             
              module Format
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
21 
     | 
    
         
             
                class Identifier
         
     | 
| 
       24 
22 
     | 
    
         
             
                  include ::Libis::Tools::Logger
         
     | 
| 
       25 
23 
     | 
    
         
             
                  include Singleton
         
     | 
| 
       26 
24 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
                  public
         
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
25 
     | 
    
         
             
                  def self.add_xml_validation(mimetype, xsd_file)
         
     | 
| 
       30 
26 
     | 
    
         
             
                    instance.xml_validations[mimetype] = xsd_file
         
     | 
| 
       31 
27 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -41,29 +37,28 @@ module Libis 
     | 
|
| 
       41 
37 
     | 
    
         
             
                  attr_reader :xml_validations
         
     | 
| 
       42 
38 
     | 
    
         | 
| 
       43 
39 
     | 
    
         
             
                  def get(file, options = {})
         
     | 
| 
       44 
     | 
    
         
            -
             
     | 
| 
       45 
     | 
    
         
            -
                    options[: 
     | 
| 
       46 
     | 
    
         
            -
                    options[: 
     | 
| 
       47 
     | 
    
         
            -
                    options[:file] = true unless options.keys.include?(:file) or (options[:tool] and options[:tool] != :file)
         
     | 
| 
      
 40 
     | 
    
         
            +
                    options[:droid] = true unless options.keys.include?(:droid) || (options[:tool] && (options[:tool] != :droid))
         
     | 
| 
      
 41 
     | 
    
         
            +
                    options[:fido] = true unless options.keys.include?(:fido) || (options[:tool] && (options[:tool] != :fido))
         
     | 
| 
      
 42 
     | 
    
         
            +
                    options[:file] = true unless options.keys.include?(:file) || (options[:tool] && (options[:tool] != :file))
         
     | 
| 
       48 
43 
     | 
    
         
             
                    options[:xml_validation] = true if options[:xml_validation].nil?
         
     | 
| 
       49 
44 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
                    result = {messages: [], output: {}, formats: {}}
         
     | 
| 
      
 45 
     | 
    
         
            +
                    result = { messages: [], output: {}, formats: {} }
         
     | 
| 
       51 
46 
     | 
    
         | 
| 
       52 
47 
     | 
    
         
             
                    begin
         
     | 
| 
       53 
48 
     | 
    
         
             
                      get_droid_identification(file, result, options) if options[:droid]
         
     | 
| 
       54 
     | 
    
         
            -
                    rescue => e
         
     | 
| 
      
 49 
     | 
    
         
            +
                    rescue StandardError => e
         
     | 
| 
       55 
50 
     | 
    
         
             
                      log_msg(result, :error, "Error running Droid: #{e.message} @ #{e.backtrace.first}")
         
     | 
| 
       56 
51 
     | 
    
         
             
                    end
         
     | 
| 
       57 
52 
     | 
    
         | 
| 
       58 
53 
     | 
    
         
             
                    begin
         
     | 
| 
       59 
54 
     | 
    
         
             
                      get_fido_identification(file, result, options) if options[:fido]
         
     | 
| 
       60 
     | 
    
         
            -
                    rescue => e
         
     | 
| 
      
 55 
     | 
    
         
            +
                    rescue StandardError => e
         
     | 
| 
       61 
56 
     | 
    
         
             
                      log_msg(result, :error, "Error running Fido: #{e.message} @ #{e.backtrace.first}")
         
     | 
| 
       62 
57 
     | 
    
         
             
                    end
         
     | 
| 
       63 
58 
     | 
    
         | 
| 
       64 
59 
     | 
    
         
             
                    begin
         
     | 
| 
       65 
60 
     | 
    
         
             
                      get_file_identification(file, result, options) if options[:file]
         
     | 
| 
       66 
     | 
    
         
            -
                    rescue => e
         
     | 
| 
      
 61 
     | 
    
         
            +
                    rescue StandardError => e
         
     | 
| 
       67 
62 
     | 
    
         
             
                      log_msg(result, :error, "Error running File: #{e.message} @ #{e.backtrace.first}")
         
     | 
| 
       68 
63 
     | 
    
         
             
                    end
         
     | 
| 
       69 
64 
     | 
    
         | 
| 
         @@ -74,14 +69,13 @@ module Libis 
     | 
|
| 
       74 
69 
     | 
    
         
             
                    # Libis::Tools::Format::Identifier.add_xml_validation('my_type', '/path/to/my_type.xsd')
         
     | 
| 
       75 
70 
     | 
    
         
             
                    begin
         
     | 
| 
       76 
71 
     | 
    
         
             
                      validate_against_xml_schema(result, options[:base_dir]) if options[:xml_validation]
         
     | 
| 
       77 
     | 
    
         
            -
                    rescue => e
         
     | 
| 
      
 72 
     | 
    
         
            +
                    rescue StandardError => e
         
     | 
| 
       78 
73 
     | 
    
         
             
                      log_msg(result, :error, "Error validating XML files: #{e.message} @ #{e.backtrace.first}")
         
     | 
| 
       79 
74 
     | 
    
         
             
                    end
         
     | 
| 
       80 
75 
     | 
    
         | 
| 
       81 
76 
     | 
    
         
             
                    process_results(result, !options[:keep_output])
         
     | 
| 
       82 
77 
     | 
    
         | 
| 
       83 
78 
     | 
    
         
             
                    result
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
79 
     | 
    
         
             
                  end
         
     | 
| 
       86 
80 
     | 
    
         | 
| 
       87 
81 
     | 
    
         
             
                  protected
         
     | 
| 
         @@ -123,18 +117,21 @@ module Libis 
     | 
|
| 
       123 
117 
     | 
    
         
             
                  end
         
     | 
| 
       124 
118 
     | 
    
         | 
| 
       125 
119 
     | 
    
         
             
                  def xml_validate(file, file_result, result, base_dir)
         
     | 
| 
       126 
     | 
    
         
            -
                    return unless file_result[:mimetype] =~  
     | 
| 
      
 120 
     | 
    
         
            +
                    return unless file_result[:mimetype] =~ %r{^(text|application)/xml$}
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
       127 
122 
     | 
    
         
             
                    filepath = base_dir ? File.join(base_dir, file) : file
         
     | 
| 
       128 
123 
     | 
    
         
             
                    doc = ::Libis::Tools::XmlDocument.open filepath
         
     | 
| 
       129 
124 
     | 
    
         
             
                    xml_validations.each do |mime, xsd_file|
         
     | 
| 
       130 
125 
     | 
    
         
             
                      next unless xsd_file
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
       131 
127 
     | 
    
         
             
                      begin
         
     | 
| 
       132 
128 
     | 
    
         
             
                        if doc.validates_against?(xsd_file)
         
     | 
| 
       133 
129 
     | 
    
         
             
                          log_msg result, :debug, "XML file validated against XML Schema: #{xsd_file}"
         
     | 
| 
       134 
     | 
    
         
            -
                          info = {mimetype: mime, tool_raw: file_result[:tool], tool: :xsd_validation, match_type: 'xsd_validation', 
     | 
| 
      
 130 
     | 
    
         
            +
                          info = { mimetype: mime, tool_raw: file_result[:tool], tool: :xsd_validation, match_type: 'xsd_validation',
         
     | 
| 
      
 131 
     | 
    
         
            +
                                   format_version: '' }
         
     | 
| 
       135 
132 
     | 
    
         
             
                          file_result.merge! Libis::Format::TypeDatabase.enrich(info, PUID: :puid, MIME: :mimetype, NAME: :format_name)
         
     | 
| 
       136 
133 
     | 
    
         
             
                        end
         
     | 
| 
       137 
     | 
    
         
            -
                      rescue => e
         
     | 
| 
      
 134 
     | 
    
         
            +
                      rescue StandardError => e
         
     | 
| 
       138 
135 
     | 
    
         
             
                        # Do nothing - probably Nokogiri chrashed during validation. Could have many causes
         
     | 
| 
       139 
136 
     | 
    
         
             
                        # (remote schema (firewall, network, link rot, ...), schema syntax error, corrupt XML,...)
         
     | 
| 
       140 
137 
     | 
    
         
             
                        # so we log and continue.
         
     | 
| 
         @@ -142,7 +139,7 @@ module Libis 
     | 
|
| 
       142 
139 
     | 
    
         
             
                                "Error during XML validation of file #{file} against #{File.basename(xsd_file)}: #{e.message}")
         
     | 
| 
       143 
140 
     | 
    
         
             
                      end
         
     | 
| 
       144 
141 
     | 
    
         
             
                    end
         
     | 
| 
       145 
     | 
    
         
            -
                  rescue => e
         
     | 
| 
      
 142 
     | 
    
         
            +
                  rescue StandardError => e
         
     | 
| 
       146 
143 
     | 
    
         
             
                    # Not much we can do. probably Nokogiri chrashed opening the XML file. What caused this?
         
     | 
| 
       147 
144 
     | 
    
         
             
                    # (XML not parsable, false XML identification, ???)
         
     | 
| 
       148 
145 
     | 
    
         
             
                    # so we log and continue.
         
     | 
| 
         @@ -150,30 +147,30 @@ module Libis 
     | 
|
| 
       150 
147 
     | 
    
         
             
                  end
         
     | 
| 
       151 
148 
     | 
    
         | 
| 
       152 
149 
     | 
    
         
             
                  def process_results(result, delete_output = true)
         
     | 
| 
       153 
     | 
    
         
            -
                    result[:output]. 
     | 
| 
      
 150 
     | 
    
         
            +
                    result[:output].each_key do |file|
         
     | 
| 
       154 
151 
     | 
    
         
             
                      output = result[:output][file]
         
     | 
| 
       155 
152 
     | 
    
         
             
                      file_result = result[:formats][file] = {}
         
     | 
| 
       156 
153 
     | 
    
         
             
                      if output.empty?
         
     | 
| 
       157 
154 
     | 
    
         
             
                        log_msg(result, :warn, "Could not identify format of '#{file}'.")
         
     | 
| 
       158 
     | 
    
         
            -
                        file_result 
     | 
| 
       159 
     | 
    
         
            -
             
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
       163 
     | 
    
         
            -
                         
     | 
| 
      
 155 
     | 
    
         
            +
                        file_result.merge!(
         
     | 
| 
      
 156 
     | 
    
         
            +
                          mimetype: 'application/octet-stream',
         
     | 
| 
      
 157 
     | 
    
         
            +
                          puid: 'fmt/unknown',
         
     | 
| 
      
 158 
     | 
    
         
            +
                          score: 0,
         
     | 
| 
      
 159 
     | 
    
         
            +
                          tool: nil
         
     | 
| 
      
 160 
     | 
    
         
            +
                        )
         
     | 
| 
       164 
161 
     | 
    
         
             
                      else
         
     | 
| 
       165 
     | 
    
         
            -
                        format_matches = output.group_by {|x| [x[:mimetype], x[:puid]]}
         
     | 
| 
      
 162 
     | 
    
         
            +
                        format_matches = output.group_by { |x| [x[:mimetype], x[:puid]] }
         
     | 
| 
       166 
163 
     | 
    
         
             
                        format_matches.each do |match, group|
         
     | 
| 
       167 
     | 
    
         
            -
                          format_matches[match] = group.group_by {|x| x[:score]}.sort.reverse.to_h
         
     | 
| 
      
 164 
     | 
    
         
            +
                          format_matches[match] = group.group_by { |x| x[:score] }.sort.reverse.to_h
         
     | 
| 
       168 
165 
     | 
    
         
             
                        end
         
     | 
| 
       169 
166 
     | 
    
         
             
                        case format_matches.count
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
       171 
     | 
    
         
            -
             
     | 
| 
       172 
     | 
    
         
            -
             
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
             
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
      
 167 
     | 
    
         
            +
                        when 0
         
     | 
| 
      
 168 
     | 
    
         
            +
                          # No this really cannot happen. If there are no hits, there will be at least a format [nil,nil]
         
     | 
| 
      
 169 
     | 
    
         
            +
                        when 1
         
     | 
| 
      
 170 
     | 
    
         
            +
                          # only one match, that's easy. The first of the highest score will be used
         
     | 
| 
      
 171 
     | 
    
         
            +
                          file_result.merge!(get_best_result(output))
         
     | 
| 
      
 172 
     | 
    
         
            +
                        else
         
     | 
| 
      
 173 
     | 
    
         
            +
                          process_multiple_formats(file_result, format_matches, output)
         
     | 
| 
       177 
174 
     | 
    
         
             
                        end
         
     | 
| 
       178 
175 
     | 
    
         
             
                      end
         
     | 
| 
       179 
176 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -184,12 +181,13 @@ module Libis 
     | 
|
| 
       184 
181 
     | 
    
         
             
                    # multiple matches. Let's select the highest score matches
         
     | 
| 
       185 
182 
     | 
    
         
             
                    file_result.merge!(get_best_result(output))
         
     | 
| 
       186 
183 
     | 
    
         
             
                    file_result[:alternatives] = []
         
     | 
| 
       187 
     | 
    
         
            -
                    format_matches. 
     | 
| 
      
 184 
     | 
    
         
            +
                    format_matches.each_key do |mime, puid|
         
     | 
| 
       188 
185 
     | 
    
         
             
                      next if file_result[:mimetype] == mime && puid.nil?
         
     | 
| 
       189 
     | 
    
         
            -
             
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
                      selection = output.select { |x| x[:mimetype] == mime && x[:puid] == puid }
         
     | 
| 
       190 
188 
     | 
    
         
             
                      file_result[:alternatives] << get_best_result(selection)
         
     | 
| 
       191 
189 
     | 
    
         
             
                    end
         
     | 
| 
       192 
     | 
    
         
            -
                    file_result[:alternatives] = file_result[:alternatives].sort_by {|x| x[:score]}.reverse
         
     | 
| 
      
 190 
     | 
    
         
            +
                    file_result[:alternatives] = file_result[:alternatives].sort_by { |x| x[:score] }.reverse
         
     | 
| 
       193 
191 
     | 
    
         
             
                    file_result.delete(:alternatives) if file_result[:alternatives].size <= 1
         
     | 
| 
       194 
192 
     | 
    
         
             
                  end
         
     | 
| 
       195 
193 
     | 
    
         | 
| 
         @@ -208,15 +206,15 @@ module Libis 
     | 
|
| 
       208 
206 
     | 
    
         
             
                  end
         
     | 
| 
       209 
207 
     | 
    
         | 
| 
       210 
208 
     | 
    
         
             
                  def get_mimetype(puid)
         
     | 
| 
       211 
     | 
    
         
            -
                    ::Libis::Format::TypeDatabase.puid_typeinfo(puid)[:MIME].first 
     | 
| 
      
 209 
     | 
    
         
            +
                    ::Libis::Format::TypeDatabase.puid_typeinfo(puid)[:MIME].first
         
     | 
| 
      
 210 
     | 
    
         
            +
                  rescue StandardError
         
     | 
| 
      
 211 
     | 
    
         
            +
                    nil
         
     | 
| 
       212 
212 
     | 
    
         
             
                  end
         
     | 
| 
       213 
213 
     | 
    
         | 
| 
       214 
214 
     | 
    
         
             
                  def get_best_result(results)
         
     | 
| 
       215 
     | 
    
         
            -
                    score = results.map {|x| x[:score]}.max
         
     | 
| 
       216 
     | 
    
         
            -
                    results.select {|x| x[:score] == score}.reduce(:apply_defaults)
         
     | 
| 
      
 215 
     | 
    
         
            +
                    score = results.map { |x| x[:score] }.max
         
     | 
| 
      
 216 
     | 
    
         
            +
                    results.select { |x| x[:score] == score }.reduce(:apply_defaults)
         
     | 
| 
       217 
217 
     | 
    
         
             
                  end
         
     | 
| 
       218 
     | 
    
         
            -
             
     | 
| 
       219 
218 
     | 
    
         
             
                end
         
     | 
| 
       220 
     | 
    
         
            -
             
     | 
| 
       221 
219 
     | 
    
         
             
              end
         
     | 
| 
       222 
220 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'singleton'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            require 'tempfile'
         
     | 
| 
         @@ -5,10 +7,10 @@ require 'csv' 
     | 
|
| 
       5 
7 
     | 
    
         | 
| 
       6 
8 
     | 
    
         
             
            require 'libis/format/config'
         
     | 
| 
       7 
9 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
            unless CSV::HeaderConverters. 
     | 
| 
       9 
     | 
    
         
            -
              CSV::HeaderConverters[:droid_headers] = lambda {|h|
         
     | 
| 
       10 
     | 
    
         
            -
                h.encode(ConverterEncoding).downcase.strip 
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 10 
     | 
    
         
            +
            unless CSV::HeaderConverters.key?(:droid_headers)
         
     | 
| 
      
 11 
     | 
    
         
            +
              CSV::HeaderConverters[:droid_headers] = lambda { |h|
         
     | 
| 
      
 12 
     | 
    
         
            +
                h.encode(ConverterEncoding).downcase.strip
         
     | 
| 
      
 13 
     | 
    
         
            +
                 .gsub(/\W+/, '').to_sym
         
     | 
| 
       12 
14 
     | 
    
         
             
              }
         
     | 
| 
       13 
15 
     | 
    
         
             
            end
         
     | 
| 
       14 
16 
     | 
    
         | 
| 
         @@ -17,9 +19,7 @@ require_relative 'identification_tool' 
     | 
|
| 
       17 
19 
     | 
    
         
             
            module Libis
         
     | 
| 
       18 
20 
     | 
    
         
             
              module Format
         
     | 
| 
       19 
21 
     | 
    
         
             
                module Tool
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
22 
     | 
    
         
             
                  class Droid < Libis::Format::Tool::IdentificationTool
         
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
23 
     | 
    
         
             
                    def run_list(filelist, _options = {})
         
     | 
| 
       24 
24 
     | 
    
         
             
                      runner(filelist)
         
     | 
| 
       25 
25 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -43,12 +43,13 @@ module Libis 
     | 
|
| 
       43 
43 
     | 
    
         
             
                    end
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
       45 
45 
     | 
    
         
             
                    def parse_report(report)
         
     | 
| 
       46 
     | 
    
         
            -
                      keys = [
         
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 46 
     | 
    
         
            +
                      keys = %i[
         
     | 
| 
      
 47 
     | 
    
         
            +
                        id parent_id uri filepath filename matchtype status filesize type extension
         
     | 
| 
      
 48 
     | 
    
         
            +
                        mod_time ext_mismatch hash format_count puid mimetype format_name format_version
         
     | 
| 
      
 49 
     | 
    
         
            +
                      ]
         
     | 
| 
       49 
50 
     | 
    
         
             
                      result = CSV.parse(File.readlines(report).join)
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
      
 51 
     | 
    
         
            +
                                  .map { |a| Hash[keys.zip(a)] }
         
     | 
| 
      
 52 
     | 
    
         
            +
                                  .select { |a| a[:type] == 'File' }
         
     | 
| 
       52 
53 
     | 
    
         
             
                      # File.delete report
         
     | 
| 
       53 
54 
     | 
    
         
             
                      result.each do |r|
         
     | 
| 
       54 
55 
     | 
    
         
             
                        r.delete(:id)
         
     | 
| 
         @@ -70,39 +71,39 @@ module Libis 
     | 
|
| 
       70 
71 
     | 
    
         | 
| 
       71 
72 
     | 
    
         
             
                    def create_report(profile, report)
         
     | 
| 
       72 
73 
     | 
    
         
             
                      args = [
         
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
      
 74 
     | 
    
         
            +
                        '-e', report,
         
     | 
| 
      
 75 
     | 
    
         
            +
                        '-p', profile,
         
     | 
| 
      
 76 
     | 
    
         
            +
                        '-q'
         
     | 
| 
       76 
77 
     | 
    
         
             
                      ]
         
     | 
| 
       77 
78 
     | 
    
         
             
                      timeout = Libis::Format::Config[:timeouts][:droid]
         
     | 
| 
       78 
79 
     | 
    
         
             
                      result = Libis::Tools::Command.run(
         
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
      
 80 
     | 
    
         
            +
                        Libis::Format::Config[:droid_cmd], *args,
         
     | 
| 
      
 81 
     | 
    
         
            +
                        timeout:,
         
     | 
| 
      
 82 
     | 
    
         
            +
                        kill_after: timeout * 2
         
     | 
| 
       82 
83 
     | 
    
         
             
                      )
         
     | 
| 
       83 
     | 
    
         
            -
                      result[:err].select! {|x| x =~ /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} ERROR /}
         
     | 
| 
       84 
     | 
    
         
            -
                      raise  
     | 
| 
       85 
     | 
    
         
            -
                      raise  
     | 
| 
      
 84 
     | 
    
         
            +
                      result[:err].select! { |x| x =~ /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} ERROR / }
         
     | 
| 
      
 85 
     | 
    
         
            +
                      raise "#{self.class} report took too long (> #{timeout} seconds) to complete" if result[:timeout]
         
     | 
| 
      
 86 
     | 
    
         
            +
                      raise "#{self.class} report errors: #{result[:err].join("\n")}" unless result[:err].empty?
         
     | 
| 
       86 
87 
     | 
    
         | 
| 
       87 
88 
     | 
    
         
             
                      File.delete profile
         
     | 
| 
       88 
89 
     | 
    
         
             
                    end
         
     | 
| 
       89 
90 
     | 
    
         | 
| 
       90 
91 
     | 
    
         
             
                    def create_profile(file_or_list, profile, recursive = false)
         
     | 
| 
       91 
92 
     | 
    
         
             
                      args = []
         
     | 
| 
       92 
     | 
    
         
            -
                      files =  
     | 
| 
       93 
     | 
    
         
            -
                      files.each {|file| args << '-a' << file}
         
     | 
| 
      
 93 
     | 
    
         
            +
                      files = file_or_list.is_a?(Array) ? file_or_list.map(&:escape_for_string) : [file_or_list.escape_for_string]
         
     | 
| 
      
 94 
     | 
    
         
            +
                      files.each { |file| args << '-a' << file }
         
     | 
| 
       94 
95 
     | 
    
         
             
                      args << '-q'
         
     | 
| 
       95 
96 
     | 
    
         
             
                      args << '-p' << profile
         
     | 
| 
       96 
97 
     | 
    
         
             
                      args << '-R' if recursive
         
     | 
| 
       97 
98 
     | 
    
         
             
                      timeout = Libis::Format::Config[:timeouts][:droid]
         
     | 
| 
       98 
99 
     | 
    
         
             
                      result = Libis::Tools::Command.run(
         
     | 
| 
       99 
     | 
    
         
            -
             
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
             
     | 
| 
      
 100 
     | 
    
         
            +
                        Libis::Format::Config[:droid_cmd], *args,
         
     | 
| 
      
 101 
     | 
    
         
            +
                        timeout:,
         
     | 
| 
      
 102 
     | 
    
         
            +
                        kill_after: timeout * 2
         
     | 
| 
       102 
103 
     | 
    
         
             
                      )
         
     | 
| 
       103 
     | 
    
         
            -
                      result[:err].select! {|x| x =~ /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} ERROR /}
         
     | 
| 
       104 
     | 
    
         
            -
                      raise  
     | 
| 
       105 
     | 
    
         
            -
                      raise  
     | 
| 
      
 104 
     | 
    
         
            +
                      result[:err].select! { |x| x =~ /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3} ERROR / }
         
     | 
| 
      
 105 
     | 
    
         
            +
                      raise "#{self.class} profile took too long (> #{timeout} seconds) to complete" if result[:timeout]
         
     | 
| 
      
 106 
     | 
    
         
            +
                      raise "#{self.class} profile errors: #{result[:err].join("\n")}" unless result[:err].empty?
         
     | 
| 
       106 
107 
     | 
    
         
             
                    end
         
     | 
| 
       107 
108 
     | 
    
         | 
| 
       108 
109 
     | 
    
         
             
                    def profile_file_name
         
     | 
| 
         @@ -112,9 +113,7 @@ module Libis 
     | 
|
| 
       112 
113 
     | 
    
         
             
                    def result_file_name
         
     | 
| 
       113 
114 
     | 
    
         
             
                      Tools::TempFile.name('droid', '.csv')
         
     | 
| 
       114 
115 
     | 
    
         
             
                    end
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
       116 
116 
     | 
    
         
             
                  end
         
     | 
| 
       117 
     | 
    
         
            -
             
     | 
| 
       118 
117 
     | 
    
         
             
                end
         
     | 
| 
       119 
118 
     | 
    
         
             
              end
         
     | 
| 
       120 
119 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'libis/tools/extend/string'
         
     | 
| 
       2 
4 
     | 
    
         
             
            require 'libis/tools/extend/empty'
         
     | 
| 
       3 
5 
     | 
    
         
             
            require 'libis/tools/command'
         
     | 
| 
         @@ -8,18 +10,17 @@ require 'libis/format/config' 
     | 
|
| 
       8 
10 
     | 
    
         
             
            module Libis
         
     | 
| 
       9 
11 
     | 
    
         
             
              module Format
         
     | 
| 
       10 
12 
     | 
    
         
             
                module Tool
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
13 
     | 
    
         
             
                  class FFMpeg
         
     | 
| 
       13 
14 
     | 
    
         
             
                    include Singleton
         
     | 
| 
       14 
15 
     | 
    
         
             
                    include ::Libis::Tools::Logger
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
17 
     | 
    
         
             
                    def self.installed?
         
     | 
| 
       17 
     | 
    
         
            -
                      result = Libis::Tools::Command.run(Libis::Format::Config[:ffmpeg_cmd],  
     | 
| 
       18 
     | 
    
         
            -
                      result[:status] 
     | 
| 
      
 18 
     | 
    
         
            +
                      result = Libis::Tools::Command.run(Libis::Format::Config[:ffmpeg_cmd], '-h')
         
     | 
| 
      
 19 
     | 
    
         
            +
                      (result[:status]).zero?
         
     | 
| 
       19 
20 
     | 
    
         
             
                    end
         
     | 
| 
       20 
21 
     | 
    
         | 
| 
       21 
22 
     | 
    
         
             
                    def self.run(source, target, options = {})
         
     | 
| 
       22 
     | 
    
         
            -
                       
     | 
| 
      
 23 
     | 
    
         
            +
                      instance.run source, target, options
         
     | 
| 
       23 
24 
     | 
    
         
             
                    end
         
     | 
| 
       24 
25 
     | 
    
         | 
| 
       25 
26 
     | 
    
         
             
                    def run(source, target, options = {})
         
     | 
| 
         @@ -33,25 +34,22 @@ module Libis 
     | 
|
| 
       33 
34 
     | 
    
         | 
| 
       34 
35 
     | 
    
         
             
                      timeout = Libis::Format::Config[:timeouts][:ffmpeg]
         
     | 
| 
       35 
36 
     | 
    
         
             
                      result = Libis::Tools::Command.run(
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
      
 37 
     | 
    
         
            +
                        Libis::Format::Config[:ffmpeg_cmd], *opts,
         
     | 
| 
      
 38 
     | 
    
         
            +
                        timeout:,
         
     | 
| 
      
 39 
     | 
    
         
            +
                        kill_after: timeout * 2
         
     | 
| 
       39 
40 
     | 
    
         
             
                      )
         
     | 
| 
       40 
41 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                      raise  
     | 
| 
       42 
     | 
    
         
            -
                      raise  
     | 
| 
      
 42 
     | 
    
         
            +
                      raise "#{self.class} took too long (> #{timeout} seconds) to complete" if result[:timeout]
         
     | 
| 
      
 43 
     | 
    
         
            +
                      raise "#{self.class} errors: #{result[:err].join("\n")}" unless (result[:status]).zero?
         
     | 
| 
       43 
44 
     | 
    
         | 
| 
       44 
45 
     | 
    
         
             
                      warn "FFMpeg warnings: #{(result[:err] + result[:out]).join("\n")}" unless result[:err].empty?
         
     | 
| 
       45 
46 
     | 
    
         | 
| 
       46 
47 
     | 
    
         
             
                      {
         
     | 
| 
       47 
48 
     | 
    
         
             
                        command: result,
         
     | 
| 
       48 
     | 
    
         
            -
                        files: [ 
     | 
| 
      
 49 
     | 
    
         
            +
                        files: [target]
         
     | 
| 
       49 
50 
     | 
    
         
             
                      }
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
51 
     | 
    
         
             
                    end
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
52 
     | 
    
         
             
                  end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
53 
     | 
    
         
             
                end
         
     | 
| 
       56 
54 
     | 
    
         
             
              end
         
     | 
| 
       57 
55 
     | 
    
         
             
            end
         
     | 
| 
         @@ -80,7 +80,7 @@ module Libis 
     | 
|
| 
       80 
80 
     | 
    
         | 
| 
       81 
81 
     | 
    
         
             
                      # Log warning if needed
         
     | 
| 
       82 
82 
     | 
    
         
             
                      raise "#{self.class} took too long (> #{timeout} seconds) to complete" if result[:timeout]
         
     | 
| 
       83 
     | 
    
         
            -
                      raise "#{self.class} errors: #{result[:err].join("\n")}" unless (result[:status]) 
     | 
| 
      
 83 
     | 
    
         
            +
                      raise "#{self.class} errors: #{result[:err].join("\n")}" unless (result[:status])&.zero? && result[:err].empty?
         
     | 
| 
       84 
84 
     | 
    
         | 
| 
       85 
85 
     | 
    
         
             
                      # Parse output (CSV) text into array and return result
         
     | 
| 
       86 
86 
     | 
    
         
             
                      keys = %i[status time puid format_name format_version filesize filepath mimetype matchtype]
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'os'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            require 'libis/tools/extend/string'
         
     | 
| 
         @@ -9,49 +11,46 @@ require 'libis/format/config' 
     | 
|
| 
       9 
11 
     | 
    
         
             
            module Libis
         
     | 
| 
       10 
12 
     | 
    
         
             
              module Format
         
     | 
| 
       11 
13 
     | 
    
         
             
                module Tool
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
14 
     | 
    
         
             
                  class PdfCopy
         
     | 
| 
       14 
15 
     | 
    
         
             
                    include ::Libis::Tools::Logger
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
17 
     | 
    
         
             
                    def self.installed?
         
     | 
| 
       17 
     | 
    
         
            -
                      result = Libis::Tools::Command.run(Libis::Format::Config[:java_cmd],  
     | 
| 
       18 
     | 
    
         
            -
                      return false unless result[:status] 
     | 
| 
      
 18 
     | 
    
         
            +
                      result = Libis::Tools::Command.run(Libis::Format::Config[:java_cmd], '-version')
         
     | 
| 
      
 19 
     | 
    
         
            +
                      return false unless (result[:status]).zero?
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       19 
21 
     | 
    
         
             
                      File.exist?(Libis::Format::Config[:pdf_tool])
         
     | 
| 
       20 
22 
     | 
    
         
             
                    end
         
     | 
| 
       21 
23 
     | 
    
         | 
| 
       22 
24 
     | 
    
         
             
                    def self.run(source, target, options = [])
         
     | 
| 
       23 
     | 
    
         
            -
                       
     | 
| 
      
 25 
     | 
    
         
            +
                      new.run source, target, options
         
     | 
| 
       24 
26 
     | 
    
         
             
                    end
         
     | 
| 
       25 
27 
     | 
    
         | 
| 
       26 
28 
     | 
    
         
             
                    def run(source, target, options = [])
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
       28 
29 
     | 
    
         
             
                      if OS.java?
         
     | 
| 
       29 
30 
     | 
    
         
             
                        # TODO: import library and execute in current VM. For now do exactly as in MRI.
         
     | 
| 
       30 
31 
     | 
    
         
             
                      end
         
     | 
| 
       31 
32 
     | 
    
         | 
| 
       32 
33 
     | 
    
         
             
                      timeout = Libis::Format::Config[:timeouts][:pdf_copy]
         
     | 
| 
       33 
34 
     | 
    
         
             
                      result = Libis::Tools::Command.run(
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
      
 35 
     | 
    
         
            +
                        Libis::Format::Config[:java_cmd],
         
     | 
| 
      
 36 
     | 
    
         
            +
                        '-cp', Libis::Format::Config[:pdf_tool],
         
     | 
| 
      
 37 
     | 
    
         
            +
                        'CopyPdf',
         
     | 
| 
      
 38 
     | 
    
         
            +
                        '--file_input', source,
         
     | 
| 
      
 39 
     | 
    
         
            +
                        '--file_output', target,
         
     | 
| 
      
 40 
     | 
    
         
            +
                        *options,
         
     | 
| 
      
 41 
     | 
    
         
            +
                        timeout:,
         
     | 
| 
      
 42 
     | 
    
         
            +
                        kill_after: timeout * 2
         
     | 
| 
       42 
43 
     | 
    
         
             
                      )
         
     | 
| 
       43 
44 
     | 
    
         | 
| 
       44 
     | 
    
         
            -
                      raise  
     | 
| 
       45 
     | 
    
         
            -
                      raise  
     | 
| 
      
 45 
     | 
    
         
            +
                      raise "#{self.class} took too long (> #{timeout} seconds) to complete" if result[:timeout]
         
     | 
| 
      
 46 
     | 
    
         
            +
                      raise "#{self.class} errors: #{result[:err].join("\n")}" unless (result[:status]).zero? && result[:err].empty?
         
     | 
| 
       46 
47 
     | 
    
         | 
| 
       47 
48 
     | 
    
         
             
                      {
         
     | 
| 
       48 
49 
     | 
    
         
             
                        command: result,
         
     | 
| 
       49 
     | 
    
         
            -
                        files: [ 
     | 
| 
      
 50 
     | 
    
         
            +
                        files: [target]
         
     | 
| 
       50 
51 
     | 
    
         
             
                      }
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
52 
     | 
    
         
             
                    end
         
     | 
| 
       53 
53 
     | 
    
         
             
                  end
         
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
54 
     | 
    
         
             
                end
         
     | 
| 
       56 
55 
     | 
    
         
             
              end
         
     | 
| 
       57 
56 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'os'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            require 'libis/tools/extend/string'
         
     | 
| 
         @@ -9,18 +11,18 @@ require 'libis/format/config' 
     | 
|
| 
       9 
11 
     | 
    
         
             
            module Libis
         
     | 
| 
       10 
12 
     | 
    
         
             
              module Format
         
     | 
| 
       11 
13 
     | 
    
         
             
                module Tool
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
14 
     | 
    
         
             
                  class PdfMerge
         
     | 
| 
       14 
15 
     | 
    
         
             
                    include ::Libis::Tools::Logger
         
     | 
| 
       15 
16 
     | 
    
         | 
| 
       16 
17 
     | 
    
         
             
                    def self.installed?
         
     | 
| 
       17 
     | 
    
         
            -
                      result = Libis::Tools::Command.run(Libis::Format::Config[:java_cmd],  
     | 
| 
       18 
     | 
    
         
            -
                      return false unless result[:status] 
     | 
| 
      
 18 
     | 
    
         
            +
                      result = Libis::Tools::Command.run(Libis::Format::Config[:java_cmd], '-version')
         
     | 
| 
      
 19 
     | 
    
         
            +
                      return false unless (result[:status]).zero?
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
       19 
21 
     | 
    
         
             
                      File.exist?(Libis::Format::Config[:pdf_tool])
         
     | 
| 
       20 
22 
     | 
    
         
             
                    end
         
     | 
| 
       21 
23 
     | 
    
         | 
| 
       22 
24 
     | 
    
         
             
                    def self.run(source, target, options = [])
         
     | 
| 
       23 
     | 
    
         
            -
                       
     | 
| 
      
 25 
     | 
    
         
            +
                      new.run source, target, options
         
     | 
| 
       24 
26 
     | 
    
         
             
                    end
         
     | 
| 
       25 
27 
     | 
    
         | 
| 
       26 
28 
     | 
    
         
             
                    def run(source, target, options = [])
         
     | 
| 
         @@ -32,27 +34,25 @@ module Libis 
     | 
|
| 
       32 
34 
     | 
    
         | 
| 
       33 
35 
     | 
    
         
             
                      timeout = Libis::Format::Config[:timeouts][:pdf_merge]
         
     | 
| 
       34 
36 
     | 
    
         
             
                      result = Libis::Tools::Command.run(
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
       40 
     | 
    
         
            -
             
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
      
 37 
     | 
    
         
            +
                        Libis::Format::Config[:java_cmd],
         
     | 
| 
      
 38 
     | 
    
         
            +
                        '-cp', Libis::Format::Config[:pdf_tool],
         
     | 
| 
      
 39 
     | 
    
         
            +
                        'MergePdf',
         
     | 
| 
      
 40 
     | 
    
         
            +
                        '--file_output', target,
         
     | 
| 
      
 41 
     | 
    
         
            +
                        *options,
         
     | 
| 
      
 42 
     | 
    
         
            +
                        *source,
         
     | 
| 
      
 43 
     | 
    
         
            +
                        timeout:,
         
     | 
| 
      
 44 
     | 
    
         
            +
                        kill_after: timeout * 2
         
     | 
| 
       43 
45 
     | 
    
         
             
                      )
         
     | 
| 
       44 
46 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
                      raise  
     | 
| 
       46 
     | 
    
         
            -
                      raise  
     | 
| 
      
 47 
     | 
    
         
            +
                      raise "#{self.class} took too long (> #{timeout} seconds) to complete" if result[:timeout]
         
     | 
| 
      
 48 
     | 
    
         
            +
                      raise "#{self.class} errors: #{result[:err].join("\n")}" unless (result[:status]).zero? && result[:err].empty?
         
     | 
| 
       47 
49 
     | 
    
         | 
| 
       48 
50 
     | 
    
         
             
                      {
         
     | 
| 
       49 
51 
     | 
    
         
             
                        command: result,
         
     | 
| 
       50 
     | 
    
         
            -
                        files: [ 
     | 
| 
      
 52 
     | 
    
         
            +
                        files: [target]
         
     | 
| 
       51 
53 
     | 
    
         
             
                      }
         
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
       53 
54 
     | 
    
         
             
                    end
         
     | 
| 
       54 
55 
     | 
    
         
             
                  end
         
     | 
| 
       55 
     | 
    
         
            -
             
     | 
| 
       56 
56 
     | 
    
         
             
                end
         
     | 
| 
       57 
57 
     | 
    
         
             
              end
         
     | 
| 
       58 
58 
     | 
    
         
             
            end
         
     |