libis-format 1.0.2 → 1.0.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21f527308cef3b9865c24c956f5a76cf67973400
4
- data.tar.gz: 19c867aef5d28da24a3354025b11fc718b885a7f
3
+ metadata.gz: a96a71d90952cf5d8be62d9b82ac6fc22c4f080a
4
+ data.tar.gz: 79bda271ae8b628e96c7a3d19b65884a3fe1eee0
5
5
  SHA512:
6
- metadata.gz: 3af22a3b301bc89a0839215a96a571d729478c61f3d414ee144e7f011d16443f4e604efd8f6afb0b40d2dd02dc77ca65878dfba7b29a6f4bc186beec8373b437
7
- data.tar.gz: 81bebc7836625f251e9365100bfdb4a13d3ec4424a26a536521bb1776a11d96472645af1e360077ff64d5ef4e6f08671e0c87330d8fa32f5230b390509a016ce
6
+ metadata.gz: 303f4353c79d988110668ddc1c4bb5867d4e644b30d1a6f60e24da13a2f8f99703ab1b8f5afba73ed11aee0cfdd8bad6e759e857350a97d734d021fcfca31c32
7
+ data.tar.gz: 612a76df7a9907900aa292e68065f3c13d1362edffa01cbf2425edb8c8f41040d17871680ad7bab430a49790da96bba323ce2706ab13dfa39494ca8795e7d639
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
5
+
6
+ require 'libis/format/command_line'
7
+
8
+ Libis::Format::CommandLine.start(ARGV)
@@ -4,6 +4,7 @@ module Libis
4
4
  module Format
5
5
  autoload :Config, 'libis/format/config'
6
6
  autoload :TypeDatabase, 'libis/format/type_database'
7
+ autoload :TypeDatabaseImpl, 'libis/format/type_database_impl'
7
8
  autoload :Identifier, 'libis/format/identifier'
8
9
 
9
10
  autoload :Tool, 'libis/format/tool'
