libis-format 1.3.8.1 → 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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +20 -0
  4. data/.travis.yml +70 -0
  5. data/Gemfile +0 -12
  6. data/README.md +2 -2
  7. data/Rakefile +8 -0
  8. data/base/Dockerfile +35 -0
  9. data/base/Dockerfile.alpine +20 -0
  10. data/base/Dockerfile.rvm +56 -0
  11. data/base/rework_path +20 -0
  12. data/bin/{pdf_tool → pdf_copy} +2 -3
  13. data/data/PDFA_def.ps +3 -3
  14. data/data/eciRGB_v2.icc +0 -0
  15. data/data/types.yml +4 -17
  16. data/docker_cfg.yml +1 -0
  17. data/lib/libis/format/cli/convert.rb +4 -4
  18. data/lib/libis/format/cli/prompt_helper.rb +24 -32
  19. data/lib/libis/format/command_line.rb +3 -2
  20. data/lib/libis/format/config.rb +23 -19
  21. data/lib/libis/format/converter/audio_converter.rb +31 -56
  22. data/lib/libis/format/converter/base.rb +36 -16
  23. data/lib/libis/format/converter/chain.rb +32 -62
  24. data/lib/libis/format/converter/fop_pdf_converter.rb +8 -4
  25. data/lib/libis/format/converter/image_assembler.rb +82 -0
  26. data/lib/libis/format/converter/image_converter.rb +45 -248
  27. data/lib/libis/format/converter/image_splitter.rb +80 -0
  28. data/lib/libis/format/converter/image_watermarker.rb +261 -0
  29. data/lib/libis/format/converter/jp2_converter.rb +38 -36
  30. data/lib/libis/format/converter/office_converter.rb +28 -22
  31. data/lib/libis/format/converter/pdf_assembler.rb +66 -0
  32. data/lib/libis/format/converter/pdf_converter.rb +52 -200
  33. data/lib/libis/format/converter/pdf_optimizer.rb +70 -0
  34. data/lib/libis/format/converter/pdf_splitter.rb +65 -0
  35. data/lib/libis/format/converter/pdf_watermarker.rb +110 -0
  36. data/lib/libis/format/converter/repository.rb +13 -7
  37. data/lib/libis/format/converter/spreadsheet_converter.rb +16 -10
  38. data/lib/libis/format/converter/video_converter.rb +73 -109
  39. data/lib/libis/format/converter/xslt_converter.rb +11 -13
  40. data/lib/libis/format/converter.rb +1 -1
  41. data/lib/libis/format/identifier.rb +46 -44
  42. data/lib/libis/format/info.rb +27 -0
  43. data/lib/libis/format/library.rb +147 -0
  44. data/lib/libis/format/tool/droid.rb +30 -29
  45. data/lib/libis/format/tool/extension_identification.rb +26 -24
  46. data/lib/libis/format/tool/{ff_mpeg.rb → ffmpeg.rb} +10 -17
  47. data/lib/libis/format/tool/fido.rb +27 -22
  48. data/lib/libis/format/tool/file_tool.rb +24 -11
  49. data/lib/libis/format/tool/fop_pdf.rb +14 -25
  50. data/lib/libis/format/tool/identification_tool.rb +40 -38
  51. data/lib/libis/format/tool/office_to_pdf.rb +18 -30
  52. data/lib/libis/format/tool/pdf_copy.rb +47 -0
  53. data/lib/libis/format/tool/pdf_merge.rb +19 -25
  54. data/lib/libis/format/tool/pdf_optimizer.rb +19 -22
  55. data/lib/libis/format/tool/pdf_split.rb +33 -6
  56. data/lib/libis/format/tool/pdf_to_pdfa.rb +31 -45
  57. data/lib/libis/format/tool/pdfa_validator.rb +30 -24
  58. data/lib/libis/format/tool/spreadsheet_to_ods.rb +18 -29
  59. data/lib/libis/format/tool.rb +3 -4
  60. data/lib/libis/format/version.rb +1 -3
  61. data/lib/libis/format/yaml_loader.rb +71 -0
  62. data/lib/libis/format.rb +7 -5
  63. data/lib/libis-format.rb +0 -2
  64. data/libis-format.gemspec +19 -29
  65. data/tools/PdfTool.jar +0 -0
  66. data/tools/pdfbox/pdfbox-app-2.0.13.jar +0 -0
  67. data/tools/pdfbox/{preflight-app-3.0.3.jar → preflight-app-2.0.13.jar} +0 -0
  68. metadata +83 -152
  69. data/data/AdobeRGB1998.icc +0 -0
  70. data/lib/libis/format/converter/email_converter.rb +0 -51
  71. data/lib/libis/format/tool/eml_to_pdf.rb +0 -168
  72. data/lib/libis/format/tool/mail_to_pdf.rb +0 -447
  73. data/lib/libis/format/tool/msg_to_pdf.rb +0 -154
  74. data/lib/libis/format/tool/pdf_tool.rb +0 -52
  75. data/lib/libis/format/type_database.rb +0 -156
  76. data/lib/libis/format/type_database_impl.rb +0 -153
  77. data/tools/pdf2pdfa +0 -395
  78. data/tools/pdfbox/pdfbox-app-3.0.3.jar +0 -0
  79. /data/bin/{droid_tool → droid} +0 -0
  80. /data/bin/{fido_tool → fido} +0 -0
