libis-format 1.3.2 → 2.0.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/.coveralls.yml +2 -0
- data/.gitignore +20 -0
- data/.travis.yml +70 -0
- data/Gemfile +0 -12
- data/README.md +2 -2
- data/Rakefile +8 -0
- data/base/Dockerfile +35 -0
- data/base/Dockerfile.alpine +20 -0
- data/base/Dockerfile.rvm +56 -0
- data/base/rework_path +20 -0
- data/bin/{pdf_tool → pdf_copy} +2 -3
- data/data/PDFA_def.ps +3 -3
- data/data/eciRGB_v2.icc +0 -0
- data/data/types.yml +4 -17
- data/docker_cfg.yml +1 -0
- data/lib/libis/format/cli/convert.rb +4 -4
- data/lib/libis/format/cli/prompt_helper.rb +24 -32
- data/lib/libis/format/command_line.rb +3 -2
- data/lib/libis/format/config.rb +23 -19
- data/lib/libis/format/converter/audio_converter.rb +31 -56
- data/lib/libis/format/converter/base.rb +36 -16
- data/lib/libis/format/converter/chain.rb +32 -52
- data/lib/libis/format/converter/fop_pdf_converter.rb +8 -4
- data/lib/libis/format/converter/image_assembler.rb +82 -0
- data/lib/libis/format/converter/image_converter.rb +40 -153
- data/lib/libis/format/converter/image_splitter.rb +80 -0
- data/lib/libis/format/converter/image_watermarker.rb +261 -0
- data/lib/libis/format/converter/jp2_converter.rb +38 -36
- data/lib/libis/format/converter/office_converter.rb +28 -22
- data/lib/libis/format/converter/pdf_assembler.rb +66 -0
- data/lib/libis/format/converter/pdf_converter.rb +52 -200
- data/lib/libis/format/converter/pdf_optimizer.rb +70 -0
- data/lib/libis/format/converter/pdf_splitter.rb +65 -0
- data/lib/libis/format/converter/pdf_watermarker.rb +110 -0
- data/lib/libis/format/converter/repository.rb +13 -7
- data/lib/libis/format/converter/spreadsheet_converter.rb +16 -10
- data/lib/libis/format/converter/video_converter.rb +58 -47
- data/lib/libis/format/converter/xslt_converter.rb +11 -13
- data/lib/libis/format/converter.rb +1 -1
- data/lib/libis/format/identifier.rb +46 -44
- data/lib/libis/format/info.rb +27 -0
- data/lib/libis/format/library.rb +147 -0
- data/lib/libis/format/tool/droid.rb +30 -29
- data/lib/libis/format/tool/extension_identification.rb +26 -24
- data/lib/libis/format/tool/{ff_mpeg.rb → ffmpeg.rb} +10 -17
- data/lib/libis/format/tool/fido.rb +27 -22
- data/lib/libis/format/tool/file_tool.rb +24 -11
- data/lib/libis/format/tool/fop_pdf.rb +14 -25
- data/lib/libis/format/tool/identification_tool.rb +40 -38
- data/lib/libis/format/tool/office_to_pdf.rb +18 -30
- data/lib/libis/format/tool/pdf_copy.rb +47 -0
- data/lib/libis/format/tool/pdf_merge.rb +48 -0
- data/lib/libis/format/tool/pdf_optimizer.rb +19 -22
- data/lib/libis/format/tool/pdf_split.rb +47 -0
- data/lib/libis/format/tool/pdf_to_pdfa.rb +31 -45
- data/lib/libis/format/tool/pdfa_validator.rb +30 -24
- data/lib/libis/format/tool/spreadsheet_to_ods.rb +18 -29
- data/lib/libis/format/tool.rb +3 -4
- data/lib/libis/format/version.rb +1 -3
- data/lib/libis/format/yaml_loader.rb +71 -0
- data/lib/libis/format.rb +7 -5
- data/lib/libis-format.rb +0 -2
- data/libis-format.gemspec +18 -24
- data/tools/PdfTool.jar +0 -0
- data/tools/pdfbox/pdfbox-app-2.0.13.jar +0 -0
- data/tools/pdfbox/{preflight-app-3.0.3.jar → preflight-app-2.0.13.jar} +0 -0
- metadata +85 -125
- data/data/AdobeRGB1998.icc +0 -0
- data/lib/libis/format/converter/email_converter.rb +0 -35
- data/lib/libis/format/tool/msg_to_pdf.rb +0 -270
- data/lib/libis/format/tool/pdf_tool.rb +0 -52
- data/lib/libis/format/type_database.rb +0 -156
- data/lib/libis/format/type_database_impl.rb +0 -153
- data/tools/pdf2pdfa +0 -395
- data/tools/pdfbox/pdfbox-app-3.0.3.jar +0 -0
- /data/bin/{droid_tool → droid} +0 -0
- /data/bin/{fido_tool → fido} +0 -0
| @@ -1,5 +1,3 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            require_relative 'base'
         | 