@@ -0,0 +1,310 @@
1
+ require 'awesome_print'
2
+ require 'libis-format'
3
+ require 'libis-tools'
4
+ require 'libis/tools/extend/hash'
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require 'yaml'
8
+
9
+ require 'libis/format/converter/image_converter'
10
+
11
+ require_relative 'sub_command'
12
+
13
+ module Libis
14
+ module Format
15
+ module Cli
16
+ class Convert < SubCommand
17
+
18
+ no_commands do
19
+ def self.description(field)
20
+ "#{STRING_CONFIG[field]}." + (DEFAULT_CONFIG[field].nil? ? '' : " default: #{DEFAULT_CONFIG[field]}")
21
+ end
22
+ end
23
+
24
+ DEFAULT_CONFIG = {
25
+ scale: '100%',
26
+ resize: '100%',
27
+ wm_tiles: 4,
28
+ wm_resize: 1.0,
29
+ wm_gap: 0.2,
30
+ wm_rotation: 30,
31
+ wm_opacity: 0.1,
32
+ wm_gravity: 'center',
33
+ wm_composition: 'modulate'
34
+ }
35
+
36
+ STRING_CONFIG = {
37
+ page: 'Page number to select for multipage documents',
38
+ quiet: 'suppress all warning messages. Error messages are still reported',
39
+ scale: 'minify / magnify the image with pixel block averaging and pixel replication, respectively',
40
+ resize: 'Resize the image',
41
+ resample: 'Resize the image so that its rendered size remains the same as the original at the specified target resolution',
42
+ flatten: 'Create a canvas the size of the first images virtual canvas using the current -background color, and -compose each image in turn onto that canvas. Images falling outside that canvas is clipped',
43
+ delete_date: 'Remove modified date and created date metadata from the target image',
44
+ colorspace: 'Set the image colorspace',
45
+ profile: 'Specify color profile used for the image',
46
+ wm_text: 'Create watermark with given text',
47
+ wm_file: 'Create watermark from given file',
48
+ wm_tiles: 'Number of tiles of the watermark to distribute over the image. 0: no tiling, 1: watermark image scaled to fit image, n>1: at least n tiles horizontally/vertically, n<0: tile without recaling',
49
+ wm_resize: 'Resize the watermark image (fraction 0.0 - 1.0)',
50
+ wm_gap: 'Leave n % of whitespace between the watermark images. Similar effect can be achieved with wm_resize',
51
+ wm_rotation: 'Rotate the watermark text n degrees counterclockwise (0-360)',
52
+ wm_opacity: 'Opacity of the watermark (fraction 0.0 - 1.0)',
53
+ wm_gravity: 'Center point of the watermark overlay',
54
+ wm_composition: 'Set the type of image composition'
55
+ }
56
+
57
+ desc 'auto SOURCE TARGET [options]', 'Convert SOURCE file to TARGET file using auto algorithm'
58
+ long_desc <<-DESC
59
+
60
+ 'auto SOURCE TARGET [options]' will convert a file according to the best conversion chain algorithm.
61
+
62
+ A source file name and target file name should be supplied. The source file should exist and be readable.
63
+ The target file should be writable, but should not exist.
64
+
65
+ Optionally an options file name can be added to the command line. The options file should be a valid YAML
66
+ file that contains either a Hash or an Array of Hashes. The content should contain the required methods and
67
+ arguments that any of the targetted converters support.
68
+
69
+ The source file's format will be identified by the Libis::Format::Identifier and the target file's format
70
+ will be derived from the file's extension. The Libis::Format::TypeDatabase is used to relate extensions
71
+ with formats.
72
+
73
+ DESC
74
+
75
+ method_option :options, aliases: '-o', desc: 'Options file'
76
+
77
+ def auto(source_file, target_file)
78
+ options_file = options[:options]
79
+ opts = check_input(source_file, target_file, options_file)
80
+ output, converter = do_convert(source_file, target_file, opts)
81
+ prompt.ok "Output file '#{output}' created with converter #{converter}."
82
+ end
83
+
84
+ desc 'image SOURCE TARGET [options]', 'Convert SOURCE image to TARGET image using ImageConverter'
85
+ long_desc <<-DESC
86
+
87
+ 'image SOURCE TARGET [options]' will convert a SOURCE image to TARGET image using the ImageConverter.
88
+
89
+ A source file name and target file name should be supplied. The source file should exist and be readable.
90
+ The target file should be writable, but should not exist.
91
+
92
+ The target file's format will be derived from the file's extension. The Libis::Format::TypeDatabase is used
93
+ to relate extensions with formats.
94
+
95
+ DESC
96
+
97
+ method_option :page, type: :numeric, aliases: '-p', desc: description(:page)
98
+ method_option :quiet, type: :boolean, aliases: '-q', desc: description(:quiet)
99
+ method_option :scale, type: :numeric, aliases: '-c', desc: description(:scale)
100
+ method_option :resize, type: :numeric, aliases: '-r', desc: description(:resize)
101
+ method_option :resample, type: :numeric, aliases: '-m', desc: description(:resample)
102
+ method_option :flatten, type: :boolean, aliases: '-f', desc: description(:flatten)
103
+ method_option :delete_date, type: :boolean, aliases: '-dd', desc: description(:delete_date)
104
+ method_option :colorspace, aliases: '-cs', desc: description(:colorspace)
105
+ method_option :profile, aliases: '-prof', desc: description(:profile)
106
+ method_option :wm_text, desc: description(:wm_text)
107
+ method_option :wm_file, desc: description(:wm_file)
108
+ method_option :wm_tiles, type: :numeric, desc: description(:wm_tiles)
109
+ method_option :wm_resize, type: :numeric, desc: description(:wm_resize)
110
+ method_option :wm_gap, type: :numeric, desc: description(:wm_gap)
111
+ method_option :wm_rotation, type: :numeric, desc: description(:wm_rotation)
112
+ method_option :wm_opacity, type: :numeric, desc: description(:wm_opacity)
113
+ method_option :wm_gravity, desc: description(:wm_gravity)
114
+ method_option :wm_composition, desc: description(:wm_composition)
115
+
116
+ def image(source_file, target_file)
117
+ check_input(source_file, target_file)
118
+ convert_image(source_file, target_file)
119
+ prompt.ok "Output file '#{target_file}' created with image converter."
120
+ end
121
+
122
+ protected
123
+
124
+ def do_convert(source_file, target_file, opts)
125
+ format_info = format_identifier(source_file)
126
+ src_mime = format_info[:mimetype]
127
+ source_format = format_info[:TYPE]
128
+ unless source_format
129
+ prompt.error "File item %s format (#{src_mime}) is not supported."
130
+ exit
131
+ end
132
+ target_format = get_format(target_file)
133
+ converterlist = []
134
+ temp_files = []
135
+ opts.each do |o|
136
+ o = o.dup
137
+ tgt_format = o.delete(:target_format) || target_format
138
+ tgt_file = tempname(source_file, tgt_format)
139
+ temp_files << tgt_file
140
+ begin
141
+ source_file, converter = convert_file(source_file, tgt_file, source_format, tgt_format, o)
142
+ rescue Exception => e
143
+ prompt.error "File conversion of '%s' from '%s' to '%s' failed: %s @ %s" %
144
+ [source_file, source_format, tgt_format, e.message, e.backtrace.first]
145
+ exit
146
+ end
147
+ source_format = tgt_format
148
+ converterlist << converter
149
+ end
150
+ converter = converterlist.join(' + ')
151
+ if target_file
152
+ FileUtils.mkpath(File.dirname(target_file))
153
+ FileUtils.copy(source_file, target_file)
154
+ else
155
+ target_file = temp_files.pop
156
+ end
157
+ temp_files.each {|tmp_file| FileUtils.rm_f tmp_file}
158
+ [target_file, converter]
159
+ end
160
+
161
+ def convert_file(src_file, tgt_file, src_format, tgt_format, opts)
162
+ converter = Libis::Format::Converter::Repository.get_converter_chain(src_format, tgt_format, opts)
163
+
164
+ unless converter
165
+ prompt.error "Could not find converter for #{src_format} -> #{tgt_format} with #{opts}"
166
+ exit
167
+ end
168
+
169
+ converter_name = converter.to_s
170
+ prompt.say 'Converting file %s to %s with %s ' % [src_file, tgt_file, converter_name]
171
+ converted = converter.convert(src_file, tgt_file)
172
+
173
+ unless converted && converted == tgt_file
174
+ prompt.error 'File conversion failed (%s).', converter_name
175
+ return [nil, converter_name]
176
+ end
177
+
178
+ [tgt_file, converter_name]
179
+ end
180
+
181
+ def convert_image(source_file, target_file)
182
+ target_format = get_format(target_file)
183
+ converter = Libis::Format::Converter::ImageConverter.new
184
+ converter.page options[:page] if options[:page]
185
+ converter.quiet options[:quiet] if options[:quiet]
186
+ converter.scale options[:scale] if options[:scale]
187
+ converter.resize options[:resize] if options[:resize]
188
+ converter.resample options[:resample] if options[:resample]
189
+ converter.flatten if options[:flatten]
190
+ converter.delete_date if options[:delete_date]
191
+ converter.colorspace options[:colorspace] if options[:colorspace]
192
+ converter.profile options[:profile] if options[:profile]
193
+ if options[:wm_text] || options[:wm_file]
194
+ wm_options = {}
195
+ wm_options[:text] = options[:wm_text] if options[:wm_text]
196
+ wm_options[:file] = options[:wm_file] if options[:wm_file]
197
+ wm_options[:tiles] = options[:wm_tiles] if options[:wm_tiles]
198
+ wm_options[:resize] = options[:wm_resize] if options[:wm_resize]
199
+ wm_options[:gap] = options[:wm_gap] if options[:wm_gap]
200
+ wm_options[:rotation] = options[:wm_rotation] if options[:wm_rotation]
201
+ wm_options[:opacity] = options[:wm_opacity] if options[:wm_opacity]
202
+ wm_options[:gravity] = options[:wm_gravity] if options[:wm_gravity]
203
+ wm_options[:composition] = options[:wm_composition] if options[:wm_composition]
204
+ converter.watermark(wm_options)
205
+ end
206
+ converter.convert source_file, target_file, target_format
207
+ end
208
+
209
+ private
210
+
211
+ def check_input(source_file, target_file, options_file = nil)
212
+ # Check if source file exists and can be read
213
+ unless source_file && File.exist?(source_file) && File.readable?(source_file)
214
+ prompt.error "Fatal error trying to access source file '#{source_file}'."
215
+ exit
216
+ end
217
+ # Check if target file argument is supplied
218
+ unless target_file
219
+ prompt.error "Fatal error: no target file name supplied."
220
+ exit
221
+ end
222
+ # Check if target file directory can be created
223
+ begin
224
+ FileUtils.mkdir_p(File.dirname(target_file))
225
+ rescue SystemCallError => e
226
+ prompt.error "Fatal error trying to create folder for target file: #{e.message}"
227
+ exit
228
+ end
229
+
230
+ return [{}] unless options_file
231
+
232
+ # Check if options file exists and can be read
233
+ unless File.exist?(options_file) && File.readable?(options_file)
234
+ prompt.error "Fatal error trying to access options file '#{options_file}'."
235
+ exit
236
+ end
237
+
238
+ begin
239
+ opts = ::YAML.load_file(options_file)
240
+ opts = case opts
241
+ when Hash
242
+ [opts]
243
+ when Array
244
+ opts
245
+ when NilClass
246
+ [{}]
247
+ else
248
+ prompt.error "Options file contents should be a Hash or an Array of Hashes."
249
+ exit
250
+ end
251
+ opts.each {|h| h.key_strings_to_symbols!(recursive: true)}
252
+ opts
253
+ rescue Exception => e
254
+ prompt.error "Fatal error trying to parse options file: #{e.message}"
255
+ exit
256
+ end
257
+
258
+ end
259
+
260
+ def tempname(source_file, target_format)
261
+ # noinspection RubyResolve
262
+ Dir::Tmpname.create(
263
+ [File.basename(source_file, '.*'), ".#{extname(target_format)}"]
264
+ ) {}
265
+ end
266
+
267
+ def extname(format)
268
+ Libis::Format::TypeDatabase.type_extentions(format).first
269
+ end
270
+
271
+ def get_format(file_name)
272
+ Libis::Format::TypeDatabase.ext_types(File.extname(file_name)).first
273
+ end
274
+
275
+ def format_identifier(file)
276
+ prompt.say "Identifying format of file '#{file}'"
277
+ result = Libis::Format::Identifier.get(file) || {}
278
+ process_messages(result)
279
+ format = result[:formats][file]
280
+ unless format[:mimetype]
281
+ prompt.warn "Could not determine MIME type. Using default 'application/octet-stream'."
282
+ result[:puid] ||= 'fmt/unknown'
283
+ end
284
+ prompt.say "#{file} format: #{format[:GROUP]}, #{format[:TYPE]} (puid: #{format[:puid]}) mimetype: #{format[:mimetype]}"
285
+ format
286
+ end
287
+
288
+ def process_messages(format_result)
289
+ format_result[:messages].each do |msg|
290
+ case msg[0]
291
+ when :debug
292
+ prompt.say msg[1]
293
+ when :info
294
+ prompt.say msg[1]
295
+ when :warn
296
+ prompt.warn msg[1]
297
+ when :error
298
+ prompt.error msg[1]
299
+ when :fatal
300
+ prompt.error msg[1]
301
+ else
302
+ prompt.say "#{msg[0]}: #{msg[1]}"
303
+ end
304
+ end
305
+ end
306
+
307
+ end
308
+ end
309
+ end
310
+ end
@@ -0,0 +1,77 @@
1
+ require 'awesome_print'
2
+ require 'libis-format'
3
+ require 'libis-tools'
4
+
5
+ require_relative 'sub_command'
6
+
7
+ module Libis
8
+ module Format
9
+ module Cli
10
+ class Format < SubCommand
11
+
12
+ no_commands do
13
+ def self.description(field)
14
+ "#{STRING_CONFIG[field]}." + (DEFAULT_CONFIG[field].nil? ? '' : " default: #{DEFAULT_CONFIG[field]}")
15
+ end
16
+ end
17
+
18
+ DEFAULT_CONFIG = {
19
+ droid: true,
20
+ fido: true,
21
+ file: true,
22
+ xml_validation: true
23
+ }
24
+
25
+ STRING_CONFIG = {
26
+ droid: 'Use Droid to identify the format',
27
+ fido: 'Use Fido to identify the format',
28
+ file: 'Use File to identify the format',
29
+ xml_validation: 'When XML file found, validate the file against known XML schemas',
30
+ }
31
+
32
+ desc 'identify FILE [options]', 'Identify the FILE using a combination of the tools.'
33
+ long_desc <<-DESC
34
+
35
+ 'identify FILE [options]' will idnetify a file using a combination of tools.
36
+
37
+ The file will be identified by each of the selected tools in turn and the format with best score will be
38
+ selected to give the final result. The score is determined by the identification method and will be lowered if
39
+ a known weak format (e.g. zip file) is detected.
40
+
41
+ The tool will display as much information about the format as possible, including the format candidates that
42
+ were not selected.
43
+
44
+ DESC
45
+
46
+ method_option :droid, default: DEFAULT_CONFIG[:droid], type: :boolean, desc: STRING_CONFIG[:droid]
47
+ method_option :fido, default: DEFAULT_CONFIG[:fido], type: :boolean, desc: STRING_CONFIG[:fido]
48
+ method_option :file, default: DEFAULT_CONFIG[:file], type: :boolean, desc: STRING_CONFIG[:file]
49
+ method_option :xml_validation, default: DEFAULT_CONFIG[:xml_validation], type: :boolean, desc: STRING_CONFIG[:xml_validation]
50
+
51
+ def identify(source_file)
52
+ ::Libis::Tools::Config.logger.level = :WARN
53
+ opts = options.inject({}) { |h, x| h[x.first.to_sym] = x.last; h}
54
+ opts[:keep_output] = true
55
+ result = ::Libis::Format::Identifier.get source_file, opts
56
+ puts '--- messages ---'
57
+ result[:messages].each do |message|
58
+ puts "#{message[0]} : #{message[1]}"
59
+ end
60
+
61
+ puts '--- formats ---'
62
+ result[:formats].each do |file, info|
63
+ puts "#{file}:"
64
+ ap info
65
+ end
66
+
67
+ puts '--- tool results ---'
68
+ result[:output].each do |file, info|
69
+ puts "#{file}:"
70
+ ap info
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,87 @@
1
+ require 'tty-prompt'
2
+ require 'pastel'
3
+
4
+ module Libis
5
+ module Format
6
+ module Cli
7
+ module PromptHelper
8
+
9
+ attr_reader :prompt, :pastel
10
+
11
+ def initialize(*args)
12
+ @prompt = TTY::Prompt.new
13
+ @pastel = Pastel.new
14
+ super
15
+ end
16
+
17
+ protected
18
+
19
+ private
20
+
21
+ def index_of(list, value)
22
+ i = list.index(value)
23
+ i += 1 if i
24
+ i || 1
25
+ end
26
+
27
+ def ask(question, bool: false, enum: nil, default: nil, mask: false)
28
+ cmd, args, opts = :ask, [question], {}
29
+ if enum
30
+ cmd = :select
31
+ args << enum
32
+ # Change default to its index in the enum
33
+ default = index_of(enum, default)
34
+ end
35
+ cmd = :mask if mask
36
+ opts[:default] = default if default
37
+ cmd = (opts[:default] ? :yes? : :no?) if bool
38
+ prompt.send(cmd, *args, opts)
39
+ end
40
+
41
+ def tree_select(path, question: nil, file: false, page_size: 22, filter: true, cycle: false, create: false,
42
+ default_choices: nil)
43
+ path = Pathname.new(path) unless path.is_a? Pathname
44
+
45
+ return path unless path.exist?
46
+ path = path.realpath
47
+
48
+ dirs = path.children.select(&:directory?).sort
49
+ files = file ? path.children.select(&:file?).sort : []
50
+
51
+ choices = []
52
+ choices << {name: "Folder: #{path}", value: path, disabled: file ? '' : false}
53
+ choices += default_choices if default_choices
54
+ choices << {name: '-- new directory --', value: -> do
55
+ new_name = prompt.ask('new directory name:', modify: :trim, required: true)
56
+ new_path = path + new_name
57
+ FileUtils.mkdir(new_path.to_path)
58
+ new_path
59
+ end
60
+ } if create
61
+
62
+ choices << {name: "-- new file --", value: -> do
63
+ new_name = prompt.ask('new file name:', modify: :trim, required: true)
64
+ path + new_name
65
+ end
66
+ } if file && create
67
+
68
+ choices << {name: '[..]', value: path.parent}
69
+
70
+ dirs.each {|d| choices << {name: "[#{d.basename}]", value: d}}
71
+ files.each {|f| choices << {name: f.basename.to_path, value: f}}
72
+
73
+ question ||= "Select #{'file or ' if files}directory"
74
+ selection = prompt.select question, choices,
75
+ per_page: page_size, filter: filter, cycle: cycle, default: file ? 2 : 1
76
+
77
+ return selection unless selection.is_a? Pathname
78
+ return selection.to_path if selection == path || selection.file?
79
+
80
+ tree_select selection, question: question, file: file, page_size: page_size, filter: filter,
81
+ cycle: cycle, create: create, default_choices: default_choices
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,22 @@
1
+ require 'thor'
2
+ require_relative 'prompt_helper'
3
+
4
+ module Libis
5
+ module Format
6
+ module Cli
7
+ class SubCommand < Thor
8
+
9
+ include PromptHelper
10
+
11
+ def self.banner(command, namespace = nil, subcommand = false)
12
+ "#{basename} #{subcommand_prefix} #{command.usage}"
13
+ end
14
+
15
+ def self.subcommand_prefix
16
+ self.name.gsub(%r{.*::}, '').gsub(%r{^[A-Z]}) { |match| match[0].downcase }.gsub(%r{[A-Z]}) { |match| "-#{match[0].downcase}" }
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ require 'thor'
2
+ require 'tty-prompt'
3
+ require 'tty-config'
4
+
5
+ require 'libis/format/cli/convert'
6
+ require 'libis/format/cli/format'
7
+
8
+ module Libis
9
+ module Format
10
+
11
+ class CommandLine < Thor
12
+
13
+ def self.exit_on_failure?
14
+ true
15
+ end
16
+
17
+ desc 'convert', 'perform format conversion on a given file'
18
+ subcommand 'convert', Cli::Convert
19
+
20
+ desc 'format', 'perform format identification on a given file or directory'
21
+ subcommand 'format', Cli::Format
22
+ end
23
+
24
+ end
25
+ end
@@ -6,18 +6,20 @@ require 'libis/format/identifier'
6
6
  require 'mini_magick'
