libis-format 0.9.41 → 0.9.44
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/README.md +365 -0
- data/bin/droid +1 -1
- data/bin/fido +1 -1
- data/bin/pdf_copy +1 -1
- data/lib/libis/format/config.rb +1 -0
- data/lib/libis/format/converter/audio_converter.rb +1 -1
- data/lib/libis/format/converter/base.rb +2 -1
- data/lib/libis/format/converter/office_converter.rb +2 -2
- data/lib/libis/format/converter/pdf_converter.rb +6 -6
- data/lib/libis/format/converter/video_converter.rb +96 -2
- data/lib/libis/format/identifier.rb +12 -12
- data/lib/libis/format/tool/droid.rb +108 -0
- data/lib/libis/format/tool/extension_identification.rb +58 -0
- data/lib/libis/format/tool/ffmpeg.rb +43 -0
- data/lib/libis/format/tool/fido.rb +91 -0
- data/lib/libis/format/tool/file_tool.rb +78 -0
- data/lib/libis/format/tool/identification_tool.rb +175 -0
- data/lib/libis/format/tool/office_to_pdf.rb +54 -0
- data/lib/libis/format/tool/pdf_copy.rb +42 -0
- data/lib/libis/format/tool/pdf_merge.rb +43 -0
- data/lib/libis/format/tool/pdf_optimizer.rb +38 -0
- data/lib/libis/format/tool/pdf_split.rb +41 -0
- data/lib/libis/format/tool/pdf_to_pdfa.rb +78 -0
- data/lib/libis/format/tool/pdfa_validator.rb +63 -0
- data/lib/libis/format/tool.rb +23 -0
- data/lib/libis/format/version.rb +1 -1
- data/lib/libis/format.rb +1 -15
- data/libis-format.gemspec +1 -2
- data/spec/converter_audio_spec.rb +66 -0
- data/spec/converter_image_spec.rb +166 -0
- data/spec/converter_office_spec.rb +84 -0
- data/spec/converter_pdf_spec.rb +30 -0
- data/spec/converter_repository_spec.rb +91 -0
- data/spec/converter_video_spec.rb +97 -0
- data/spec/data/video/copyright.png +0 -0
- data/spec/identifier_spec.rb +3 -15
- metadata +32 -33
- data/lib/libis/format/droid.rb +0 -106
- data/lib/libis/format/extension_identification.rb +0 -55
- data/lib/libis/format/ffmpeg.rb +0 -41
- data/lib/libis/format/fido.rb +0 -89
- data/lib/libis/format/file_tool.rb +0 -76
- data/lib/libis/format/identification_tool.rb +0 -174
- data/lib/libis/format/office_to_pdf.rb +0 -52
- data/lib/libis/format/pdf_copy.rb +0 -40
- data/lib/libis/format/pdf_merge.rb +0 -41
- data/lib/libis/format/pdf_optimizer.rb +0 -36
- data/lib/libis/format/pdf_split.rb +0 -39
- data/lib/libis/format/pdf_to_pdfa.rb +0 -74
- data/lib/libis/format/pdfa_validator.rb +0 -61
- data/spec/converter_spec.rb +0 -433
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 22fe2305d1461bf58825e88933f215cd64fffdba
|
4
|
+
data.tar.gz: 454e2fc45afeae5b338723df845923c7f4364d10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ecf6f26241e61b34c6162c31ee1f55896a8d9bb67b01e2484db1714d1c5dfc75ce5666fad215dc8bc99d6e12d6f50fac3e81f92c9f47a5d8f26bdb43c0766d7b
|
7
|
+
data.tar.gz: 8743beb8af9bc17f9953e9488d0fc78ccb8e709a5fcbc551470926fea972e39560b6ab092faa52789109ff796b7309f45bba9844e395c1e2cc0f3c10d94b27b8
|
data/README.md
CHANGED
@@ -30,6 +30,371 @@ Or install it yourself as:
|
|
30
30
|
|
31
31
|
The type database is the core of the format services. It stores information about all the known formats.
|
32
32
|
|
33
|
+
### ::Libis::Format::Identifier
|
34
|
+
|
35
|
+
This class enables support for format identification. It will use 3 external tools to identify a file format:
|
36
|
+
droid, fido and the unix file tool. Based on several criteria, the results of these tools will be given a
|
37
|
+
score and the result with the highest confidence is returned. The output of all tools can also be returned.
|
38
|
+
The format identification result contains a MIME-type and a PRONOM PUID if they are known. Also the calculated
|
39
|
+
score, the tool that produced the outcome and recognition method are listed. Some tools also return more
|
40
|
+
information like the format name and format version. If these are present on the most confident output, their
|
41
|
+
values will also be part of the result info.
|
42
|
+
|
43
|
+
Unidentified files will be listed with MIME-type 'application/octet-stream' and PUID 'fmt/unknown'.
|
44
|
+
|
45
|
+
The main method #get that performs the format identification takes two parameters:
|
46
|
+
- file: can be a string representing a file or directory path, but also an array of file paths.
|
47
|
+
- options: optional hash with parameters that influence the behaviour of the format identification process
|
48
|
+
|
49
|
+
The options has accespts the following keys (Symbol types):
|
50
|
+
- :droid
|
51
|
+
Boolean if set to false will not use the Droid tool. Default: true
|
52
|
+
- :fido
|
53
|
+
Boolean if set to false will not use the Fido tool. Default: true
|
54
|
+
- :file
|
55
|
+
Boolean if set to false will not use the Unix file tool. Default: true
|
56
|
+
- :tool
|
57
|
+
Symbol either :droid, :fido or :file. A shortcut option for setting only the given value to true.
|
58
|
+
- :xml_validation
|
59
|
+
Boolean if set to false will not perform XML validation (see below)
|
60
|
+
- :recursive
|
61
|
+
Boolean if set to true and a directory is passed as first argument, Identifier will parse the
|
62
|
+
directory tree recursively and will process all files found. Default: false
|
63
|
+
- :base_dir
|
64
|
+
String. Normally file will be referenced by their absolute path in the results. If a value is
|
65
|
+
supplied for this option, the given path will be stripped from the start of the file references in the
|
66
|
+
result. Default: nil.
|
67
|
+
- :keep_output
|
68
|
+
Boolean if set will store the output of each identification tool in the result structure. Default: false
|
69
|
+
|
70
|
+
The result of the identification is a Hash with the following keys:
|
71
|
+
- :messages
|
72
|
+
a list (Array) of error and warning messages that the Identifier or one of the tools used has generated.
|
73
|
+
Each entry is another Array with the first argument the severity of the message and the second one the
|
74
|
+
message itself.
|
75
|
+
- :output
|
76
|
+
optional output of each tool as an Array with an entry per tool and grouped into a Hash by file reference.
|
77
|
+
- :formats
|
78
|
+
a Hash with file references as key and the outcome of the identification as value.
|
79
|
+
|
80
|
+
The identification outcome is a Hash of key-value pairs for each property returned. Keys are lower-case
|
81
|
+
symbols. If the tools gave results that deffer in a significant part, their outcome will be added to a list as
|
82
|
+
:alternatives (see example).
|
83
|
+
|
84
|
+
#### XML Validation
|
85
|
+
|
86
|
+
None of the tools used is able to identify an XML file by its content. In our context this is especially
|
87
|
+
annoying for EAD XML files as we want to identify them in order to process them different from the other XML
|
88
|
+
files. The Identifier solves this by performing an extra check on files identified as XML files. It will
|
89
|
+
validate each XML file against a list of XML schemas and return the matching MIME-type in the result. If the
|
90
|
+
Type Database contains an entry for this format, the result will be extended with the information from the
|
91
|
+
Type Database.
|
92
|
+
|
93
|
+
With the :xml_validation option this behaviour can be turned off, for instance in cases where no EAD files are
|
94
|
+
to be expected or no further identification of XML files is needed. Note that if no XML files are present, the
|
95
|
+
Identifier will not spend any time on XML validation anyway.
|
96
|
+
|
97
|
+
The list of validation schemas can be extended with the class method #add_xml_validation which takes two
|
98
|
+
parameters: a MIME-type and the path to an XML schema (XSD). If you want to also assign a fictuous PUID to the
|
99
|
+
XML type you should add an entry to your Type Database with the same MIME-type.
|
100
|
+
|
101
|
+
### Example
|
102
|
+
|
103
|
+
```
|
104
|
+
```
|
105
|
+
|
106
|
+
```
|
107
|
+
{
|
108
|
+
:messages => [
|
109
|
+
[0] [
|
110
|
+
[0] :debug,
|
111
|
+
[1] "XML file validated against XML Schema: [...]/data/ead.xsd"
|
112
|
+
],
|
113
|
+
[1] [
|
114
|
+
[0] :debug,
|
115
|
+
[1] "XML file validated against XML Schema: [...]/data/ead.xsd"
|
116
|
+
],
|
117
|
+
[2] [
|
118
|
+
[0] :debug,
|
119
|
+
[1] "XML file validated against XML Schema: [...]/data/ead.xsd"
|
120
|
+
]
|
121
|
+
],
|
122
|
+
:output => {
|
123
|
+
"[...]/data/Cevennes2.bmp" => [
|
124
|
+
[0] {
|
125
|
+
:matchtype => "signature",
|
126
|
+
:ext_mismatch => "false",
|
127
|
+
:puid => "fmt/116",
|
128
|
+
:mimetype => "image/bmp",
|
129
|
+
:format_name => "Windows Bitmap",
|
130
|
+
:format_version => "3.0",
|
131
|
+
:source => :droid,
|
132
|
+
:TYPE => :BMP,
|
133
|
+
:GROUP => :IMAGE,
|
134
|
+
:score => 7
|
135
|
+
},
|
136
|
+
[1] {
|
137
|
+
:puid => "fmt/116",
|
138
|
+
:format_name => "Windows Bitmap",
|
139
|
+
:format_version => "Windows Bitmap 3.0",
|
140
|
+
:mimetype => "image/bmp",
|
141
|
+
:matchtype => "signature",
|
142
|
+
:source => :fido,
|
143
|
+
:TYPE => :BMP,
|
144
|
+
:GROUP => :IMAGE,
|
145
|
+
:score => 7
|
146
|
+
},
|
147
|
+
[2] {
|
148
|
+
:mimetype => "image/bmp",
|
149
|
+
:matchtype => "magic",
|
150
|
+
:source => :file,
|
151
|
+
:TYPE => :BMP,
|
152
|
+
:GROUP => :IMAGE,
|
153
|
+
:score => 2
|
154
|
+
}
|
155
|
+
],
|
156
|
+
"[...]/data/Cevennes2.jp2" => [
|
157
|
+
[0] {
|
158
|
+
:matchtype => "signature",
|
159
|
+
:ext_mismatch => "false",
|
160
|
+
:puid => "x-fmt/392",
|
161
|
+
:mimetype => "image/jp2",
|
162
|
+
:format_name => "JP2 (JPEG 2000 part 1)",
|
163
|
+
:format_version => "",
|
164
|
+
:source => :droid,
|
165
|
+
:TYPE => :JP2,
|
166
|
+
:GROUP => :IMAGE,
|
167
|
+
:score => 7
|
168
|
+
},
|
169
|
+
[1] {
|
170
|
+
:puid => "x-fmt/392",
|
171
|
+
:format_name => "JP2 (JPEG 2000 part 1)",
|
172
|
+
:format_version => "JPEG2000",
|
173
|
+
:mimetype => "image/jp2",
|
174
|
+
:matchtype => "signature",
|
175
|
+
:source => :fido,
|
176
|
+
:TYPE => :JP2,
|
177
|
+
:GROUP => :IMAGE,
|
178
|
+
:score => 7
|
179
|
+
},
|
180
|
+
[2] {
|
181
|
+
:mimetype => "image/jp2",
|
182
|
+
:matchtype => "magic",
|
183
|
+
:source => :file,
|
184
|
+
:TYPE => :JP2,
|
185
|
+
:GROUP => :IMAGE,
|
186
|
+
:score => 2
|
187
|
+
}
|
188
|
+
],
|
189
|
+
[...]
|
190
|
+
},
|
191
|
+
:formats => {
|
192
|
+
"[...]/data/Cevennes2.bmp" => {
|
193
|
+
:matchtype => "signature",
|
194
|
+
:ext_mismatch => "false",
|
195
|
+
:puid => "fmt/116",
|
196
|
+
:mimetype => "image/bmp",
|
197
|
+
:format_name => "Windows Bitmap",
|
198
|
+
:format_version => "3.0",
|
199
|
+
:source => :droid,
|
200
|
+
:TYPE => :BMP,
|
201
|
+
:GROUP => :IMAGE,
|
202
|
+
:score => 7
|
203
|
+
},
|
204
|
+
"[...]/data/Cevennes2.jp2" => {
|
205
|
+
:matchtype => "signature",
|
206
|
+
:ext_mismatch => "false",
|
207
|
+
:puid => "x-fmt/392",
|
208
|
+
:mimetype => "image/jp2",
|
209
|
+
:format_name => "JP2 (JPEG 2000 part 1)",
|
210
|
+
:format_version => "JPEG2000",
|
211
|
+
:source => :droid,
|
212
|
+
:TYPE => :JP2,
|
213
|
+
:GROUP => :IMAGE,
|
214
|
+
:score => 7
|
215
|
+
},
|
216
|
+
"[...]/data/NikonRaw-CameraRaw.TIF" => {
|
217
|
+
:matchtype => "signature",
|
218
|
+
:ext_mismatch => "false",
|
219
|
+
:puid => "fmt/353",
|
220
|
+
:mimetype => "image/tiff",
|
221
|
+
:format_name => "Tagged Image File Format",
|
222
|
+
:format_version => "TIFF generic (little-endian)",
|
223
|
+
:source => :droid,
|
224
|
+
:TYPE => :TIFF,
|
225
|
+
:GROUP => :IMAGE,
|
226
|
+
:score => 7
|
227
|
+
},
|
228
|
+
"[...]/data/NikonRaw-CaptureOne.tif" => {
|
229
|
+
:matchtype => "signature",
|
230
|
+
:ext_mismatch => "false",
|
231
|
+
:puid => "x-fmt/387",
|
232
|
+
:mimetype => "image/tiff",
|
233
|
+
:format_name => "Exchangeable Image File Format (Uncompressed)",
|
234
|
+
:format_version => "2.2",
|
235
|
+
:source => :droid,
|
236
|
+
:TYPE => :TIFF,
|
237
|
+
:GROUP => :IMAGE,
|
238
|
+
:score => 7,
|
239
|
+
:alternatives => [
|
240
|
+
[0] {
|
241
|
+
:puid => "fmt/353",
|
242
|
+
:format_name => "Tagged Image File Format",
|
243
|
+
:format_version => "TIFF generic (little-endian)",
|
244
|
+
:mimetype => "image/tiff",
|
245
|
+
:matchtype => "signature",
|
246
|
+
:source => :fido,
|
247
|
+
:TYPE => :TIFF,
|
248
|
+
:GROUP => :IMAGE,
|
249
|
+
:score => 7
|
250
|
+
},
|
251
|
+
[1] {
|
252
|
+
:matchtype => "signature",
|
253
|
+
:ext_mismatch => "false",
|
254
|
+
:puid => "x-fmt/387",
|
255
|
+
:mimetype => "image/tiff",
|
256
|
+
:format_name => "Exchangeable Image File Format (Uncompressed)",
|
257
|
+
:format_version => "2.2",
|
258
|
+
:source => :droid,
|
259
|
+
:TYPE => :TIFF,
|
260
|
+
:GROUP => :IMAGE,
|
261
|
+
:score => 7
|
262
|
+
}
|
263
|
+
]
|
264
|
+
},
|
265
|
+
"[...]/data/test-ead.xml" => {
|
266
|
+
:matchtype => "signature",
|
267
|
+
:ext_mismatch => "false",
|
268
|
+
:puid => "fmt/101",
|
269
|
+
:mimetype => "archive/ead",
|
270
|
+
:format_name => "Encoded Archival Description (EAD)",
|
271
|
+
:format_version => "",
|
272
|
+
:source => :xsd_validation,
|
273
|
+
:TYPE => :EAD,
|
274
|
+
:GROUP => :ARCHIVE,
|
275
|
+
:score => 7,
|
276
|
+
:tool => :droid,
|
277
|
+
:match_type => "xsd_validation"
|
278
|
+
},
|
279
|
+
"[...]/data/test.doc" => {
|
280
|
+
:matchtype => "container",
|
281
|
+
:ext_mismatch => "false",
|
282
|
+
:puid => "fmt/40",
|
283
|
+
:mimetype => "application/msword",
|
284
|
+
:format_name => "Microsoft Word Document",
|
285
|
+
:format_version => "97-2003",
|
286
|
+
:source => :droid,
|
287
|
+
:TYPE => :MSDOC,
|
288
|
+
:GROUP => :TEXT,
|
289
|
+
:score => 9,
|
290
|
+
:alternatives => [
|
291
|
+
[0] {
|
292
|
+
:matchtype => "container",
|
293
|
+
:ext_mismatch => "false",
|
294
|
+
:puid => "fmt/40",
|
295
|
+
:mimetype => "application/msword",
|
296
|
+
:format_name => "Microsoft Word Document",
|
297
|
+
:format_version => "97-2003",
|
298
|
+
:source => :droid,
|
299
|
+
:TYPE => :MSDOC,
|
300
|
+
:GROUP => :TEXT,
|
301
|
+
:score => 9
|
302
|
+
},
|
303
|
+
[1] {
|
304
|
+
:puid => "fmt/111",
|
305
|
+
:format_name => "OLE2 Compound Document Format",
|
306
|
+
:format_version => "OLE2 Compound Document Format",
|
307
|
+
:mimetype => nil,
|
308
|
+
:matchtype => "signature",
|
309
|
+
:source => :fido,
|
310
|
+
:score => 3
|
311
|
+
}
|
312
|
+
]
|
313
|
+
},
|
314
|
+
"[...]/data/test.docx" => {
|
315
|
+
:matchtype => "container",
|
316
|
+
:ext_mismatch => "false",
|
317
|
+
:puid => "fmt/412",
|
318
|
+
:mimetype => "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
319
|
+
:format_name => "Microsoft Word for Windows",
|
320
|
+
:format_version => "2007 onwards",
|
321
|
+
:source => :droid,
|
322
|
+
:TYPE => :MSDOCX,
|
323
|
+
:GROUP => :TEXT,
|
324
|
+
:score => 9
|
325
|
+
},
|
326
|
+
"[...]/data/test.xlsx" => {
|
327
|
+
:matchtype => "container",
|
328
|
+
:ext_mismatch => "false",
|
329
|
+
:puid => "fmt/214",
|
330
|
+
:mimetype => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
331
|
+
:format_name => "Microsoft Excel for Windows",
|
332
|
+
:format_version => "2007 onwards",
|
333
|
+
:source => :droid,
|
334
|
+
:TYPE => :MSXLSX,
|
335
|
+
:GROUP => :TABULAR,
|
336
|
+
:score => 9,
|
337
|
+
:alternatives => [
|
338
|
+
[0] {
|
339
|
+
:matchtype => "container",
|
340
|
+
:ext_mismatch => "false",
|
341
|
+
:puid => "fmt/214",
|
342
|
+
:mimetype => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
343
|
+
:format_name => "Microsoft Excel for Windows",
|
344
|
+
:format_version => "2007 onwards",
|
345
|
+
:source => :droid,
|
346
|
+
:TYPE => :MSXLSX,
|
347
|
+
:GROUP => :TABULAR,
|
348
|
+
:score => 9
|
349
|
+
},
|
350
|
+
[1] {
|
351
|
+
:mimetype => "application/octet-stream",
|
352
|
+
:matchtype => "magic",
|
353
|
+
:source => :file,
|
354
|
+
:score => -2
|
355
|
+
}
|
356
|
+
]
|
357
|
+
},
|
358
|
+
"[...]/data/test_pdfa.pdf" => {
|
359
|
+
:matchtype => "signature",
|
360
|
+
:ext_mismatch => "false",
|
361
|
+
:puid => "fmt/354",
|
362
|
+
:mimetype => "application/pdf",
|
363
|
+
:format_name => "Acrobat PDF/A - Portable Document Format",
|
364
|
+
:format_version => "1b",
|
365
|
+
:source => :droid,
|
366
|
+
:TYPE => :PDFA,
|
367
|
+
:GROUP => :TEXT,
|
368
|
+
:score => 7,
|
369
|
+
:alternatives => [
|
370
|
+
[0] {
|
371
|
+
:puid => "fmt/19",
|
372
|
+
:format_name => "Acrobat PDF 1.5 - Portable Document Format",
|
373
|
+
:format_version => "PDF 1.5",
|
374
|
+
:mimetype => "application/pdf",
|
375
|
+
:matchtype => "signature",
|
376
|
+
:source => :fido,
|
377
|
+
:TYPE => :PDF,
|
378
|
+
:GROUP => :TEXT,
|
379
|
+
:score => 7
|
380
|
+
},
|
381
|
+
[1] {
|
382
|
+
:matchtype => "signature",
|
383
|
+
:ext_mismatch => "false",
|
384
|
+
:puid => "fmt/354",
|
385
|
+
:mimetype => "application/pdf",
|
386
|
+
:format_name => "Acrobat PDF/A - Portable Document Format",
|
387
|
+
:format_version => "1b",
|
388
|
+
:source => :droid,
|
389
|
+
:TYPE => :PDFA,
|
390
|
+
:GROUP => :TEXT,
|
391
|
+
:score => 7
|
392
|
+
}
|
393
|
+
]
|
394
|
+
}
|
395
|
+
}
|
396
|
+
}
|
397
|
+
```
|
33
398
|
## Contributing
|
34
399
|
|
35
400
|
1. Fork it ( https://github.com/Kris-LIBIS/LIBIS_Format/fork )
|
data/bin/droid
CHANGED
data/bin/fido
CHANGED
data/bin/pdf_copy
CHANGED
data/lib/libis/format/config.rb
CHANGED
@@ -22,6 +22,7 @@ module Libis
|
|
22
22
|
Config[:xml_validations] = [['archive/ead', File.join(data_dir, 'ead.xsd')]]
|
23
23
|
Config[:type_database] = File.join(data_dir, 'types.yml')
|
24
24
|
Config[:raw_audio_convert_cmd] = 'sox %s -e signed -b 16 -t wav %s rate %d channels %d'
|
25
|
+
Config[:watermark_font] = '/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf'
|
25
26
|
|
26
27
|
end
|
27
28
|
end
|
@@ -168,7 +168,7 @@ module Libis
|
|
168
168
|
opts[:output] << '-ar' << @options[:sampling_freq] if @options[:sampling_freq]
|
169
169
|
opts[:output] << '-ac' << @options[:channels] if @options[:channels]
|
170
170
|
opts[:output] << '-f' << @options[:format] if @options[:format]
|
171
|
-
result = Libis::Format::FFMpeg.run(source, target, opts)
|
171
|
+
result = Libis::Format::Tool::FFMpeg.run(source, target, opts)
|
172
172
|
info "FFMpeg output: #{result}"
|
173
173
|
result
|
174
174
|
target
|
@@ -3,6 +3,7 @@
|
|
3
3
|
### require 'tools/string'
|
4
4
|
require 'tmpdir'
|
5
5
|
require 'libis/tools/logger'
|
6
|
+
require 'libis/tools/temp_file'
|
6
7
|
require 'libis/format/type_database'
|
7
8
|
|
8
9
|
require_relative 'repository'
|
@@ -43,7 +44,7 @@ module Libis
|
|
43
44
|
end
|
44
45
|
|
45
46
|
def Base.using_temp(target)
|
46
|
-
tempfile =
|
47
|
+
tempfile = Tools::TempFile.name("convert-#{File.basename(target, '.*').gsub(/\s/, '_')}", File.extname(target))
|
47
48
|
result = yield tempfile
|
48
49
|
return nil unless result
|
49
50
|
FileUtils.move result, target
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative 'base'
|
4
4
|
|
5
|
-
require 'libis/format/office_to_pdf'
|
5
|
+
require 'libis/format/tool/office_to_pdf'
|
6
6
|
require 'libis/format/type_database'
|
7
7
|
|
8
8
|
module Libis
|
@@ -38,7 +38,7 @@ module Libis
|
|
38
38
|
def convert(source, target, format, opts = {})
|
39
39
|
super
|
40
40
|
|
41
|
-
return nil unless OfficeToPdf.run(source, target)
|
41
|
+
return nil unless Format::Tool::OfficeToPdf.run(source, target)
|
42
42
|
|
43
43
|
target
|
44
44
|
|
@@ -3,9 +3,9 @@
|
|
3
3
|
require_relative 'base'
|
4
4
|
|
5
5
|
require 'libis/tools/extend/hash'
|
6
|
-
require 'libis/format/pdf_copy'
|
7
|
-
require 'libis/format/pdf_to_pdfa'
|
8
|
-
require 'libis/format/pdf_optimizer'
|
6
|
+
require 'libis/format/tool/pdf_copy'
|
7
|
+
require 'libis/format/tool/pdf_to_pdfa'
|
8
|
+
require 'libis/format/tool/pdf_optimizer'
|
9
9
|
|
10
10
|
module Libis
|
11
11
|
module Format
|
@@ -126,7 +126,7 @@ module Libis
|
|
126
126
|
def optimize_pdf(source, target, quality)
|
127
127
|
|
128
128
|
using_temp(target) do |tmpname|
|
129
|
-
result = Libis::Format::PdfOptimizer.run(source, tmpname, quality)
|
129
|
+
result = Libis::Format::Tool::PdfOptimizer.run(source, tmpname, quality)
|
130
130
|
unless result[:status] == 0
|
131
131
|
error("Pdf optimization encountered errors:\n%s", (result[:err] + result[:out]).join('\n'))
|
132
132
|
next nil
|
@@ -138,7 +138,7 @@ module Libis
|
|
138
138
|
def convert_pdf(source, target)
|
139
139
|
|
140
140
|
using_temp(target) do |tmpname|
|
141
|
-
result = Libis::Format::PdfCopy.run(
|
141
|
+
result = Libis::Format::Tool::PdfCopy.run(
|
142
142
|
source, tmpname,
|
143
143
|
@options.map { |k, v|
|
144
144
|
if v.nil?
|
@@ -159,7 +159,7 @@ module Libis
|
|
159
159
|
def pdf_to_pdfa(source, target)
|
160
160
|
|
161
161
|
using_temp(target) do |tmpname|
|
162
|
-
result = Libis::Format::PdfToPdfa.run source, tmpname
|
162
|
+
result = Libis::Format::Tool::PdfToPdfa.run source, tmpname
|
163
163
|
unless result[:status] == 0
|
164
164
|
error("Pdf/A conversion encountered errors:\n%s", result[:err].join('\n'))
|
165
165
|
next nil
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative 'base'
|
2
|
-
require 'libis/format/ffmpeg'
|
2
|
+
require 'libis/format/tool/ffmpeg'
|
3
3
|
|
4
4
|
require 'fileutils'
|
5
5
|
|
@@ -82,6 +82,49 @@ module Libis
|
|
82
82
|
@options[:scale] = width_x_height
|
83
83
|
end
|
84
84
|
|
85
|
+
# @param [String] file Image file path to use as watermark
|
86
|
+
def watermark_image(file)
|
87
|
+
@options[:watermark_image] = file
|
88
|
+
end
|
89
|
+
|
90
|
+
# @param [String] value text for watermark. No watermark if nil (default)
|
91
|
+
def watermark_text(value)
|
92
|
+
@options[:watermark_text] = value
|
93
|
+
end
|
94
|
+
|
95
|
+
# @param [Integer] value Font size for watermark text. Default: 10
|
96
|
+
# Note that the font is selected by the Config[:watermark_font] setting
|
97
|
+
def watermark_text_size(value)
|
98
|
+
@options[:watermark_text_size] = value.to_i
|
99
|
+
end
|
100
|
+
|
101
|
+
# @param [String] value Text color for the watermark text. Default: white
|
102
|
+
def watermark_text_color(value)
|
103
|
+
@options[:watermark_text_color] = value
|
104
|
+
end
|
105
|
+
|
106
|
+
# @param [String] value Text color for the watermark text shadow. Default: black
|
107
|
+
def watermark_text_shadow_color(value)
|
108
|
+
@options[:watermark_text_shadow_color] = value
|
109
|
+
end
|
110
|
+
|
111
|
+
# @param [Integer] value Offset of the watermark text shadow. Used for both x and y offset; default: 1
|
112
|
+
# If the offset is set to 0, no shadow will be printed
|
113
|
+
def watermark_text_shadow_offset(value)
|
114
|
+
@options[:watermark_text_offset] = value.to_i
|
115
|
+
end
|
116
|
+
|
117
|
+
# @param [String] value one of 'bottom_left' (default), 'top_left', 'bottom_right', 'top_right', 'center'
|
118
|
+
def watermark_position(value)
|
119
|
+
@options[:watermark_position] = value
|
120
|
+
end
|
121
|
+
|
122
|
+
# @param [Number] value watermark opacity (0-1) with 0 = invisible and 1 = 100% opaque. Default: 0.5
|
123
|
+
def watermark_opacity(value)
|
124
|
+
@options[:watermark_opacity] = value.to_f
|
125
|
+
end
|
126
|
+
|
127
|
+
# @param [Boolean] value If set to true automatically selects optimal format for web viewing. Default: false
|
85
128
|
def web_stream(value)
|
86
129
|
if value
|
87
130
|
@options[:video_codec] = 'h264'
|
@@ -89,14 +132,17 @@ module Libis
|
|
89
132
|
end
|
90
133
|
end
|
91
134
|
|
135
|
+
# @param [String] name name of a preset. See FFMpeg documentation for more info
|
92
136
|
def preset(name)
|
93
137
|
@options[:preset] = name
|
94
138
|
end
|
95
139
|
|
140
|
+
# @param [String] name name of an audio preset. See FFMpeg documentation for more info
|
96
141
|
def audio_preset(name)
|
97
142
|
@options[:audio_preset] = name
|
98
143
|
end
|
99
144
|
|
145
|
+
# @param [String] name name of a video preset. See FFMpeg documentation for more info
|
100
146
|
def video_preset(name)
|
101
147
|
@options[:video_preset] = name
|
102
148
|
end
|
@@ -163,6 +209,36 @@ module Libis
|
|
163
209
|
opts = {global: [], input: [], filter: [], output: []}
|
164
210
|
opts[:global] << '-hide_banner'
|
165
211
|
opts[:global] << '-loglevel' << (@options[:quiet] ? 'fatal' : 'warning')
|
212
|
+
|
213
|
+
# Watermark info
|
214
|
+
@options[:watermark_opacity] ||= 0.5
|
215
|
+
if @options[:watermark_image]
|
216
|
+
opts[:filter] << '-i' << @options[:watermark_image] << '-filter_complex'
|
217
|
+
opts[:filter] << "[1:v]format=argb,colorchannelmixer=aa=%f[wm];[0:v][wm]overlay=%s" %
|
218
|
+
[@options[:watermark_opacity], watermark_position_text]
|
219
|
+
elsif @options[:watermark_text]
|
220
|
+
@options[:watermark_text_size] ||= 10
|
221
|
+
@options[:watermark_text_color] ||= 'white'
|
222
|
+
@options[:watermark_text_shadow_color] ||= 'black'
|
223
|
+
@options[:watermark_text_shadow_offset] ||= 1
|
224
|
+
filter_text = "drawtext=text='%s':%s:fontfile=%s:fontsize=%d:fontcolor=%s@%f" %
|
225
|
+
[
|
226
|
+
@options[:watermark_text],
|
227
|
+
watermark_position_text(true),
|
228
|
+
Config[:watermark_font],
|
229
|
+
@options[:watermark_text_size],
|
230
|
+
@options[:watermark_text_color],
|
231
|
+
@options[:watermark_opacity]
|
232
|
+
]
|
233
|
+
filter_text += ':shadowcolor=%s@%f:shadowx=%d:shadowy=%d' %
|
234
|
+
[
|
235
|
+
@options[:watermark_text_shadow_color],
|
236
|
+
@options[:watermark_opacity],
|
237
|
+
@options[:watermark_text_shadow_offset],
|
238
|
+
@options[:watermark_text_shadow_offset]
|
239
|
+
] if @options[:watermark_text_shadow_offset] > 0
|
240
|
+
opts[:filter] << '-vf' << filter_text
|
241
|
+
end
|
166
242
|
opts[:output] << '-ac' << @options[:audio_channels] if @options[:audio_channels]
|
167
243
|
opts[:output] << '-c:a' << @options[:audio_codec] if @options[:audio_codec]
|
168
244
|
opts[:output] << '-c:v' << @options[:video_codec] if @options[:video_codec]
|
@@ -188,11 +264,29 @@ module Libis
|
|
188
264
|
opts[:output] << '-pre' << @options[:preset] if @options[:preset]
|
189
265
|
opts[:output] << '-apre' << @options[:audio_preset] if @options[:audio_preset]
|
190
266
|
opts[:output] << '-vpre' << @options[:video_preset] if @options[:video_preset]
|
191
|
-
|
267
|
+
info "FFMpeg options: #{opts}"
|
268
|
+
result = Libis::Format::Tool::FFMpeg.run(source, target, opts)
|
192
269
|
info "FFMpeg output: #{result}"
|
193
270
|
target
|
194
271
|
end
|
195
272
|
|
273
|
+
def watermark_position_text(for_text = false, margin = 10)
|
274
|
+
w = for_text ? 'tw' : 'w'
|
275
|
+
h = for_text ? 'th' : 'h'
|
276
|
+
case @options[:watermark_position]
|
277
|
+
when 'bottom_left'
|
278
|
+
"x=#{margin}:y=H-#{h}-#{margin}"
|
279
|
+
when 'top_left'
|
280
|
+
"x=#{margin}:y=#{margin}"
|
281
|
+
when 'bottom_right'
|
282
|
+
"x=W-#{w}-#{margin}:y=H-#{h}-#{margin}"
|
283
|
+
when 'top_right'
|
284
|
+
"x=W-#{w}-#{margin}:y=#{margin}"
|
285
|
+
else
|
286
|
+
"x=#{margin}:y=H-#{h}-#{margin}"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
196
290
|
end
|
197
291
|
|
198
292
|
end
|