@@ -1,447 +0,0 @@
1
- # rubocop:disable Style/Documentation, Metrics/*
2
- # frozen_string_literal: true
3
-
4
- require 'base64'
5
- require 'cgi'
6
- require 'pdfkit'
7
- require 'time'
8
- require 'fileutils'
9
- require 'pathname'
10
- require 'libis/format/config'
11
-
12
- module Libis
13
- module Format
14
- module Tool
15
- HEADER_STYLE = <<~HTML
16
- <style>
17
- .header-table {
18
- margin: 0 0 10px 0;
19
- padding: 0;
20
- font-family: Arial, Helvetica, sans-serif;
21
- }
22
- .header-table table {
23
- width: 100%;
24
- }
25
- .header-name {
26
- padding-right: 5px;
27
- color: #9E9E9E;
28
- text-align: right;
29
- vertical-align: top;
30
- font-size: 12px;
31
- }
32
- .header-value {
33
- font-size: 12px;
34
- width: 99%;
35
- }
36
- .header_fields {
37
- background: white;
38
- margin: 0;
39
- border: 1px solid #DDD;
40
- border-radius: 3px;
41
- padding: 8px;
42
- box-sizing: border-box;
43
- }
44
- </style>
45
- HTML
46
-
47
- HEADER_TABLE_TEMPLATE = <<~HTML
48
- <div class="header-table">
49
- <table class="header_fields">
50
- <tbody>
51
- %s
52
- </tbody>
53
- </table>
54
- </div>
55
- HTML
56
-
57
- HEADER_FIELD_TEMPLATE = <<~HTML
58
- <tr>
59
- <td class="header-name">%s</td>
60
- <td class="header-value">%s</td>
61
- </tr>
62
- HTML
63
-
64
- HTML_WRAPPER_TEMPLATE = <<~HTML
65
- <!DOCTYPE html>
66
- <html>
67
- <head>
68
- <style>
69
- body {
70
- font-size: 12px;
71
- }
72
- </style>
73
- <title>title</title>
74
- </head>
75
- <body>
76
- <pre>
77
- %s
78
- </pre>
79
- </body>
80
- </html>
81
- HTML
82
-
83
- HTML_BODY_TEMPLATE = <<~HTML
84
- <!DOCTYPE html>
85
- <html>
86
- <head>
87
- <style>
88
- body {
89
- font-size: 12px;
90
- }
91
- </style>
92
- <title>title</title>
93
- </head>
94
- <body>
95
- %s
96
- </body>
97
- </html>
98
- HTML
99
-
100
- ATTACHMENT_STYLE = <<~HTML
101
- <style>
102
- .attachment-list {
103
- border: 1px solid #DDD;
104
- margin: 0 0 10px 0;
105
- padding: 0;
106
- font-family: Arial, Helvetica, sans-serif;
107
- }
108
- .attachment-list ul {
109
- list-style: disclosure-closed;
110
- }
111
- .attachment-list li {
112
- font-size: 12px;
113
- padding-left: 1em;
114
- }
115
- </style>
116
- HTML
117
-
118
- ATTACHMENT_LIST_TEMPLATE = <<~HTML
119
- <div class="attachment-list">
120
- <ul>
121
- %s
122
- </ul>
123
- </div>
124
- HTML
125
-
126
- HTML_DOCTYPE_TEMPLATE = '<!DOCTYPE html>%s'
127
- ATTACHMENT_ITEM_TEMPLATE = '<li>%s</li>'
128
-
129
- IMG_CID_PLAIN_REGEX = /\[cid:(.*?)\]/im
130
- IMG_CID_HTML_REGEX = /cid:([^"]*)/im
131
-
132
- class MailToPdf
133
- include ::Libis::Tools::Logger
134
-
135
- def self.installed?
136
- File.exist?(Libis::Format::Config[:wkhtmltopdf])
137
- end
138
-
139
- def self.run(source, target, **options)
140
- new.run source, target, **options
141
- end
142
-
143
- def run(source, target, **options)
144
- # Preliminary checks
145
- @warnings = []
146
-
147
- # PDF creation options
148
- @pdf_options = {
149
- page_size: 'A4',
150
- margin_top: '10mm',
151
- margin_bottom: '10mm',
152
- margin_left: '10mm',
153
- margin_right: '10mm',
154
- # image_quality: 100,
155
- # viewport_size: '2480x3508',
156
- dpi: 300
157
- }.merge options
158
-
159
- # Check if source file exists
160
- raise "File #{source} does not exist" unless File.exist?(source)
161
-
162
- # Open the email
163
- email = open_email(source)
164
-
165
- # Convert the email message to PDF
166
- result = email_to_pdf(email, target, root_msg: true)
167
-
168
- # Close email message
169
- close_email(email)
170
-
171
- result
172
- end
173
-
174
- protected
175
-
176
- def email_to_pdf(msg, target, root_msg: false)
177
- # Make sure the target directory exists
178
- outdir = File.dirname(target)
179
- FileUtils.mkdir_p(outdir)
180
-
181
- # Process the message body
182
- # ------------------------
183
- body = get_body(msg)
184
-
185
- # Process headers
186
- # ---------------
187
- headers, headers_html = get_headers(msg)
188
-
189
- # Add header section to the HTML body
190
- body = add_headers_to_body(body, headers_html)
191
-
192
- # Embed inline images
193
- # -------------------
194
- attachments = msg.attachments
195
- used_files = embed_inline_attachments(body, attachments)
196
-
197
- # Save other attachments
198
- # ----------------------
199
- attachments_dir = "#{target}.attachments"
200
-
201
- files = save_attachments(attachments, attachments_dir, used_files)
202
-
203
- # Add attachment section to the HTML body
204
- body = add_attachments_to_body(body, files, attachments_dir)
205
-
206
- # Save the HTML body as a .html file next to the PDF for debugging purposes
207
- File.open("#{target}.html", 'wb') { |f| f.write(body) }
208
-
209
- # Create PDF
210
- # ----------
211
- write_target_file(body, get_subject(msg), target)
212
-
213
- files = [target] + files if File.exist?(target)
214
-
215
- if root_msg
216
- p = Pathname(File.dirname(files.first))
217
- files.drop(1).each do |f|
218
- (headers[:attachments] ||= []) << Pathname.new(f).relative_path_from(p).to_s
219
- end
220
- end
221
-
222
- {
223
- command: { status: 0 },
224
- files:,
225
- headers:,
226
- warnings: @warnings
227
- }
228
- rescue StandardError => e
229
- raise unless root_msg
230
-
231
- close_email(msg) if msg
232
- {
233
- command: { status: -1 },
234
- files: [],
235
- headers: {},
236
- errors: [
237
- {
238
- error: e.message,
239
- error_class: e.class.name,
240
- error_trace: e.backtrace
241
- }
242
- ],
243
- warnings: @warnings
244
- }
245
- end
246
-
247
- def get_body(msg)
248
- body = get_body_html(msg)
249
-
250
- body = HTML_BODY_TEMPLATE % body unless /<body[^>]*>/i.match?(body)
251
- body = HTML_DOCTYPE_TEMPLATE % body unless /<!DOCTYPE html/i.match?(body)
252
- body.sub!(%r{<title>title</title>}, "<title>#{get_subject(msg)}</title>")
253
-
254
- body
255
- end
256
-
257
- def add_headers_to_body(body, headers_html)
258
- encoding = body.encoding
259
- return body if headers_html.empty?
260
-
261
- b = body.downcase
262
-
263
- # Insert header block styles
264
- if b.include?('</head>')
265
- # if head exists, append the style block
266
- body.gsub!(%r{</head>}i, "#{HEADER_STYLE}</head>")
267
- elsif b.include?('<head/>')
268
- # empty head, replace with the style block
269
- body.gsub!(%r{<head/>}i, "<head>#{HEADER_STYLE}</head>")
270
- else
271
- # otherwise insert a head section before the body tag
272
- body.gsub!(/<body/i, "<head>#{HEADER_STYLE}</head><body")
273
- end
274
- # Add the headers html table as first element in the body section
275
- body.gsub!(/<body[^>]*>/i) { |m| "#{m}#{HEADER_TABLE_TEMPLATE % headers_html.encode(encoding)}" }
276
- body
277
- end
278
-
279
- def hdr_html(key, value)
280
- if key.is_a?(String) && value.is_a?(String) && !value.empty?
281
- return format(HEADER_FIELD_TEMPLATE, key,
282
- CGI.escapeHTML(value))
283
- end
284
-
285
- ''
286
- end
287
-
288
- def embed_inline_attachments(body, attachments)
289
- used_files = []
290
-
291
- # First process plaintext cid entries
292
- body.gsub!(IMG_CID_PLAIN_REGEX) do |_match|
293
- data = get_inline_attachment_data(attachments, ::Regexp.last_match(1))
294
- if data
295
- used_files << ::Regexp.last_match(1)
296
- "<img src=\"data:#{data[:mime_type]};base64,#{data[:base64]}\"/>"
297
- else
298
- '<img src=""/>'
299
- end
300
- end
301
-
302
- # Then process HTML img tags with CID entries
303
- body.gsub!(IMG_CID_HTML_REGEX) do |_match|
304
- data = get_inline_attachment_data(attachments, ::Regexp.last_match(1))
305
- if data
306
- used_files << ::Regexp.last_match(1)
307
- "data:#{data[:mime_type]};base64,#{data[:base64]}"
308
- else
309
- ''
310
- end
311
- end
312
-
313
- used_files
314
- end
315
-
316
- def save_attachments(attachments, outdir, used_files)
317
- files = []
318
-
319
- digits = ((attachments.count + 1) / 10) + 1
320
- i = 1
321
-
322
- get_attachments(attachments, used_files).each do |attachment|
323
- prefix = "#{format('%0*d', digits, i)}-"
324
-
325
- info = get_attachment_info(attachment)
326
-
327
- if info[:embedded_msg]
328
- sub_msg = info[:embedded_msg]
329
- file = File.join(outdir, "#{prefix}#{info[:filename].tr('/', '_')}.msg.pdf")
330
-
331
- result = email_to_pdf(sub_msg, file, root_msg: false)
332
-
333
- if (e = result[:error])
334
- raise e
335
- end
336
-
337
- files += result[:files]
338
- elsif info[:data]
339
- file = File.join(outdir, "#{prefix}#{info[:filename].tr('/', '_')}")
340
- FileUtils.mkdir_p(File.dirname(file))
341
- File.open(file, 'wb') { |f| f.write(info[:data]) }
342
- files << file
343
- else
344
- @warnings << "Attachment #{info[:filename]} cannot be extracted"
345
- next
346
- end
347
-
348
- i += 1
349
- end
350
- files
351
- end
352
-
353
- def add_attachments_to_body(body, files, attachments_dir)
354
- return body if files.empty?
355
-
356
- b = body.downcase
357
-
358
- # Insert attachment block styles
359
- if b.include?('</head>')
360
- # if head exists, append the style block
361
- body.gsub!(%r{</head>}i, "#{ATTACHMENT_STYLE}</head>")
362
- elsif b.include?('<head/>')
363
- # empty head, replace with the style block
364
- body.gsub!(%r{<head/>}i, "<head>#{ATTACHMENT_STYLE}</head>")
365
- else
366
- # otherwise insert a head section before the body tag
367
- body.gsub!(/<body/i, "<head>#{ATTACHMENT_STYLE}</head><body")
368
- end
369
-
370
- # Filter files to only include those that are in the attachments directory
371
- # and map them to relative paths from the attachments directory
372
- items = files.filter_map do |f|
373
- Pathname.new(f).relative_path_from(Pathname.new(attachments_dir)).to_s if File.dirname(f) == attachments_dir
374
- end
375
-
376
- # Create the attachment item HTML
377
- items = items.map do |f|
378
- format(ATTACHMENT_ITEM_TEMPLATE, f, File.basename(f))
379
- end.join("\n")
380
-
381
- # Create the attachment list HTML
382
- attachments_html = ATTACHMENT_LIST_TEMPLATE % items
383
-
384
- # make sure the attachments_html is encoded in the same encoding as the body
385
- attachments_html = attachments_html.encode(body.encoding)
386
-
387
- # Add the attachments html list after the headers
388
- # if there are no headers, then add it at the beginning of the body section
389
- body.sub!(%r{<div class="header-table">.*?</div>}im) { |m| "#{m}#{attachments_html}" } ||
390
- body.gsub!(/<body[^>]*>/i) { |m| "#{m}#{attachments_html}" }
391
-
392
- body
393
- end
394
-
395
- def get_attachments(attachments, used_files)
396
- get_file_attachments(attachments, used_files) + get_mail_attachments(attachments)
397
- end
398
-
399
- def write_target_file(body, title, target)
400
- kit = PDFKit.new(body, title: title || 'message', **@pdf_options)
401
- pdf = kit.to_pdf
402
- File.open(target, 'wb') { |f| f.write(pdf) }
403
- end
404
-
405
- # ---------------------------------------
406
- # Methods to be implemented by subclasses
407
- # ---------------------------------------
408
- def open_email(_source)
409
- raise NotImplementedError, 'Subclasses must implement the open_email method'
410
- end
411
-
412
- def close_email(_email)
413
- raise NotImplementedError, 'Subclasses must implement the close_email method'
414
- end
415
-
416
- def get_body_html(_msg)
417
- raise NotImplementedError, 'Subclasses must implement the get_body_html method'
418
- end
419
-
420
- def get_subject(_msg)
421
- raise NotImplementedError, 'Subclasses must implement the get_subject method'
422
- end
423
-
424
- def get_headers(_msg)
425
- raise NotImplementedError, 'Subclasses must implement the get_headers method'
426
- end
427
-
428
- def get_inline_attachment_data(_attachments, _cid)
429
- raise NotImplementedError, 'Subclasses must implement the get_inline_attachment_data method'
430
- end
431
-
432
- def get_file_attachments(_attachments, _used_files)
433
- raise NotImplementedError, 'Subclasses must implement the get_file_attachments method'
434
- end
435
-
436
- def get_mail_attachments(_attachments)
437
- raise NotImplementedError, 'Subclasses must implement the get_mail_attachments method'
438
- end
439
-
440
- def get_attachment_info(_attachment)
441
- raise NotImplementedError, 'Subclasses must implement the get_attachment_info method'
442
- end
443
- end
444
- end
445
- end
446
- end
447
- # rubocop:enable Style/Documentation, Metrics/*
@@ -1,154 +0,0 @@
1
- # rubocop:disable Style/Documentation, Metrics/*
2
- # frozen_string_literal: true
3
-
4
- require_relative 'mail_to_pdf'
5
-
6
- require 'msg_extractor'
7
- require 'word_wrap'
8
-
9
- module Libis
10
- module Format
11
- module Tool
12
- class MsgToPdf < MailToPdf
13
- protected
14
-
15
- def open_email(source)
16
- msg = nil
17
-
18
- # Open the message
19
- msg = MsgExtractor.open(source)
20
-
21
- unless msg.is_a?(MsgExtractor::Message)
22
- raise "File #{File.basename(source)} is not an Outlook message but a #{msg.class.name}"
23
- end
24
-
25
- msg
26
- rescue StandardError => e
27
- raise "Failed to open message: #{e.message}"
28
- end
29
-
30
- def close_email(_msg)
31
- true
32
- end
33
-
34
- def get_body_html(msg)
35
- # Get the body of the message in HTML
36
- body = msg.html_body
37
-
38
- # Embed plain body in HTML as a fallback
39
- body ||= HTML_WRAPPER_TEMPLATE % WordWrap.ww(msg.body, 120, false)
40
-
41
- # Worst case, just create empty body
42
- body ||= HTML_WRAPPER_TEMPLATE % ''
43
-
44
- # # Check and fix the character encoding
45
- # begin
46
- # # Try to encode into UTF-8
47
- # body.encode!('UTF-8', universal_newline: true)
48
- # rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError
49
- # begin
50
- # # If it fails, the text may be in Windows' Latin1 (ISO-8859-1)
51
- # body.force_encoding('ISO-8859-1').encode!('UTF-8', universal_newline: true)
52
- # rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError => e
53
- # # If that fails too, log a warning and replace the invalid/unknown with a ? character.
54
- # @warnings << "#{e.class}: #{e.message}"
55
- # body.encode!('UTF-8', universal_newline: true, invalid: :replace, undef: :replace)
56
- # end
57
- # end
58
-
59
- body
60
- end
61
-
62
- def get_subject(msg)
63
- msg.subject || ''
64
- end
65
-
66
- def get_headers(msg)
67
- headers = {}
68
- html = ''
69
-
70
- %w[From To Cc Subject Date].each do |key|
71
- value = find_hdr(msg, key)
72
- next unless value
73
-
74
- if key.casecmp('Date').zero? && value.is_a?(Time)
75
- headers[key.downcase.to_sym] = value.iso8601
76
- html += hdr_html(key, value.rfc2822)
77
- else
78
- headers[key.downcase.to_sym] = value
79
- html += hdr_html(key, value)
80
- end
81
- end
82
-
83
- [headers, html]
84
- end
85
-
86
- def get_inline_attachment_data(attachments, cid)
87
- attachments.each do |attachment|
88
- next unless attachment.content_id == cid
89
-
90
- return {
91
- mime_type: attachment.mime_type,
92
- base64: Base64.encode64(attachment.data).gsub(/[\r\n]/, '')
93
- }
94
- end
95
- nil
96
- end
97
-
98
- def get_file_attachments(attachments, _used_files)
99
- attachments.select do |attachment|
100
- !attachment.content_id && !attachment.embedded_message? && attachment.filename
101
- end
102
- end
103
-
104
- def get_mail_attachments(attachments)
105
- attachments.select(&:embedded_message?)
106
- end
107
-
108
- def get_attachment_info(attachment)
109
- if attachment.embedded_message?
110
-
111
- {
112
- embedded_msg: attachment.data,
113
- filename: attachment.message&.subject || 'email'
114
- }
115
-
116
- elsif attachment.filename
117
-
118
- {
119
- data: attachment.data,
120
- filename: attachment.filename
121
- }
122
-
123
- else
124
- {
125
- filename: attachment.mime_type || 'unknown'
126
- }
127
- end
128
- end
129
-
130
- private
131
-
132
- def find_hdr(msg, key)
133
- value = if key.casecmp('From').zero?
134
- msg.sender
135
- else
136
- msg.send(key.downcase.to_sym)
137
- end
138
-
139
- if value.is_a?(Array)
140
- value.compact.empty? ? nil : value.compact.map(&:to_s).join(', ')
141
-
142
- elsif value.is_a?(Time)
143
- value.localtime
144
-
145
- else
146
- value.to_s
147
-
148
- end
149
- end
150
- end
151
- end
152
- end
153
- end
154
- # rubocop:enable Style/Documentation, Metrics/*
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'os'
4
-
5
- require 'libis/tools/extend/string'
6
- require 'libis/tools/logger'
7
- require 'libis/tools/command'
8
-
9
- require 'libis/format/config'
10
-
11
- module Libis
12
- module Format
13
- module Tool
14
- class PdfTool
15
- include ::Libis::Tools::Logger
16
-
17
- def self.installed?
18
- result = Libis::Tools::Command.run(Libis::Format::Config[:java_cmd], '-version')
19
- return false unless (result[:status]).zero?
20
-
21
- File.exist?(Libis::Format::Config[:pdf_tool])
22
- end
23
-
24
- def self.run(command, source, target, *options)
25
- new.run command, source, target, *options
26
- end
27
-
28
- def run(command, source, target, *options)
29
- if OS.java?
30
- # TODO: import library and execute in current VM. For now do exactly as in MRI.
31
- end
32
-
33
- timeout = Libis::Format::Config[:timeouts][:pdf_tool]
34
- args = [
35
- Libis::Format::Config[:java_cmd],
36
- '-jar', Libis::Format::Config[:pdf_tool],
37
- [command],
38
- '-i', source,
39
- '-o', target,
40
- options,
41
- ].flatten
42
-
43
- result = Libis::Tools::Command.run(*args, timeout: , kill_after: timeout * 2)
44
-
45
- result[:err] << "#{self.class} took too long (> #{timeout} seconds) to complete" if result[:timeout]
46
-
47
- result
48
- end
49
- end
50
- end
51
- end
52
- end