7
7
  require 'fileutils'
8
8
 
9
- MiniMagick.logger.level = ::Logger::ERROR
9
+ MiniMagick.logger.level = ::Logger::UNKNOWN
10
10
 
11
11
  MiniMagick.configure do |config|
12
12
  # config.cli = :graphicsmagick
13
13
  config.validate_on_create = false
14
14
  config.validate_on_write = false
15
+ config.whiny = false
15
16
  end
16
17
 
17
18
  module Libis
18
19
  module Format
19
20
  module Converter
20
21
 
22
+ # noinspection RubyTooManyInstanceVariablesInspection
21
23
  class ImageConverter < Libis::Format::Converter::Base
22
24
 
23
25
  def self.input_types
@@ -43,7 +45,7 @@ module Libis
43
45
  end
44
46
 
45
47
  def quiet(v)
46
- @flags[:quiet] = !!v
48
+ @quiet = !!v
47
49
  end
48
50
 
49
51
  def page(nr)
@@ -70,16 +72,16 @@ module Libis
70
72
  @options[:resample] = value
71
73
  end
72
74
 
73
- def flatten
74
- @flags[:flatten] = true
75
+ def flatten(value = true)
76
+ @options[:flatten] = !!value
75
77
  end
76
78
 
77
79
  def colorspace(value)