| 4 2 | 
             
            require 'libis/format/identifier'
         | 
| 5 3 | 
             
            require 'chromaprint'
         | 
| @@ -9,19 +7,24 @@ require 'fileutils' | |
| 9 7 | 
             
            module Libis
         | 
| 10 8 | 
             
              module Format
         | 
| 11 9 | 
             
                module Converter
         | 
| 10 | 
            +
             | 
| 12 11 | 
             
                  class AudioConverter < Libis::Format::Converter::Base
         | 
| 12 | 
            +
             | 
| 13 13 | 
             
                    def self.input_types
         | 
| 14 | 
            -
                       | 
| 14 | 
            +
                      [:MP3, :FLAC, :AC3, :AAC, :WMA, :ALAC, :WAV, :AIFF, :AMR, :AU, :M4A]
         | 
| 15 15 | 
             
                    end
         | 
| 16 16 |  | 
| 17 17 | 
             
                    def self.output_types(format = nil)
         | 
| 18 | 
            -
                      return [] unless input_types.include?(format)
         | 
| 18 | 
            +
                      return [] unless format.nil? || input_types.include?(format)
         | 
| 19 | 
            +
                      [:MP3, :FLAC, :AC3, :AAC, :WMA, :ALAC, :WAV, :AIFF, :AMR, :AU, :M4A]
         | 
| 20 | 
            +
                    end
         | 
| 19 21 |  | 
| 20 | 
            -
             | 
| 22 | 
            +
                    def initialize
         | 
| 23 | 
            +
                      super
         | 
| 21 24 | 
             
                    end
         | 
