file_pipeline 0.0.7 → 0.0.8
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.rdoc +40 -19
- data/lib/file_pipeline/errors/failed_modification_error.rb +3 -3
- data/lib/file_pipeline/file_operations/default_operations/exif_recovery.rb +53 -0
- data/lib/file_pipeline/file_operations/default_operations/exif_restoration.rb +9 -9
- data/lib/file_pipeline/file_operations/exif_manipulable.rb +4 -0
- data/lib/file_pipeline/file_operations/file_operation.rb +11 -2
- data/lib/file_pipeline/versioned_file.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d91b7a6c23d1882671966e17afc994e18ccb2d5aa26105d9759e8b37ee393109
|
4
|
+
data.tar.gz: adeea178ac4e331b837a014b91572b1e498f215f3d81b854b1744dc8738eb113
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5671985f69f7600efd16bbc4ad9ff56c815268deb0ef3f4f76dacc9de56c422a3e8f8a35b1d4c1b52c707144b8287ef64c7b91d773b3d4d6be8c0dd235ffb93
|
7
|
+
data.tar.gz: ba7d56495aca8c56cce1bea10f27467703f4c1121632ce34de07b6f7e693c3b0648e6b4fb4c7c213d07ff1649c1248c29f6eae971b813c2c78655d766af6387d
|
data/README.rdoc
CHANGED
@@ -248,8 +248,7 @@ The <tt>#initialize</tt> method _must_ take an +options+ argument (a hash
|
|
248
248
|
with a default value, or a <em>double splat</em>) and _must_ be exposed
|
249
249
|
through an <tt>#options</tt> getter method.
|
250
250
|
|
251
|
-
The options passed can be any
|
252
|
-
a specific instance of a method.
|
251
|
+
The options passed can be any to properly configure an instance of the class.
|
253
252
|
|
254
253
|
This requirement is imposed by the
|
255
254
|
{#define_operation}[rdoc-ref:FilePipeline::Pipeline#define_operation] instance
|
@@ -296,20 +295,26 @@ The three arguments required for implementations of <tt>#run</tt> are:
|
|
296
295
|
succession of modified versions has been created.
|
297
296
|
|
298
297
|
The <em>original file</em> will only be used by file operations that require
|
299
|
-
it for reference, e.g. to restore file metadata that was compromised
|
300
|
-
other file operations.
|
298
|
+
it for reference, e.g. to restore or recover file metadata that was compromised
|
299
|
+
by other file operations.
|
301
300
|
|
302
301
|
===== Return value
|
303
302
|
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
303
|
+
If the operation modifies the file (i.e. creates a new version), the +run+
|
304
|
+
method _must_ return the path to the file that was created (perferrably in the
|
305
|
+
_directory_). If it does not modify and no results are returned, it _must_
|
306
|
+
return +nil+.
|
307
|
+
|
308
|
+
The method _may_ return a
|
309
|
+
{Results}[rdoc-ref:FilePipeline::FileOperations::Results] object along with the
|
310
|
+
path or +nil+. The results object should contain the operation itself, a
|
311
|
+
_success_ flag (+true+ or +false+), and any logs or data returned by the
|
312
|
+
operation.
|
309
313
|
|
310
314
|
If results are returned with the path to the created file, both values must
|
311
315
|
be wrapped in an array, with the path as the first element, the results as
|
312
|
-
the second.
|
316
|
+
the second. If the operation does not modify and therefore not return a path,
|
317
|
+
the first element of the array must be +nil+.
|
313
318
|
|
314
319
|
===== Example
|
315
320
|
|
@@ -367,15 +372,21 @@ logic to perform the actual file operation, but will call an
|
|
367
372
|
{#operation method}[rdoc-label:label-The+operation+method] that _must_ be
|
368
373
|
defined in the subclass unless the subclass overrides the <tt>#run</tt> method.
|
369
374
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
extension. The default behavior is to
|
374
|
-
same as for the file that was passed in as
|
375
|
-
version will be created. If the operation will
|
376
|
-
type, the subclass _should_ define a
|
377
|
-
returns the appropriate file extension
|
378
|
-
{Target file extensions}[rdoc-label:label-Target+file+extensions]).
|
375
|
+
If the operation is modifying (creates a new version), the <tt>#run</tt> method
|
376
|
+
will generate the new path that is passed to the <tt>#operation</tt> method,
|
377
|
+
and to which the latter will write the new version of the file. The new file
|
378
|
+
path will need an appropriate file type extension. The default behavior is to
|
379
|
+
assume that the extension will be the same as for the file that was passed in as
|
380
|
+
the basis from which the new version will be created. If the operation will
|
381
|
+
result in a different file type, the subclass _should_ define a
|
382
|
+
<tt>#target_extension</tt> method that returns the appropriate file extension
|
383
|
+
(see {Target file extensions}[rdoc-label:label-Target+file+extensions]).
|
384
|
+
|
385
|
+
Subclasses of FileOperation are by default modifying. If the operation is not
|
386
|
+
modifying (does not create a new version of the file), the subclass _must_
|
387
|
+
override the <tt>#modiies?</tt> method or override the <tt>#run</tt> method to
|
388
|
+
ensure it does not return a file path (see
|
389
|
+
{Non-modifying operations}[rdoc-label:label-Non-modifying+operations]).
|
379
390
|
|
380
391
|
==== Initializer
|
381
392
|
|
@@ -490,6 +501,16 @@ return the appropriate
|
|
490
501
|
return
|
491
502
|
end
|
492
503
|
|
504
|
+
==== Non-modifying operations
|
505
|
+
|
506
|
+
If the operation will not create a new version, the class _must_ redefine the
|
507
|
+
<tt>#modifies?</tt> method to return +false+:
|
508
|
+
|
509
|
+
# non-modiyfing operation
|
510
|
+
def modifies?
|
511
|
+
false
|
512
|
+
end
|
513
|
+
|
493
514
|
==== Target file extensions
|
494
515
|
|
495
516
|
If the file that the operation creates is of a different type than the file
|
@@ -12,7 +12,7 @@ module FilePipeline
|
|
12
12
|
#
|
13
13
|
# ===== Arguments
|
14
14
|
#
|
15
|
-
# * +msg+ - error message for the exception. If none provided, the
|
15
|
+
# * +msg+ - error message for the exception. If none provided, the
|
16
16
|
# instance will be initialized with the #default_message.
|
17
17
|
#
|
18
18
|
# ===== Options
|
@@ -38,7 +38,7 @@ module FilePipeline
|
|
38
38
|
|
39
39
|
private
|
40
40
|
|
41
|
-
# Appends the backtrace of the error that caused the exception to the
|
41
|
+
# Appends the backtrace of the error that caused the exception to the
|
42
42
|
# #default_message.
|
43
43
|
def append_backtrace(str)
|
44
44
|
return str + "\n" unless original_backtrace
|
@@ -46,7 +46,7 @@ module FilePipeline
|
|
46
46
|
str + " Backtrace:\n#{original_backtrace}"
|
47
47
|
end
|
48
48
|
|
49
|
-
# Appends the message of the error that caused the exception to the
|
49
|
+
# Appends the message of the error that caused the exception to the
|
50
50
|
# #default_message.
|
51
51
|
def append_error(str)
|
52
52
|
return str unless original_error
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FilePipeline
|
4
|
+
module FileOperations
|
5
|
+
# A non-modifying FileOperation that compares a file's _Exif_ Metadata with
|
6
|
+
# that of a reference file and returns tags missing in the working file as
|
7
|
+
# captured data.
|
8
|
+
#
|
9
|
+
# Used to recover _Exif_ tags that were not preserved during e.g. a file
|
10
|
+
# conversion.
|
11
|
+
class ExifRecovery < FileOperation
|
12
|
+
include ExifManipulable
|
13
|
+
|
14
|
+
# :args: options
|
15
|
+
#
|
16
|
+
# Returns a new instance.
|
17
|
+
#
|
18
|
+
# ===== Options
|
19
|
+
#
|
20
|
+
# * <tt>skip_tags</tt> - _Exif_ tags to be ignored during comparison.
|
21
|
+
#
|
22
|
+
# The ExifManipulable mixin defines a set of _Exif_
|
23
|
+
# {tags}[rdoc-ref:FilePipeline::FileOperations::ExifManipulable.file_tags]
|
24
|
+
# that will always be ignored.
|
25
|
+
def initialize(**opts)
|
26
|
+
defaults = { skip_tags: [] }
|
27
|
+
super(opts, defaults)
|
28
|
+
@options[:skip_tags] += ExifManipulable.file_tags
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the DROPPED_EXIF_DATA tag defined in CapturedDataTags.
|
32
|
+
#
|
33
|
+
# Instances of ExifRecovery will capture any _Exif_ tags and their values
|
34
|
+
# that are present in the reference file but missing in the working file.
|
35
|
+
def captured_data_tag
|
36
|
+
CapturedDataTags::DROPPED_EXIF_DATA
|
37
|
+
end
|
38
|
+
|
39
|
+
# Instances of ExifRecovery do not modify the working file.
|
40
|
+
def modifies?
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
# Compares the _Exif_ metadata of <tt>src_file</tt> with that of
|
45
|
+
# +original+ and returns all tags that are present in +original+ but
|
46
|
+
# missing in <tt>src_file</tt>.
|
47
|
+
def operation(src_file, _, original)
|
48
|
+
original_exif, src_file_exif = read_exif original, src_file
|
49
|
+
missing_exif_fields(src_file_exif, original_exif)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
module FilePipeline
|
4
4
|
module FileOperations
|
5
|
-
# A FileOperation that compares Exif Metadata
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# A modifying FileOperation that compares a file's Exif Metadata with that
|
6
|
+
# of a reference file and attempts to copy tags missing in the working file
|
7
|
+
# from the reference file.
|
8
|
+
#
|
9
|
+
# Used to restore Exif tags that were not preserved during e.g. a file
|
10
|
+
# conversion.
|
8
11
|
#
|
9
12
|
# *Caveat:* if this operation is applied to a file together with
|
10
13
|
# ExifRedaction, it should be applied _before_ the latter, to avoid
|
@@ -20,10 +23,9 @@ module FilePipeline
|
|
20
23
|
#
|
21
24
|
# * <tt>skip_tags</tt> - _Exif_ tags to be ignored during restoration.
|
22
25
|
#
|
23
|
-
# The ExifManipulable mixin defines a set of _Exif_
|
24
|
-
#
|
25
|
-
#
|
26
|
-
# such as file format conversions.
|
26
|
+
# The ExifManipulable mixin defines a set of _Exif_
|
27
|
+
# {tags}[rdoc-ref:FilePipeline::FileOperations::ExifManipulable.file_tags]
|
28
|
+
# that will always be ignored.
|
27
29
|
def initialize(**opts)
|
28
30
|
defaults = { skip_tags: [] }
|
29
31
|
super(opts, defaults)
|
@@ -38,8 +40,6 @@ module FilePipeline
|
|
38
40
|
CapturedDataTags::DROPPED_EXIF_DATA
|
39
41
|
end
|
40
42
|
|
41
|
-
# :args: src_file, out_file
|
42
|
-
#
|
43
43
|
# Writes a new version of <tt>src_file</tt> to <tt>out_file</tt> with all
|
44
44
|
# writable _Exif_ tags from +original+ restored.
|
45
45
|
#
|
@@ -9,6 +9,10 @@ module FilePipeline
|
|
9
9
|
# Returns an Array of tags to be ignored during comparison. These can
|
10
10
|
# be merged with an ExifManipulable including FileOperation's options
|
11
11
|
# to skip tags (e.g. the <tt>skip_tags</tt> option in ExifRestoration).
|
12
|
+
#
|
13
|
+
# The included tags relate to the file properties (e.g. filesize,
|
14
|
+
# MIME-type) that will have been altered by any prior operation, such as
|
15
|
+
# file format conversions.
|
12
16
|
def self.file_tags
|
13
17
|
%w[FileSize FileModifyDate FileAccessDate FileInodeChangeDate
|
14
18
|
FilePermissions FileType FileTypeExtension MIMEType]
|
@@ -18,6 +18,9 @@ module FilePipeline
|
|
18
18
|
# that is passed to #run or #operation as <tt>src_file</tt>, the subclass
|
19
19
|
# must have a #target_extension method that returns the appropriate
|
20
20
|
# extension.
|
21
|
+
#
|
22
|
+
# If the operation is non-modifying, the subclass must redefine the
|
23
|
+
# #modifies? methods to return +false+.
|
21
24
|
class FileOperation
|
22
25
|
# A Hash; any options used when performing #operation.
|
23
26
|
attr_reader :options
|
@@ -62,6 +65,12 @@ module FilePipeline
|
|
62
65
|
results false, log_data
|
63
66
|
end
|
64
67
|
|
68
|
+
# Returns +true+ if the FIleOperation will create a new version.
|
69
|
+
# _Default:_ +true+.
|
70
|
+
def modifies?
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
65
74
|
# Returns the class name (string) of +self+ _without_ the names of the
|
66
75
|
# modules that the class is nested in.
|
67
76
|
def name
|
@@ -133,11 +142,11 @@ module FilePipeline
|
|
133
142
|
# e.g. when exif metadata tags missing in the <tt>src_file</tt> are to
|
134
143
|
# be copied over from another file.
|
135
144
|
def run(src_file, directory, original = nil)
|
136
|
-
out_file = target directory, extension(src_file)
|
145
|
+
out_file = target directory, extension(src_file) if modifies?
|
137
146
|
log_data = operation src_file, out_file, original
|
138
147
|
[out_file, success(log_data)]
|
139
148
|
rescue StandardError => e
|
140
|
-
FileUtils.rm out_file if File.exist?
|
149
|
+
FileUtils.rm out_file if out_file && File.exist?(out_file)
|
141
150
|
[out_file, failure(e)]
|
142
151
|
end
|
143
152
|
|
@@ -198,6 +198,7 @@ module FilePipeline
|
|
198
198
|
# FileOperations::CapturedDataTags::DROPPED_EXIF_DATA has been merged.
|
199
199
|
def recovered_metadata
|
200
200
|
return unless changed?
|
201
|
+
|
201
202
|
captured_data_with(FileOperations::CapturedDataTags::DROPPED_EXIF_DATA)
|
202
203
|
&.reduce({}) { |recovered, data| recovered.merge data }
|
203
204
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: file_pipeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Stein
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_exiftool
|
@@ -55,6 +55,7 @@ files:
|
|
55
55
|
- lib/file_pipeline/errors/source_file_error.rb
|
56
56
|
- lib/file_pipeline/file_operations.rb
|
57
57
|
- lib/file_pipeline/file_operations/captured_data_tags.rb
|
58
|
+
- lib/file_pipeline/file_operations/default_operations/exif_recovery.rb
|
58
59
|
- lib/file_pipeline/file_operations/default_operations/exif_redaction.rb
|
59
60
|
- lib/file_pipeline/file_operations/default_operations/exif_restoration.rb
|
60
61
|
- lib/file_pipeline/file_operations/default_operations/ptiff_conversion.rb
|