78
80
  @options[:colorspace] = value
79
81
  end
80
82
 
81
- def delete_date
82
- @delete_date = true
83
+ def delete_date(value = true)
84
+ @delete_date = !!value
83
85
  end
84
86
 
85
87
  def profile(icc)
@@ -92,9 +94,16 @@ module Libis
92
94
  # - file: watermark image to use
93
95
  # - text: text to create a watermark from
94
96
  # - rotation: rotation of the watermark text (counter clockwise in degrees; integer number) - default 30
95
- # - size: size of the watermark (integer > 0, 1/n of image size) - default 4
96
- # - opacity: opacity of the watermark (fraction 0.0 - 1.0) - default 0.3
97
+ # - tiles: number of tiles of the watermark - default 4
98
+ # - 0: no tiling, so only 1 watermark will be placed with the original size
99
+ # - 1: 1 tile, so the watermark will be scaled up to fill the image
100
+ # - n > 1: minimum n tiles in both directions
101
+ # - n < 0: tile without scaling the watermark
102
+ # - size: same as tiles - for backwards compatibility
103
+ # - resize: fraction 0.0 - 1.0
97
104
  # - gap: size of the gap between watermark instances. Fractions as percentage of widht/height. - default 0.2
105
+ # - opacity: opacity of the watermark (fraction 0.0 - 1.0) - default 0.1
106
+ # - gravity: center point of the overlay - default 'center'
98
107
  # If both options are given, the file will be used as-is if it exists and is a valid image file. Otherwise the