| 22 25 |  | 
| 23 | 
            -
                    def quiet( | 
| 24 | 
            -
                      @flags[:quiet] = !! | 
| 26 | 
            +
                    def quiet(v)
         | 
| 27 | 
            +
                      @flags[:quiet] = !!v
         | 
| 25 28 | 
             
                    end
         | 
| 26 29 |  | 
| 27 30 | 
             
                    def format(format)
         | 
| @@ -57,70 +60,38 @@ module Libis | |
| 57 60 | 
             
                    end
         | 
| 58 61 |  | 
| 59 62 | 
             
                    def web_stream(value)
         | 
| 60 | 
            -
                       | 
| 61 | 
            -
             | 
| 62 | 
            -
                       | 
| 63 | 
            +
                      if value
         | 
| 64 | 
            +
                        @options[:codec] = 'mp3'
         | 
| 65 | 
            +
                      end
         | 
| 63 66 | 
             
                    end
         | 
| 64 67 |  | 
| 65 68 | 
             
                    def preset(stream, name)
         | 
| 66 69 | 
             
                      (@options[:preset] ||= {})[stream] = name
         | 
| 67 70 | 
             
                    end
         | 
| 68 71 |  | 
| 69 | 
            -
                    # def encoder(value)
         | 
| 70 | 
            -
                    #   @options[:encoder] = value
         | 
| 71 | 
            -
                    # end
         | 
| 72 | 
            -
                    #
         | 
| 73 | 
            -
                    # def encoder_options(value)
         | 
| 74 | 
            -
                    #   @options[:encoder_options] = value
         | 
| 75 | 
            -
                    # end
         | 
| 76 | 
            -
             | 
| 77 72 | 
             
                    def convert(source, target, _format, opts = {})
         | 
| 78 73 | 
             
                      super
         | 
| 79 74 |  | 
| 80 75 | 
             
                      FileUtils.mkpath(File.dirname(target))
         | 
| 81 76 |  | 
| 82 | 
            -
                       | 
| 83 | 
            -
             | 
| 84 | 
            -
                        assemble_and_convert(source, target)
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                      elsif File.directory?(source)
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                        sources = Dir[File.join(source, '**', '*')].reject { |p| File.directory? p }
         | 
| 89 | 
            -
                        assemble_and_convert(sources, target)
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                      else
         | 
| 77 | 
            +
                      convert_file(source, target)
         | 
| 92 78 |  | 
| 93 | 
            -
                        convert_file(source, target)
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                      end
         | 
| 96 | 
            -
                    end
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                    def assemble_and_convert(sources, target)
         | 
| 99 | 
            -
                      result = {}
         | 
| 100 | 
            -
                      Tempfile.create(%w[list .txt]) do |f|
         | 
| 101 | 
            -
                        sources.each { |src| f.puts src }
         | 
| 102 | 
            -
                        opts[:global] ||= []
         | 
| 103 | 
            -
                        opts[:global] += %w[-f concat]
         | 
| 104 | 
            -
                        f.close
         | 
| 105 | 
            -
                        result = convert_file(f.to_path, target)
         | 
| 106 | 
            -
                      end
         | 
| 107 | 
            -
                      result
         | 
| 108 79 | 
             
                    end
         | 
| 109 80 |  | 
| 110 81 | 
             
                    def self.sounds_like(file1, file2, threshold, rate, channels)
         | 
| 111 | 
            -
                      rate ||=  | 
| 82 | 
            +
                      rate ||= 96000
         | 
| 112 83 | 
             
                      channels ||= 2
         | 
| 113 84 | 
             
                      threshold ||= 0.85
         | 
| 114 85 |  | 
| 115 | 
            -
                      if File. | 
| 86 | 
            +
                      if File.exists?(file1) && File.exists?(file2)
         | 
| 116 87 | 
             
                        # Convert input files into raw 16-bit signed audio (WAV) to process with Chramaprint
         | 
| 117 | 
            -
                        file1_raw = File.join('', 'tmp',  | 
| 118 | 
            -
                        file2_raw = File.join('', 'tmp',  | 
| 88 | 
            +
                        file1_raw = File.join('', 'tmp', File.basename(file1) + '.wav')
         | 
| 89 | 
            +
                        file2_raw = File.join('', 'tmp', File.basename(file2) + '.wav')
         | 
| 119 90 | 
             
                        FileUtils.rm(file1_raw, force: true)
         | 
| 120 91 | 
             
                        FileUtils.rm(file2_raw, force: true)
         | 
| 121 92 | 
             
                        cvt_cmd = Libis::Format::Config[:raw_audio_convert_cmd]
         | 
| 122 | 
            -
                         | 
| 123 | 
            -
                         | 
| 93 | 
            +
                        %x"#{cvt_cmd % [file1, file1_raw, rate, channels]}"
         | 
| 94 | 
            +
                        %x"#{cvt_cmd % [file2, file2_raw, rate, channels]}"
         | 
| 124 95 | 
             
                        file1_audio = File.binread(file1_raw)
         | 
| 125 96 | 
             
                        file2_audio = File.binread(file2_raw)
         | 
| 126 97 |  | 
| @@ -140,33 +111,37 @@ module Libis | |
| 140 111 | 
             
                      else
         | 
| 141 112 | 
             
                        false
         | 
| 142 113 | 
             
                      end
         | 
| 114 | 
            +
             | 
| 143 115 | 
             
                    rescue Exception => e
         | 
| 144 | 
            -
                       | 
| 116 | 
            +
                      error "Error comparing sound file #{file1} and #{file2}: #{e.message} @ #{e.backtrace.first}"
         | 
| 145 117 | 
             
                      false
         | 
| 146 118 | 
             
                    end
         | 
| 147 119 |  | 
| 148 120 | 
             
                    protected
         | 
| 149 121 |  | 
| 150 122 | 
             
                    def convert_file(source, target)
         | 
| 151 | 
            -
                      opts = { | 
| 152 | 
            -
             | 
| 123 | 
            +
                      opts = {global: [], input: [], filter: [], output: []}
         | 
| 153 124 | 
             
                      opts[:global] << '-hide_banner'
         | 
| 154 125 | 
             
                      opts[:global] << '-loglevel' << (@options[:quiet] ? 'fatal' : 'warning')
         | 
| 155 126 | 
             
                      opts[:output] << '-vn' # disable input video stream in case it exists
         | 
| 156 127 | 
             
                      opts[:output] << '-codec:a' << @options[:codec] if @options[:codec]
         | 
| 157 128 | 
             
                      opts[:output] << '-map_metadata:g' << '0:g' # Copy global metadata
         | 
| 158 129 | 
             
                      opts[:output] << '-map_metadata:s:a' << '0:s:a' # Copy audio metadata
         | 
| 159 | 
            -
                      opts[:input] << '-accurate_seek' << (@options[:start].to_i | 
| 130 | 
            +
                      opts[:input] << '-accurate_seek' << (@options[:start].to_i < 0 ? '-sseof' : '-ss') << @options[:start] if @options[:start]
         | 
| 160 131 | 
             
                      opts[:input] << '-t' << @options[:duration] if @options[:duration]
         | 
| 161 132 | 
             
                      opts[:output] << '-q:a' << @options[:quality] if @options[:quality]
         | 
| 162 133 | 
             
                      opts[:output] << '-b:a' << @options[:bit_rate] if @options[:bit_rate]
         | 
| 163 134 | 
             
                      opts[:output] << '-ar' << @options[:sampling_freq] if @options[:sampling_freq]
         | 
| 164 135 | 
             
                      opts[:output] << '-ac' << @options[:channels] if @options[:channels]
         | 
| 165 136 | 
             
                      opts[:output] << '-f' << @options[:format] if @options[:format]
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                       | 
| 137 | 
            +
                      result = Libis::Format::Tool::FFMpeg.run(source, target, opts)
         | 
| 138 | 
            +
                      info "FFMpeg output: #{result}"
         | 
| 139 | 
            +
                      result
         | 
| 140 | 
            +
                      target
         | 
| 168 141 | 
             
                    end
         | 
| 142 | 
            +
             | 
| 169 143 | 
             
                  end
         | 
| 144 | 
            +
             | 
| 170 145 | 
             
                end
         | 
| 171 146 | 
             
              end
         | 
| 172 | 
            -
            end
         | 
| 147 | 
            +
            end
         | 
| @@ -1,16 +1,17 @@ | |
| 1 | 
            -
            #  | 
| 1 | 
            +
            # coding: utf-8
         | 
| 2 2 |  | 
| 3 3 | 
             
            ### require 'tools/string'
         | 
| 4 4 | 
             
            require 'tmpdir'
         | 
| 5 5 | 
             
            require 'libis/tools/logger'
         | 
| 6 6 | 
             
            require 'libis/tools/temp_file'
         | 
| 7 | 
            -
            require 'libis/format/ | 
| 7 | 
            +
            require 'libis/format/library'
         | 
| 8 8 |  | 
| 9 9 | 
             
            require_relative 'repository'
         | 
| 10 10 |  | 
| 11 11 | 
             
            module Libis
         | 
| 12 12 | 
             
              module Format
         | 
| 13 13 | 
             
                module Converter
         | 
| 14 | 
            +
             | 
| 14 15 | 
             
                  class Base
         | 
| 15 16 | 
             
                    include Libis::Tools::Logger
         | 
| 16 17 |  | 
| @@ -21,43 +22,58 @@ module Libis | |
| 21 22 | 
             
                      @flags = {}
         | 
| 22 23 | 
             
                    end
         | 
| 23 24 |  | 
| 24 | 
            -
                    def  | 
| 25 | 
            -
                       | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 25 | 
            +
                    def self.category
         | 
| 26 | 
            +
                      :converter
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    def check_file_exist(file)
         | 
| 30 | 
            +
                      unless File.exist? file
         | 
| 31 | 
            +
                        error "Cannot find file '#{file}'."
         | 
| 32 | 
            +
                        return false
         | 
| 33 | 
            +
                      end
         | 
| 34 | 
            +
                      true
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    def convert(source, target, format, opts = {})
         | 
| 38 | 
            +
                      if source.is_a?(Array)
         | 
| 39 | 
            +
                        return nil unless source.map { |f| check_file_exist(f) }.reduce(:&)
         | 
| 40 | 
            +
                      else
         | 
| 41 | 
            +
                        return nil unless check_file_exist(source)
         | 
| 28 42 | 
             
                      end
         | 
| 29 43 | 
             
                      @options.merge!(opts[:options]) if opts[:options]
         | 
| 30 44 | 
             
                      @flags.merge!(opts[:flags]) if opts[:flags]
         | 
| 31 45 | 
             
                    end
         | 
| 32 46 |  | 
| 33 47 | 
             
                    def self.input_types
         | 
| 34 | 
            -
                      raise 'Method #input_types needs to be overridden in converter'
         | 
| 48 | 
            +
                      raise RuntimeError, 'Method #input_types needs to be overridden in converter'
         | 
| 35 49 | 
             
                    end
         | 
| 36 50 |  | 
| 37 51 | 
             
                    def self.output_types(_format = nil)
         | 
| 38 | 
            -
                      raise 'Method #output_types needs to be overridden in converter'
         | 
| 52 | 
            +
                      raise RuntimeError, 'Method #output_types needs to be overridden in converter'
         | 
| 39 53 | 
             
                    end
         | 
| 40 54 |  | 
| 41 55 | 
             
                    def using_temp(target, &block)
         | 
| 42 56 | 
             
                      self.class.using_temp(target, &block)
         | 
| 43 57 | 
             
                    end
         | 
| 44 58 |  | 
| 45 | 
            -
                    def  | 
| 59 | 
            +
                    def Base.using_temp(target)
         | 
| 46 60 | 
             
                      tempfile = Tools::TempFile.name("convert-#{File.basename(target, '.*').gsub(/\s/, '_')}", File.extname(target))
         | 
| 47 61 | 
             
                      result = yield tempfile
         | 
| 48 62 | 
             
                      return nil unless result
         | 
| 49 | 
            -
             | 
| 50 63 | 
             
                      FileUtils.move result, target
         | 
| 51 64 | 
             
                      target
         | 
| 52 65 | 
             
                    end
         | 
| 53 66 |  | 
| 54 | 
            -
                    def  | 
| 67 | 
            +
                    def Base.inherited(klass)
         | 
| 68 | 
            +
             | 
| 55 69 | 
             
                      Repository.register klass
         | 
| 56 70 |  | 
| 57 71 | 
             
                      class << self
         | 
| 72 | 
            +
             | 
| 58 73 | 
             
                        def conversions
         | 
| 59 | 
            -
                          input_types. | 
| 74 | 
            +
                          input_types.inject({}) do |hash, input_type|
         | 
| 60 75 | 
             
                            hash[input_type] = output_types
         | 
| 76 | 
            +
                            hash
         | 
| 61 77 | 
             
                          end
         | 
| 62 78 | 
             
                        end
         | 
| 63 79 |  | 
| @@ -70,17 +86,17 @@ module Libis | |
| 70 86 | 
             
                        end
         | 
| 71 87 |  | 
| 72 88 | 
             
                        def input_mimetype?(mimetype)
         | 
| 73 | 
            -
                          type_id =  | 
| 89 | 
            +
                          type_id = Libis::Format::Library.get_field_by(:mimetype, mimetype, :format)
         | 
| 74 90 | 
             
                          input_type? type_id
         | 
| 75 91 | 
             
                        end
         | 
| 76 92 |  | 
| 77 93 | 
             
                        def output_mimetype?(mimetype)
         | 
| 78 | 
            -
                          type_id =  | 
| 94 | 
            +
                          type_id = Libis::Format::Library.get_field_by(:mimetype, mimetype, :format)
         | 
| 79 95 | 
             
                          output_type? type_id
         | 
| 80 96 | 
             
                        end
         | 
| 81 97 |  | 
| 82 98 | 
             
                        def conversion?(input_type, output_type)
         | 
| 83 | 
            -
                          conversions[input_type] | 
| 99 | 
            +
                          conversions[input_type] and conversions[input_type].any? { |t| t == output_type }
         | 
| 84 100 | 
             
                        end
         | 
| 85 101 |  | 
| 86 102 | 
             
                        def output_for(input_type)
         | 
| @@ -88,11 +104,15 @@ module Libis | |
| 88 104 | 
             
                        end
         | 
| 89 105 |  | 
| 90 106 | 
             
                        def extension?(extension)
         | 
| 91 | 
            -
                          ! | 
| 107 | 
            +
                          !Libis::Format::Library.get_field_by(:extension, extension, :format).nil?
         | 
| 92 108 | 
             
                        end
         | 
| 109 | 
            +
             | 
| 93 110 | 
             
                      end
         | 
| 111 | 
            +
             | 
| 94 112 | 
             
                    end
         | 
| 113 | 
            +
             | 
| 95 114 | 
             
                  end
         | 
| 115 | 
            +
             | 
| 96 116 | 
             
                end
         | 
| 97 117 | 
             
              end
         | 
| 98 118 | 
             
            end
         | 
| @@ -1,15 +1,16 @@ | |
| 1 | 
            -
            #  | 
| 1 | 
            +
            # coding: utf-8
         | 
| 2 2 |  | 
| 3 3 | 
             
            require 'fileutils'
         | 
| 4 4 | 
             
            require 'deep_dive'
         | 
| 5 5 |  | 
| 6 6 | 
             
            require 'libis/tools/logger'
         | 
| 7 7 | 
             
            require 'libis/tools/extend/hash'
         | 
| 8 | 
            -
            require 'libis/format/ | 
| 8 | 
            +
            require 'libis/format/library'
         | 
| 9 9 |  | 
| 10 10 | 
             
            module Libis
         | 
| 11 11 | 
             
              module Format
         | 
| 12 12 | 
             
                module Converter
         | 
| 13 | 
            +
             | 
| 13 14 | 
             
                  class Chain
         | 
| 14 15 | 
             
                    include ::Libis::Tools::Logger
         | 
| 15 16 | 
             
                    include DeepDive
         | 
| @@ -25,16 +26,15 @@ module Libis | |
| 25 26 | 
             
                    # @return [Array[Hash]]
         | 
| 26 27 | 
             
                    def append(converter)
         | 
| 27 28 | 
             
                      return [] unless converter
         | 
| 28 | 
            -
             | 
| 29 29 | 
             
                      valid_chain_nodes(converter).map do |node|
         | 
| 30 | 
            -
                        ddup.add_chain_node(node)
         | 
| 30 | 
            +
                        self.ddup.add_chain_node(node)
         | 
| 31 31 | 
             
                      end.compact
         | 
| 32 32 | 
             
                    end
         | 
| 33 33 |  | 
| 34 34 | 
             
                    def closed?
         | 
| 35 35 | 
             
                      !@converter_chain.empty? &&
         | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 36 | 
            +
                          @converter_chain.first[:input].to_sym == @source_format &&
         | 
| 37 | 
            +
                          @converter_chain.last[:output].to_sym == @target_format
         | 
| 38 38 | 
             
                    end
         | 
| 39 39 |  | 
| 40 40 | 
             
                    def valid?
         | 
| @@ -49,76 +49,68 @@ module Libis | |
| 49 49 | 
             
                      @converter_chain.size
         | 
| 50 50 | 
             
                    end
         | 
| 51 51 |  | 
| 52 | 
            -
                     | 
| 52 | 
            +
                    alias_method :length, :size
         | 
| 53 53 |  | 
| 54 54 | 
             
                    def to_s
         | 
| 55 | 
            -
                       | 
| 56 | 
            -
             | 
| 55 | 
            +
                      "#{@source_format}->-#{@converter_chain.map do |node|
         | 
| 56 | 
            +
                        "#{node[:converter].name.gsub(/^.*::/, '')}#{node[:operations].empty? ? '' :
         | 
| 57 | 
            +
                            "(#{node[:operations].each do |operation|
         | 
| 58 | 
            +
                              "#{operation[:method]}:#{operation[:argument]}"
         | 
| 59 | 
            +
                            end.join(',')})"}->-#{node[:output]}"
         | 
| 60 | 
            +
                      end.join('->-')}"
         | 
| 57 61 | 
             
                    end
         | 
| 58 62 |  | 
| 59 63 | 
             
                    def convert(src_file, target_file)
         | 
| 64 | 
            +
             | 
| 60 65 | 
             
                      unless valid?
         | 
| 61 66 | 
             
                        error 'Converter chain is not valid'
         | 
| 62 67 | 
             
                        return nil
         | 
| 63 68 | 
             
                      end
         | 
| 64 69 |  | 
| 65 70 | 
             
                      temp_files = []
         | 
| 66 | 
            -
                      xtra_files = []
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                      result = { commands: [] }
         | 
| 69 71 |  | 
| 70 72 | 
             
                      # noinspection RubyParenthesesAroundConditionInspection
         | 
| 71 | 
            -
                       | 
| 73 | 
            +
                      result = @converter_chain.each_with_index do |node, i|
         | 
| 74 | 
            +
             | 
| 72 75 | 
             
                        target_type = node[:output]
         | 
| 73 76 | 
             
                        converter_class = node[:converter]
         | 
| 74 77 | 
             
                        converter = converter_class.new
         | 
| 75 78 |  | 
| 76 | 
            -
                        node[:operations] | 
| 79 | 
            +
                        node[:operations].each do |operation|
         | 
| 77 80 | 
             
                          converter.send operation[:method], operation[:argument]
         | 
| 78 | 
            -
                        end
         | 
| 81 | 
            +
                        end if node[:operations]
         | 
| 79 82 |  | 
| 80 83 | 
             
                        target = target_file
         | 
| 81 84 |  | 
| 82 85 | 
             
                        if i < size - 1
         | 
| 83 | 
            -
                          target += ".temp.#{ | 
| 84 | 
            -
                          target += ".#{ | 
| 86 | 
            +
                          target += ".temp.#{Libis::Format::Library.get_field(target_type, :extensions).first}"
         | 
| 87 | 
            +
                          target += ".#{Libis::Format::Library.get_field(target_type, :extensions).first}" while File.exist? target
         | 
| 85 88 | 
             
                          temp_files << target
         | 
| 86 89 | 
             
                        end
         | 
| 87 90 |  | 
| 88 91 | 
             
                        FileUtils.mkdir_p File.dirname(target)
         | 
| 89 92 |  | 
| 90 | 
            -
                         | 
| 93 | 
            +
                        src_file = converter.convert(src_file, target, target_type)
         | 
| 91 94 |  | 
| 92 | 
            -
                        src_file = r[:files].first
         | 
| 93 | 
            -
                        xtra_files += r[:files][1..]
         | 
| 94 95 | 
             
                        break :failed unless src_file
         | 
| 95 96 |  | 
| 96 | 
            -
                        result[:commands] << r.merge(converter: converter_class.name)
         | 
| 97 | 
            -
             | 
| 98 | 
            -
                        :success
         | 
| 99 97 | 
             
                      end
         | 
| 100 98 |  | 
| 101 | 
            -
                      result[:files] = [src_file] + xtra_files
         | 
| 102 | 
            -
             | 
| 103 99 | 
             
                      temp_files.each do |f|
         | 
| 104 100 | 
             
                        FileUtils.rm(f, force: true)
         | 
| 105 101 | 
             
                      end
         | 
| 106 102 |  | 
| 107 | 
            -
                       | 
| 103 | 
            +
                      result == :failed ? nil : target_file
         | 
| 104 | 
            +
             | 
| 108 105 | 
             
                    end
         | 
| 109 106 |  | 
| 110 107 | 
             
                    def valid_chain_nodes(converter)
         | 
| 111 | 
            -
                      source_format =  | 
| 112 | 
            -
                        @converter_chain.last[:output]
         | 
| 113 | 
            -
                      rescue StandardError
         | 
| 114 | 
            -
                        @source_format
         | 
| 115 | 
            -
                      end
         | 
| 108 | 
            +
                      source_format = @converter_chain.last[:output] rescue @source_format
         | 
| 116 109 | 
             
                      nodes = []
         | 
| 117 110 | 
             
                      if converter.input_types.include? source_format
         | 
| 118 111 | 
             
                        converter.output_types(source_format).each do |format|
         | 
| 119 | 
            -
                          node = { converter | 
| 112 | 
            +
                          node = {converter: converter, input: source_format, output: format}
         | 
| 120 113 | 
             
                          next if node_exists?(node)
         | 
| 121 | 
            -
             | 
| 122 114 | 
             
                          nodes << node
         | 
| 123 115 | 
             
                        end
         | 
| 124 116 | 
             
                      end
         | 
| @@ -133,7 +125,6 @@ module Libis | |
| 133 125 | 
             
                      return nil unless node[:output] && node[:converter].output_types(source_format).include?(node[:output])
         | 
| 134 126 | 
             
                      return nil unless node[:converter].input_types.include? source_format
         | 
| 135 127 | 
             
                      return nil if node_exists?(node)
         | 
| 136 | 
            -
             | 
| 137 128 | 
             
                      @converter_chain << node
         | 
| 138 129 | 
             
                      # debug "Chain: #{self}"
         | 
| 139 130 | 
             
                      self
         | 
| @@ -142,16 +133,15 @@ module Libis | |
| 142 133 | 
             
                    def apply_operations
         | 
| 143 134 | 
             
                      temp_chain = @converter_chain.reverse.ddup
         | 
| 144 135 | 
             
                      applied = true
         | 
| 145 | 
            -
                      operations = @operations | 
| 136 | 
            +
                      operations = @operations && @operations.ddup || {}
         | 
| 146 137 | 
             
                      while (operation = operations.shift)
         | 
| 147 138 | 
             
                        method = operation.first.to_s.to_sym
         | 
| 148 | 
            -
                        applied &&= temp_chain.each do |node|
         | 
| 139 | 
            +
                        applied &&= :found == temp_chain.each do |node|
         | 
| 149 140 | 
             
                          next unless node[:converter].instance_methods.include?(method)
         | 
| 150 | 
            -
             | 
| 151 141 | 
             
                          node[:operations] ||= []
         | 
| 152 | 
            -
                          node[:operations] << { method | 
| 142 | 
            +
                          node[:operations] << {method: method, argument: operation.last}
         | 
| 153 143 | 
             
                          break :found
         | 
| 154 | 
            -
                        end | 
| 144 | 
            +
                        end
         | 
| 155 145 | 
             
                      end
         | 
| 156 146 | 
             
                      if applied && operations.empty?
         | 
| 157 147 | 
             
                        @converter_chain = temp_chain.reverse
         | 
| @@ -161,27 +151,17 @@ module Libis | |
| 161 151 | 
             
                      false
         | 
| 162 152 | 
             
                    end
         | 
| 163 153 |  | 
| 164 | 
            -
                    private
         | 
| 165 154 |  | 
| 166 | 
            -
                     | 
| 167 | 
            -
                      result = node[:converter].name.gsub(/^.*::/, '').to_s
         | 
| 168 | 
            -
                      unless node[:operations].empty?
         | 
| 169 | 
            -
                        result << '('
         | 
| 170 | 
            -
                        result << node[:operations].map do |operation|
         | 
| 171 | 
            -
                          "#{operation[:method]}:#{operation[:argument]}"
         | 
| 172 | 
            -
                        end.join(',')
         | 
| 173 | 
            -
                        result << ')'
         | 
| 174 | 
            -
                      end
         | 
| 175 | 
            -
                      result << '->-'
         | 
| 176 | 
            -
                      result << node[:output].to_s
         | 
| 177 | 
            -
                    end
         | 
| 155 | 
            +
                    private
         | 
| 178 156 |  | 
| 179 157 | 
             
                    def node_exists?(node)
         | 
| 180 158 | 
             
                      @converter_chain.detect do |n|
         | 
| 181 159 | 
             
                        n[:converter] == node[:converter] && n[:input] == node[:input] && n[:output] == node[:output]
         | 
| 182 160 | 
             
                      end
         | 
| 183 161 | 
             
                    end
         | 
| 162 | 
            +
             | 
| 184 163 | 
             
                  end
         | 
| 164 | 
            +
             | 
| 185 165 | 
             
                end
         | 
| 186 166 | 
             
              end
         | 
| 187 167 | 
             
            end
         | 
| @@ -1,5 +1,3 @@ | |
| 1 | 
            -
            # frozen_string_literal: true
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            require 'nokogiri'
         | 
| 4 2 |  | 
| 5 3 | 
             
            require_relative 'base'
         | 
| @@ -9,14 +7,15 @@ require 'libis/format/tool/fop_pdf' | |
| 9 7 | 
             
            module Libis
         | 
| 10 8 | 
             
              module Format
         | 
| 11 9 | 
             
                module Converter
         | 
| 10 | 
            +
             | 
| 12 11 | 
             
                  class FopPdfConverter < Libis::Format::Converter::Base
         | 
| 12 | 
            +
             | 
| 13 13 | 
             
                    def self.input_types
         | 
| 14 14 | 
             
                      [:XML]
         | 
| 15 15 | 
             
                    end
         | 
| 16 16 |  | 
| 17 17 | 
             
                    def self.output_types(format = nil)
         | 
| 18 | 
            -
                      return []  | 
| 19 | 
            -
             | 
| 18 | 
            +
                      return [] unless input_types.include?(format) if format
         | 
| 20 19 | 
             
                      [:PDF]
         | 
| 21 20 | 
             
                    end
         | 
| 22 21 |  | 
| @@ -31,8 +30,13 @@ module Libis | |
| 31 30 | 
             
                      FileUtils.mkpath(File.dirname(target))
         | 
| 32 31 |  | 
| 33 32 | 
             
                      Libis::Format::Tool::FopPdf.run(source, target)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                      target
         | 
| 35 | 
            +
             | 
| 34 36 | 
             
                    end
         | 
| 37 | 
            +
             | 
| 35 38 | 
             
                  end
         | 
| 39 | 
            +
             | 
| 36 40 | 
             
                end
         | 
| 37 41 | 
             
              end
         | 
| 38 42 | 
             
            end
         | 
| @@ -0,0 +1,82 @@ | |
| 1 | 
            +
            # encoding: utf-8
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require_relative 'base'
         | 
| 4 | 
            +
            require 'libis/format/identifier'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require 'mini_magick'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            MiniMagick.logger.level = ::Logger::UNKNOWN
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            MiniMagick.configure do |config|
         | 
| 11 | 
            +
              # config.cli = :graphicsmagick
         | 
| 12 | 
            +
              config.validate_on_create = false
         | 
| 13 | 
            +
              config.validate_on_write = false
         | 
| 14 | 
            +
              config.whiny = false
         | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            module Libis
         | 
| 18 | 
            +
              module Format
         | 
| 19 | 
            +
                module Converter
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  # noinspection RubyTooManyInstanceVariablesInspection,DuplicatedCode
         | 
| 22 | 
            +
                  class ImageAssembler < Libis::Format::Converter::Base
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                    def self.input_types
         | 
| 25 | 
            +
                      [:TIFF, :JPG, :PNG, :BMP, :GIF, :PDF, :JP2]
         | 
| 26 | 
            +
                    end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                    def self.output_types(format = nil)
         | 
| 29 | 
            +
                      return [] unless input_types.include?(format) if format
         | 
| 30 | 
            +
                      [:PDF, :TIFF, :GIF, :PBM, :PGM, :PPM]
         | 
| 31 | 
            +
                    end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                    def self.category
         | 
| 34 | 
            +
                      :assembler
         | 
| 35 | 
            +
                    end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                    def image_assemble(_)
         | 
| 38 | 
            +
                      #force usage of this converter
         | 
| 39 | 
            +
                    end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                    def quiet(v)
         | 
| 42 | 
            +
                      @quiet = !!v
         | 
| 43 | 
            +
                    end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                    def convert(source, target, format, opts = {})
         | 
| 46 | 
            +
                      super
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                      FileUtils.mkpath(File.dirname(target))
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                      if source.is_a? Array
         | 
| 51 | 
            +
                        assemble(source, target, format)
         | 
| 52 | 
            +
                      elsif File.directory?(source)
         | 
| 53 | 
            +
                        source_list = Dir[File.join(source, '**', '*')].reject {|p| File.directory? p}
         | 
| 54 | 
            +
                        assemble(source_list, target, format)
         | 
| 55 | 
            +
                      else
         | 
| 56 | 
            +
                        image = MiniMagick::Image.open(source) {|b| b.quiet}
         | 
| 57 | 
            +
                        if image.pages.size > 1
         | 
| 58 | 
            +
                          assemble(image.pages.map {|page| page.path}, target, format)
         | 
| 59 | 
            +
                        else
         | 
| 60 | 
            +
                          assemble([source], target, format)
         | 
| 61 | 
            +
                        end
         | 
| 62 | 
            +
                      end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                      target
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                    end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                    private
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                    def assemble(sources, target, format)
         | 
| 71 | 
            +
                      MiniMagick::Tool::Convert.new do |b|
         | 
| 72 | 
            +
                        sources.each {|source| b << source}
         | 
| 73 | 
            +
                        convert.format(format)
         | 
| 74 | 
            +
                        b << target
         | 
| 75 | 
            +
                      end
         | 
| 76 | 
            +
                    end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
            end
         |