99
108
  # file will be created or overwritten with a newly created watermark image.
100
109
  #
@@ -104,14 +113,17 @@ module Libis
104
113
  # @param [Hash] options Hash of options for watermark creation.
105
114
  def watermark(options = {})
106
115
  text = options[:text] || '© LIBIS'
107
- @wm_size = (options[:size] || '4').to_i
116
+ @wm_tiles = (options[:tiles] || '4').to_i
117
+ @wm_tiles ||= (options[:size] || '4').to_i
118
+ @wm_resize = ((options[:resize]).to_f * 100).to_i if options[:resize]
108
119
  @wm_opacity = ((options[:opacity] || 0.1).to_f * 100).to_i
109
120
  @wm_composition = options[:composition] || 'modulate'
110
- gap = ((options[:gap] || 0.2).to_f * 100).to_i
121
+ @wm_gravity = options[:gravity] || 'center'
122
+ @wm_gap = ((options[:gap] || 0.2).to_f * 100).to_i
111
123
  rotation = 360 - (options[:rotation] || 30).to_i
112
124
  @wm_image = MiniMagick::Image.new(options[:file]) if options[:file]
113
125
  unless @wm_image && @wm_image.valid?
114
- image = options[:file] || (Dir::Tmpname.create(%w(wm_image .png)) { |_|})
126
+ image = options[:file] || (Dir::Tmpname.create(%w(wm_image .png)) {|_|})
115
127
  # noinspection RubyResolve
116
128
  MiniMagick::Tool::Convert.new do |convert|
117
129
  # noinspection RubyLiteralArrayInspection
@@ -123,7 +135,6 @@ module Libis
123
135
  convert << "label:#{text}"
124
136
  convert.rotate rotation
125
137
  convert.trim.repage.+
126
- convert.bordercolor('transparent').border("#{gap}%")
127
138
  convert << image
128
139
  end
129
140
  if options[:file]
@@ -150,19 +161,20 @@ module Libis
150
161
  assemble_and_convert(source, target, format)
151
162
 
152
163
  elsif File.directory?(source)
153
- source_list = Dir[File.join(source, '**', '*')].reject { |p| File.directory? p }
164
+ source_list = Dir[File.join(source, '**', '*')].reject {|p| File.directory? p}
154
165
 
155
166
  assemble_and_convert(source_list, target, format)
156
167
 
157
168
  else
158
169
 
159
- image = MiniMagick::Image.new(source)
170
+ image = MiniMagick::Image.new(source) { |b| b.quiet }
160
171
 
161
172
  if image.pages.size > 1
162
173
  if @page
163
174
  convert_image(image.pages[@page].path, target, format)
164
175
  else
165
- assemble_and_convert(image.pages.map { |page| page.path }, target, format)
176
+ # noinspection RubyBlockToMethodReference
177
+ assemble_and_convert(image.pages.map {|page| page.path}, target, format)
166
178
  end
167
179
  else
168
180
  convert_image(source, target, format)
@@ -177,13 +189,14 @@ module Libis
177
189
 
178
190
  warn 'Received multiple images as input and single page format as target.' unless self.class.multipage?(format)
179
191
  converted_pages = sources.inject([]) do |list, path|
192
+ # noinspection RubyArgCount
180
193
  converted = Tempfile.new(['page-', ".#{Libis::Format::TypeDatabase.type_extentions(format).first}"])
181
194
  convert_image(path, converted.path, format)
182
195
  list << converted
183
196
  end
184
197
  MiniMagick::Tool::Convert.new do |b|
185
198
  b.append unless self.class.multipage?(format)
186
- converted_pages.each { |page| b << page.path }
199
+ converted_pages.each {|page| b << page.path}
187
200
  b << target
188
201
  end
189
202
  converted_pages.each do |temp_file|
@@ -197,29 +210,37 @@ module Libis
197
210
  def convert_image(source, target, format)
198
211
 
199
212
  image_info = nil
200
- image_info = MiniMagick::Image::Info.new(source) if @wm_image
213
+ image_info = MiniMagick::Image::Info.new(source) {|b| b.quiet} if @wm_image
201
214
 
202
215
  MiniMagick::Tool::Convert.new do |convert|
216
+ convert.quiet if @quiet
203
217
  if @wm_image
204
218
  convert << @wm_image.path
219
+ convert.bordercolor('transparent').border("#{@wm_gap}%") if @wm_gap > 0
205
220
  convert.filter('Lagrange')
206
- convert.resize("#{image_info['width'] / @wm_size}x#{image_info['height'] / @wm_size}").write('mpr:watermark').delete.+
221
+ convert.resize("#{image_info['width'] / @wm_tiles}x#{image_info['height'] / @wm_tiles}") if @wm_tiles > 0
222
+ convert.resize("#{@wm_resize}%") if @wm_resize
223
+ convert.write('mpr:watermark').delete.+
207
224
  end
208
225
 
226
+ convert.quiet if @quiet
209
227
  convert << source
210
- convert.flatten if format == :JPG
228
+ convert.flatten if @options[:flatten].nil? && format == :JPG
211
229
  if @wm_image
212
- # noinspection RubyResolve
213
- convert.stack do |stack|
214
- stack.size("#{image_info['width']}x#{image_info['height']}")
215
- stack << 'xc:transparent'
216
- stack.tile('mpr:watermark')
217
- stack.draw "rectangle 0,0,#{image_info['width']},#{image_info['height']}"
230
+ if @wm_tiles >= 0 and @wm_tiles <= 1
231
+ convert << 'mpr:watermark'
232
+ else
233
+ convert.stack do |stack|
234
+ stack.size("#{image_info['width']}x#{image_info['height']}")
235
+ stack << 'xc:transparent'
236
+ stack.tile('mpr:watermark')
237
+ stack.draw "rectangle 0,0,#{image_info['width']},#{image_info['height']}"
238
+ end
218
239
  end
219
- convert.compose(@wm_composition).define("compose:args=#{@wm_opacity}").composite
240
+ convert.compose(@wm_composition).gravity(@wm_gravity).define("compose:args=#{@wm_opacity}%").composite
220
241
  end
221
242
 
222
- @flags.each { |f, v| v.is_a?(FalseClass) ? convert.send(f).+ : convert.send(f) }
243
+ @flags.each {|f, v| v.is_a?(TrueClass) ? convert.send(f).+ : convert.send(f)}
223
244
  if @delete_date
224
245
  convert << '+set' << 'modify-date' << '+set' << 'create-date'
225
246
  end
@@ -227,13 +248,15 @@ module Libis
227
248
  colorspace = @options.delete(:colorspace) || 'sRGB'
228
249
  unless @options.empty?
229
250
  convert.colorspace('RGB')
230
- @options.each { |o, v| convert.send(o, v) }
251
+ @options.each {|o, v| convert.send(o, v)}
231
252
  end
232
253
  convert.colorspace(colorspace)
233
254
  convert.profile @profile if @profile
234
255
 
235
256
  convert.format(format)
236
257
  convert << target
258
+
259
+ debug "ImageMagick command: '#{convert.command.join(' ')}'"
237
260
  end
238
261
 
239
262
  target
@@ -42,10 +42,10 @@ module Libis
42
42
 
43
43
  def get(file, options = {})
44
44
 
45
- options[:droid] = true unless options.keys.include?(:droid) and options[:tool] and options[:tool] != :droid
46
- options[:fido] = true unless options.keys.include?(:fido) and options[:tool] and options[:tool] != :fido
47
- options[:file] = true unless options.keys.include?(:file) and options[:tool] and options[:tool] != :file
48
- options[:xml_validation] = true unless options.keys.include?(:xml_validation) and !options[:xml_validation]
45
+ options[:droid] = true unless options.keys.include?(:droid) or (options[:tool] and options[:tool] != :droid)
46
+ options[:fido] = true unless options.keys.include?(:fido) or (options[:tool] and options[:tool] != :fido)
47
+ options[:file] = true unless options.keys.include?(:file) or (options[:tool] and options[:tool] != :file)
48
+ options[:xml_validation] = true if options[:xml_validation].nil?
49
49
 
50
50
  result = {messages: [], output: {}, formats: {}}
51
51
 
@@ -1,23 +1,18 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'singleton'
4
3
  require 'yaml'
5
4
 
6
5
  require 'backports/rails/hash'
7
- require 'libis/tools/logger'
8
- require 'libis/tools/extend/string'
9
-
10
- require_relative 'config'
11
6
 
12
7
  module Libis
13
8
  module Format
14
9
 
10
+ # noinspection RubyClassVariableUsageInspection
15
11
  class TypeDatabase
16
- include Singleton
17
- include ::Libis::Tools::Logger
12
+ @implementation = Libis::Format::TypeDatabaseImpl.instance
18
13
 
19
- def self.typeinfo(t)
20
- self.instance.types[t.to_sym] || {}
14
+ def self.implementation(impl)
15
+ @implementation = impl
21
16
  end
22
17
 
23
18
  def self.enrich(info, map_keys = {})
@@ -34,7 +29,7 @@ module Libis
34
29
  mapper.keys.each do |key|
35
30
  info[mapper[key]] = get(type_name, key) || info[mapper[key]]
36
31
  end
37
- info[mapper[:GROUP]] = self.type_group(type_name)
32
+ info[mapper[:GROUP]] = type_group(type_name)
38
33
  end
39
34
  info
40
35
  end
@@ -44,14 +39,14 @@ module Libis
44
39
  mapper = Hash.new {|hash,key| hash[key] = key}
45
40
  mapper.merge! map_keys
46
41
  unless (puid = info[mapper[:PUID]]).blank?
47
- info[mapper[:TYPE]] ||= self.puid_infos(puid).first[:TYPE] rescue nil
42
+ info[mapper[:TYPE]] ||= puid_infos(puid).first[:TYPE] rescue nil
48
43
  end
49
44
  unless (mime = info[mapper[:MIME]]).blank?
50
- info[mapper[:TYPE]] ||= self.mime_infos(mime).first[:TYPE] rescue nil
45
+ info[mapper[:TYPE]] ||= mime_infos(mime).first[:TYPE] rescue nil
51
46
  end
52
47
  unless (type_name = info[mapper[:TYPE]]).nil?
53
- info[mapper[:MIME]] = self.type_mimetypes(type_name).first if self.type_mimetypes(type_name).first
54
- info[mapper[:GROUP]] = self.type_group(type_name)
48
+ info[mapper[:MIME]] = type_mimetypes(type_name).first if type_mimetypes(type_name).first
49
+ info[mapper[:GROUP]] = type_group(type_name)
55
50
  end
56
51
  info
57
52
  end
@@ -65,7 +60,7 @@ module Libis
65
60
  when :EXTENSION
66
61
  type_extentions(type_name).first
67
62
  else
68
- self.typeinfo(type_name)[key]
63
+ typeinfo(type_name)[key]
69
64
  end
70
65
  end
71
66
 
@@ -85,114 +80,52 @@ module Libis
85
80
  typeinfo(t)[:EXTENSIONS] || []
86
81
  end
87
82
 
83
+ def self.typeinfo(t)
84
+ @implementation.typeinfo(t)
85
+ end
86
+
88
87
  def self.group_types(group)
89
- self.instance.types.select do |_, v|
90
- v[:GROUP] == group.to_sym
91
- end.keys
88
+ @implementation.group_types(group)
92
89
  end
93
90
 
94
91
  def self.puid_infos(puid)
95
- self.instance.types.select do |_, v|
96
- v[:PUID].include? puid rescue false
97
- end.values
92
+ @implementation.puid_infos(puid)
98
93
  end
99
94
 
100
95
  def self.puid_types(puid)
101
- self.instance.types.select do |_, v|
102
- v[:PUID].include? puid rescue false
103
- end.keys
96
+ @implementation.puid_types(puid)
104
97
  end
105
98
 
106
99
  def self.puid_groups(puid)
107
- puid_types(puid).map do |t|
108
- type_group t
109
- end
100
+ puid_types(puid).map(&method(:type_group))
110
101
  end
111
102
 
112
103
  def self.mime_infos(mime)
113
- self.instance.types.select do |_, v|
114
- v[:MIME].include? mime rescue false
115
- end.values
104
+ @implementation.mime_infos(mime)
116
105
  end
117
106
 
118
107
  def self.mime_types(mime)
119
- self.instance.types.select do |_, v|
120
- v[:MIME].include? mime rescue false
121
- end.keys
108
+ @implementation.mime_types(mime)
122
109
  end
123
110
 
124
111
  def self.mime_groups(mime)
125
- mime_types(mime).map do |t|
126
- type_group t
127
- end
112
+ mime_types(mime).map(&method(:type_group))
128
113
  end
129
114
 
130
115
  def self.ext_infos(ext)
131
- ext = ext.gsub /^\./, ''
132
- self.instance.types.select do |_, v|
133
- v[:EXTENSIONS].include?(ext) rescue false
134
- end.values
116
+ @implementation.ext_infos(ext)
135
117
  end
136
118
 
137
119
  def self.ext_types(ext)
138
- ext = ext.gsub /^\./, ''
139
- self.instance.types.select do |_, v|
140
- v[:EXTENSIONS].include?(ext) rescue false
141
- end.keys
120
+ @implementation.ext_types(ext)
142
121
  end
143
122
 
144
123
  def self.puid_typeinfo(puid)
145
- self.instance.types.each do |_, v|
146
- return v if v[:PUID] and v[:PUID].include?(puid)
147
- end
148
- nil
124
+ @implementation.puid_typeinfo(puid)
149
125
  end
150
126
 
151
127
  def self.known_mime?(mime)
152
- self.instance.types.each do |_, v|
153
- return true if v[:MIME].include? mime
154
- end
155
- false
156
- end
157
-
158
- attr_reader :types
159
-
160
- def load_types(file_or_hash = {}, append = true)
161
- hash = file_or_hash.is_a?(Hash) ? file_or_hash : YAML::load_file(file_or_hash)
162
- # noinspection RubyResolve
163
- hash.each do |group, type_info|
164
- type_info.each do |type_name, info|
165
- type_key = type_name.to_sym
166
- info.symbolize_keys!
167
- info[:TYPE] = type_key
168
- info[:GROUP] = group.to_sym
169
- info[:MIME] = info[:MIME].strip.split(/[\s,]+/).map { |v| v.strip } rescue []
170
- info[:EXTENSIONS] = info[:EXTENSIONS].strip.split(/[\s,]+/).map { |v| v.strip } rescue []
171
- info[:PUID] = info[:PUID].strip.split(/[\s,]+/).map { |v| v.strip } if info[:PUID]
172
- if @types.has_key?(type_key)
173
- warn 'Type %s already defined; merging with info from %s.', type_name.to_s, file_or_hash
174
- info.merge!(@types[type_key]) do |_,v_new,v_old|
175
- case v_old
176
- when Array
177
- append ? v_old + v_new : v_new + v_old
178
- when Hash
179
- append ? v_new.merge(v_old) : v_old.merge(v_new)
180
- else
181
- append ? v_old : v_new
182
- end
183
- end
184
- end
185
- @types[type_key] = info
186
- end
187
- end
188
- end
189
-
190
- protected
191
-
192
- def initialize
193
- @types = Hash.new
194
- type_database = Libis::Format::Config[:type_database]
195
- load_types(type_database)
128
+ @implementation.known_mime?(mime)
196
129
  end
197
130
 
198
131
  end
@@ -0,0 +1,120 @@
1
+ # coding: utf-8
2
+
3
+ require 'singleton'
4
+ require 'yaml'
5
+
6
+ require 'backports/rails/hash'
7
+ require 'libis/tools/logger'
8
+ require 'libis/tools/extend/string'
9
+
10
+ module Libis
11
+ module Format
12
+
13
+ class TypeDatabaseImpl
14
+ include Singleton
15
+ include ::Libis::Tools::Logger
16
+
17
+ def typeinfo(t)
18
+ @types[t.to_sym] || {}
19
+ end
20
+
21
+ def group_types(group)
22
+ @types.select do |_, v|
23
+ v[:GROUP] == group.to_sym
24
+ end.keys
25
+ end
26
+
27
+ def puid_infos(puid)
28
+ @types.select do |_, v|
29
+ v[:PUID].include? puid rescue false
30
+ end.values
31
+ end
32
+
33
+ def puid_types(puid)
34
+ @types.select do |_, v|
35
+ v[:PUID].include? puid rescue false
36
+ end.keys
37
+ end
38
+
39
+ def mime_infos(mime)
40
+ @types.select do |_, v|
41
+ v[:MIME].include? mime rescue false
42
+ end.values
43
+ end
44
+
45
+ def mime_types(mime)
46
+ @types.select do |_, v|
47
+ v[:MIME].include? mime rescue false
48
+ end.keys
49
+ end
50
+
51
+ def ext_infos(ext)
52
+ ext = ext.gsub /^\./, ''
53
+ @types.select do |_, v|
54
+ v[:EXTENSIONS].include?(ext) rescue false
55
+ end.values
56
+ end
57
+
58
+ def ext_types(ext)
59
+ ext = ext.gsub /^\./, ''
60
+ @types.select do |_, v|
61
+ v[:EXTENSIONS].include?(ext) rescue false
62
+ end.keys
63
+ end
64
+
65
+ def puid_typeinfo(puid)
66
+ @types.each do |_, v|
67
+ return v if v[:PUID] and v[:PUID].include?(puid)
68
+ end
69
+ nil
70
+ end
71
+
72
+ def known_mime?(mime)
73
+ @types.each do |_, v|
74
+ return true if v[:MIME].include? mime
75
+ end
76
+ false
77
+ end
78
+
79
+ def load_types(file_or_hash = {}, append = true)
80
+ hash = file_or_hash.is_a?(Hash) ? file_or_hash : YAML::load_file(file_or_hash)
81
+ # noinspection RubyResolve
82
+ hash.each do |group, type_info|
83
+ type_info.each do |type_name, info|
84
+ type_key = type_name.to_sym
85
+ info.symbolize_keys!
86
+ info[:TYPE] = type_key
87
+ info[:GROUP] = group.to_sym
88
+ info[:MIME] = info[:MIME].strip.split(/[\s,]+/).map(&:strip) rescue []
89
+ info[:EXTENSIONS] = info[:EXTENSIONS].strip.split(/[\s,]+/).map { |v| v.strip } rescue []
90
+ info[:PUID] = info[:PUID].strip.split(/[\s,]+/).map { |v| v.strip } if info[:PUID]
91
+ if @types.has_key?(type_key)
92
+ warn 'Type %s already defined; merging with info from %s.', type_name.to_s, file_or_hash
93
+ info.merge!(@types[type_key]) do |_,v_new,v_old|
94
+ case v_old
95
+ when Array
96
+ append ? v_old + v_new : v_new + v_old
97
+ when Hash
98
+ append ? v_new.merge(v_old) : v_old.merge(v_new)
99
+ else
100
+ append ? v_old : v_new
101
+ end
102
+ end
103
+ end
104
+ @types[type_key] = info
105
+ end
106
+ end
107
+ end
108
+
109
+ protected
110
+
111
+ def initialize
112
+ @types = Hash.new
113
+ type_database = Libis::Format::Config[:type_database]
114
+ load_types(type_database)
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+ end
@@ -1,5 +1,5 @@
1
1
  module Libis
2
2
  module Format
3
- VERSION = '1.0.2'
3
+ VERSION = '1.0.4'
4
4
  end
5
5
  end
@@ -22,7 +22,6 @@ Gem::Specification.new do |spec|
22
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
23
  spec.require_paths = ['lib']
24
24
 
25
- spec.add_development_dependency 'bundler', '~> 1.6'
26
25
  spec.add_development_dependency 'rake', '~> 10.3'
27
26
  spec.add_development_dependency 'rspec', '~> 3.1'
28
27
  spec.add_development_dependency 'awesome_print'
Binary file
Binary file
Binary file
@@ -12,7 +12,7 @@ formatlist =
12
12
  'test.odt' => {mimetype: 'application/vnd.oasis.opendocument.text', puid: 'fmt/291'},
13
13
  'test.doc' => {mimetype: 'application/msword', puid: 'fmt/40'},
14
14
  'test.docx' => {mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', puid: 'fmt/412'},
15
- 'test.pdf' => {mimetype: 'application/pdf', puid: 'fmt/18'},
15
+ 'test.pdf' => {mimetype: 'application/pdf', puid: 'fmt/276'},
16
16
  'test.rtf' => {mimetype: 'application/rtf', puid: 'fmt/45'},
17
17
  'test.txt' => {mimetype: 'text/plain', puid: 'x-fmt/111'},
18
18
  'test.ods' => {mimetype: 'application/vnd.oasis.opendocument.spreadsheet', puid: 'fmt/295'},
@@ -42,7 +42,7 @@ fidolist =
42
42
  'test.odt' => {mimetype: 'application/vnd.oasis.opendocument.text', puid: 'fmt/290'},
43
43
  'test.doc' => {mimetype: nil, puid: 'fmt/111'},
44
44
  'test.docx' => {mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', puid: 'fmt/412'},
45
- 'test.pdf' => {mimetype: 'application/pdf', puid: 'fmt/18'},
45
+ 'test.pdf' => {mimetype: 'application/pdf', puid: 'fmt/276'},
46
46
  'test.rtf' => {mimetype: 'application/rtf', puid: 'fmt/45'},
47
47
  'test.txt' => {mimetype: 'text/plain', puid: 'x-fmt/111'},
48
48
  'test.ods' => {mimetype: 'application/vnd.oasis.opendocument.spreadsheet', puid: 'fmt/294'},
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
  describe 'Type Databse' do
5
5
 
6
6
  before :all do
7
- ::Libis::Format::TypeDatabase.instance.load_types File.join(File.dirname(__FILE__), 'test_types.yml')
7
+ ::Libis::Format::TypeDatabaseImpl.instance.load_types File.join(File.dirname(__FILE__), 'test_types.yml')
8
8
  end
9
9
 
10
10
  it 'should load types from file' do
@@ -93,7 +93,7 @@ describe 'Type Databse' do
93
93
 
94
94
  it 'should load types from hash' do
95
95
 
96
- ::Libis::Format::TypeDatabase.instance.load_types TESTMEDIUM: {
96
+ ::Libis::Format::TypeDatabaseImpl.instance.load_types TESTMEDIUM: {
97
97
  TESTREPORT: {
98
98
  NAME: 'Test report format',
99
99
  MIME: 'test/report application/test/report',
@@ -111,7 +111,7 @@ describe 'Type Databse' do
111
111
 
112
112
  it 'should merge types from hash' do
113
113
 
114
- ::Libis::Format::TypeDatabase.instance.load_types TESTMEDIUM: {
114
+ ::Libis::Format::TypeDatabaseImpl.instance.load_types TESTMEDIUM: {
115
115
  TESTREPORT: {
116
116
  EXTENSIONS: 'rpt'
117
117
  }
@@ -123,7 +123,7 @@ describe 'Type Databse' do
123
123
  MIME: %w'test/report application/test/report',
124
124
  EXTENSIONS: %w'rep rpt'
125
125
 
126
- ::Libis::Format::TypeDatabase.instance.load_types({TESTMEDIUM: {
126
+ ::Libis::Format::TypeDatabaseImpl.instance.load_types({TESTMEDIUM: {
127
127
  TESTREPORT: {
128
128
  EXTENSIONS: 'report'
129
129
  }
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libis-format
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kris Dekeyser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-15 00:00:00.000000000 Z
11
+ date: 2019-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.6'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.6'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: rake
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -186,6 +172,7 @@ executables:
186
172
  - droid
187
173
  - fido
188
174
  - formatinfo
175
+ - libis_format
189
176
  - pdf_copy
190
177
  extensions: []
191
178
  extra_rdoc_files: []
@@ -200,6 +187,7 @@ files:
200
187
  - bin/droid
201
188
  - bin/fido
202
189
  - bin/formatinfo
190
+ - bin/libis_format
203
191
  - bin/pdf_copy
204
192
  - data/ISOcoated_v2_eci.icc
205
193
  - data/PDFA_def.ps
@@ -210,6 +198,11 @@ files:
210
198
  - data/xlink.xsd
211
199
  - lib/libis-format.rb
212
200
  - lib/libis/format.rb
201
+ - lib/libis/format/cli/convert.rb
202
+ - lib/libis/format/cli/format.rb
203
+ - lib/libis/format/cli/prompt_helper.rb
204
+ - lib/libis/format/cli/sub_command.rb
205
+ - lib/libis/format/command_line.rb
213
206
  - lib/libis/format/config.rb
214
207
  - lib/libis/format/converter.rb
215
208
  - lib/libis/format/converter/audio_converter.rb
@@ -242,6 +235,7 @@ files:
242
235
  - lib/libis/format/tool/pdfa_validator.rb
243
236
  - lib/libis/format/tool/spreadsheet_to_ods.rb
244
237
  - lib/libis/format/type_database.rb
238
+ - lib/libis/format/type_database_impl.rb
245
239
  - lib/libis/format/version.rb
246
240
  - libis-format.gemspec
247
241
  - spec/converter_audio_spec.rb