file_pipeline 0.1.0 → 0.1.1
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/lib/file_pipeline.rb +1 -1
- data/lib/file_pipeline/errors.rb +1 -0
- data/lib/file_pipeline/errors/failed_modification_error.rb +3 -3
- data/lib/file_pipeline/errors/misplaced_version_file_error.rb +30 -0
- data/lib/file_pipeline/file_operations/exif_manipulable.rb +1 -1
- data/lib/file_pipeline/pipeline.rb +11 -4
- data/lib/file_pipeline/versioned_file.rb +15 -30
- data/lib/file_pipeline/versions/validator.rb +85 -0
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2669b6e193cbdf383b4db7bf1fe9e16a4519cefb152b394e34310ea9690d4ed6
|
4
|
+
data.tar.gz: 5c07a106071954420545dfec51b1110f71027614384e77d553f4132322848faa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b193249acfb972b2a0bc167728a2147d9e7c39e4469a4f3808ed9ff23b3db0cdbfa06000e3477a83058918a31174bad854821a95287abfb964965e6db02421d4
|
7
|
+
data.tar.gz: 265d513deaf12846e01c767c71a63c481bb0f21a8bc81d7b00e7ba2ea2291afb0c3d99cd9c3830fd37715772a8c807e3455fdfb3c4f14d558e5df5cc9ba52183
|
data/lib/file_pipeline.rb
CHANGED
@@ -33,7 +33,7 @@ module FilePipeline
|
|
33
33
|
def self.load(file_operation)
|
34
34
|
const = file_operation.split('_').map(&:capitalize).join
|
35
35
|
FilePipeline.load_file(file_operation) unless const_defined? const
|
36
|
-
const_get
|
36
|
+
const_get "FileOperations::#{const}"
|
37
37
|
rescue NameError
|
38
38
|
# TODO: implement autogenerating module names from file_operation src path
|
39
39
|
const_get const
|
data/lib/file_pipeline/errors.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'errors/failed_modification_error'
|
4
|
+
require_relative 'errors/misplaced_version_file_error'
|
4
5
|
require_relative 'errors/missing_version_file_error'
|
5
6
|
require_relative 'errors/source_directory_error'
|
6
7
|
require_relative 'errors/source_file_error'
|
@@ -41,9 +41,9 @@ module FilePipeline
|
|
41
41
|
# Appends the backtrace of the error that caused the exception to the
|
42
42
|
# #default_message.
|
43
43
|
def append_backtrace(str)
|
44
|
-
return str
|
44
|
+
return "#{str}\n" unless original_backtrace
|
45
45
|
|
46
|
-
str
|
46
|
+
"#{str} Backtrace:\n#{original_backtrace}"
|
47
47
|
end
|
48
48
|
|
49
49
|
# Appends the message of the error that caused the exception to the
|
@@ -58,7 +58,7 @@ module FilePipeline
|
|
58
58
|
|
59
59
|
# Returns a String with the #message for +self+.
|
60
60
|
def default_message
|
61
|
-
if info
|
61
|
+
if info.respond_to?(:operation) && info.respond_to?(:log)
|
62
62
|
msg = "#{info.operation&.name} with options"\
|
63
63
|
" #{info.operation&.options} failed on #{@file}."
|
64
64
|
append_error msg
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FilePipeline
|
4
|
+
module Errors
|
5
|
+
# Error class for exceptions that are raised when a new version is added,
|
6
|
+
# but the file is not in the VersionedFile's working directory.
|
7
|
+
class MisplacedVersionFileError < StandardError
|
8
|
+
# Path for of the misplaced file for the version.
|
9
|
+
attr_reader :file
|
10
|
+
|
11
|
+
# Path for the directory where the file should have been (the
|
12
|
+
# VersionedFile's working directory).
|
13
|
+
attr_reader :directory
|
14
|
+
|
15
|
+
def initialize(msg = nil, file: nil, directory: nil)
|
16
|
+
@file = file
|
17
|
+
@directory = directory
|
18
|
+
msg ||= default_message
|
19
|
+
super msg
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def default_message
|
25
|
+
"File #{File.basename @file} was expected in #{@directory},"\
|
26
|
+
" but was in #{File.dirname @file}."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -41,10 +41,7 @@ module FilePipeline
|
|
41
41
|
# Adds a file operation object #file_operations. The object must implement
|
42
42
|
# a _run_ method (see FileOperations::FileOperation#run for details).
|
43
43
|
def <<(file_operation_instance)
|
44
|
-
|
45
|
-
raise TypeError, 'File operations must implement a #run method'
|
46
|
-
end
|
47
|
-
|
44
|
+
validate file_operation_instance
|
48
45
|
@file_operations << file_operation_instance
|
49
46
|
end
|
50
47
|
|
@@ -106,5 +103,15 @@ module FilePipeline
|
|
106
103
|
operation.run version, directory, original
|
107
104
|
end
|
108
105
|
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
# Raises TypeError if <tt>file_operation_instance</tt> does not implement a
|
110
|
+
# #run method.
|
111
|
+
def validate(file_operation_instance)
|
112
|
+
return file_operation_instance if file_operation_instance.respond_to? :run
|
113
|
+
|
114
|
+
raise TypeError, 'File operations must implement a #run method'
|
115
|
+
end
|
109
116
|
end
|
110
117
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'versions/validator'
|
3
4
|
module FilePipeline
|
4
5
|
# VersionedFile creates a directory where it stores any versions of _file_.
|
5
6
|
class VersionedFile
|
@@ -81,14 +82,10 @@ module FilePipeline
|
|
81
82
|
# <tt>version_info</tt> must be a path to an existing file or an array with
|
82
83
|
# the path and optionally a FileOperations::Results instance:
|
83
84
|
# <tt>['path/to/file', results_object]</tt>.
|
84
|
-
# Will
|
85
|
+
# Will raise MisplacedVersionFileError if it is in another directory.
|
85
86
|
def <<(version_info)
|
86
|
-
|
87
|
-
|
88
|
-
raise Errors::FailedModificationError.new info: info, file: original
|
89
|
-
end
|
90
|
-
|
91
|
-
version = validate(file)
|
87
|
+
version, info = Versions::Validator[version_info, self]
|
88
|
+
version ||= @current
|
92
89
|
@history[version] = info
|
93
90
|
self
|
94
91
|
rescue StandardError => e
|
@@ -146,7 +143,7 @@ module FilePipeline
|
|
146
143
|
yield(self) if block_given?
|
147
144
|
return original unless changed?
|
148
145
|
|
149
|
-
filename = overwrite ?
|
146
|
+
filename = overwrite ? replacing_target : preserving_target
|
150
147
|
FileUtils.rm original if overwrite
|
151
148
|
@original = Versions.copy(current, original_dir, filename)
|
152
149
|
ensure
|
@@ -167,10 +164,12 @@ module FilePipeline
|
|
167
164
|
# than exif.
|
168
165
|
#++
|
169
166
|
def metadata(for_version: :current)
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
167
|
+
file = case for_version
|
168
|
+
when :current, :original
|
169
|
+
public_send for_version
|
170
|
+
else
|
171
|
+
for_version
|
172
|
+
end
|
174
173
|
read_exif(file).first
|
175
174
|
end
|
176
175
|
|
@@ -211,13 +210,13 @@ module FilePipeline
|
|
211
210
|
|
212
211
|
# Returns the filename for a target file that will not overwrite the
|
213
212
|
# original.
|
214
|
-
def
|
215
|
-
basename
|
213
|
+
def preserving_target
|
214
|
+
"#{basename}_#{target_suffix}#{current_extension}"
|
216
215
|
end
|
217
216
|
|
218
217
|
# Returns the filename for a target file that will overwrite the
|
219
218
|
# original.
|
220
|
-
def
|
219
|
+
def replacing_target
|
221
220
|
basename + current_extension
|
222
221
|
end
|
223
222
|
|
@@ -227,27 +226,13 @@ module FilePipeline
|
|
227
226
|
history.clear!
|
228
227
|
end
|
229
228
|
|
230
|
-
# Validates if file exists and has been stored in #directory.
|
231
|
-
def validate(file)
|
232
|
-
return current unless file
|
233
|
-
|
234
|
-
unless File.exist? file
|
235
|
-
raise Errors::MissingVersionFileError.new file: file
|
236
|
-
end
|
237
|
-
|
238
|
-
return file if File.dirname(file) == directory
|
239
|
-
|
240
|
-
Versions.move file, directory, File.basename(file)
|
241
|
-
end
|
242
|
-
|
243
229
|
# Creates the directory containing all version files. Directory name is
|
244
230
|
# composed of the basename plus '_version'.
|
245
231
|
#
|
246
232
|
# Raises SystemCallError if the directory already exists.
|
247
233
|
def workdir
|
248
|
-
subdir = basename + '_versions'
|
249
234
|
filedir = File.dirname(original)
|
250
|
-
dirname = File.join filedir,
|
235
|
+
dirname = File.join filedir, "#{basename}_versions"
|
251
236
|
FileUtils.mkdir(dirname)
|
252
237
|
File.path dirname
|
253
238
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FilePipeline
|
4
|
+
module Versions
|
5
|
+
# Validator objects verify the version file and results returned by a
|
6
|
+
# FileOperation.
|
7
|
+
#
|
8
|
+
# They will validate:
|
9
|
+
# - that the version file existst
|
10
|
+
# - that it is in the correct directory
|
11
|
+
# - that the file operation has not returned any failures
|
12
|
+
class Validator
|
13
|
+
extend Forwardable
|
14
|
+
|
15
|
+
# File for the version that resulted from a FileOperation.
|
16
|
+
attr_reader :file
|
17
|
+
|
18
|
+
# FileOperation::Results object.
|
19
|
+
attr_reader :info
|
20
|
+
|
21
|
+
# Returns a new instance.
|
22
|
+
#
|
23
|
+
# ===== Arguments
|
24
|
+
#
|
25
|
+
# * <tt>version_info</tt> - path to an existing file or an array with the
|
26
|
+
# path and optionally a FileOperations::Results instance.
|
27
|
+
# * +directory+ - directory where the file is expected (the working
|
28
|
+
# directory of a VersionedFile).
|
29
|
+
# * +filename+ - name of the file to be returned if the file operation was
|
30
|
+
# was non-modifying (usually the VersionedFile#original).
|
31
|
+
def initialize(version_info, directory, filename)
|
32
|
+
@file, @info = [version_info].flatten
|
33
|
+
@directory = directory
|
34
|
+
@filename = filename
|
35
|
+
end
|
36
|
+
|
37
|
+
# Validates file, directory, and info for <tt>version_info</tt> in the
|
38
|
+
# context of <tt>versioned_file</tt>.
|
39
|
+
#
|
40
|
+
# ===== Arguments
|
41
|
+
#
|
42
|
+
# * <tt>version_info</tt> - path to an existing file or an array with the
|
43
|
+
# path and optionally a FileOperations::Results instance.
|
44
|
+
# * <tt>versioned_file</tt> - an object that responds to #original and
|
45
|
+
# returns a file path, and #directory and returns a directory path.
|
46
|
+
def self.[](version_info, versioned_file)
|
47
|
+
new(version_info, versioned_file.directory, versioned_file.original)
|
48
|
+
.validate_info
|
49
|
+
.validate_file
|
50
|
+
.validate_directory
|
51
|
+
.then { |validator| [validator.file, validator.info] }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns +true+ when there is no file for the version (result of a
|
55
|
+
# non-modifying file operation), +false+ otherwise.
|
56
|
+
def unmodified?
|
57
|
+
@file.nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Raises MisplacedVersionFileError if #file is not in #directory.
|
61
|
+
def validate_directory
|
62
|
+
return self if unmodified? || File.dirname(@file) == @directory
|
63
|
+
|
64
|
+
raise Errors::MisplacedVersionFileError.new file: @file,
|
65
|
+
directory: @directory
|
66
|
+
end
|
67
|
+
|
68
|
+
# Raises MissingVersionFileError if #file does not exist on the file
|
69
|
+
# system.
|
70
|
+
def validate_file
|
71
|
+
return self if unmodified? || File.exist?(@file)
|
72
|
+
|
73
|
+
raise Errors::MissingVersionFileError.new file: @file
|
74
|
+
end
|
75
|
+
|
76
|
+
# Raises FailedModificationError if the file operation generatint the
|
77
|
+
# #info failed.
|
78
|
+
def validate_info
|
79
|
+
return self unless @info&.failure
|
80
|
+
|
81
|
+
raise Errors::FailedModificationError.new info: @info, file: @filename
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
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.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Stein
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_exiftool
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.16.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.16.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: ruby-vips
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -50,6 +50,7 @@ files:
|
|
50
50
|
- lib/file_pipeline.rb
|
51
51
|
- lib/file_pipeline/errors.rb
|
52
52
|
- lib/file_pipeline/errors/failed_modification_error.rb
|
53
|
+
- lib/file_pipeline/errors/misplaced_version_file_error.rb
|
53
54
|
- lib/file_pipeline/errors/missing_version_file_error.rb
|
54
55
|
- lib/file_pipeline/errors/source_directory_error.rb
|
55
56
|
- lib/file_pipeline/errors/source_file_error.rb
|
@@ -68,11 +69,12 @@ files:
|
|
68
69
|
- lib/file_pipeline/versioned_file.rb
|
69
70
|
- lib/file_pipeline/versions.rb
|
70
71
|
- lib/file_pipeline/versions/history.rb
|
72
|
+
- lib/file_pipeline/versions/validator.rb
|
71
73
|
homepage: https://github.com/loveablelobster/file_pipeline
|
72
74
|
licenses:
|
73
75
|
- MIT
|
74
76
|
metadata: {}
|
75
|
-
post_install_message:
|
77
|
+
post_install_message:
|
76
78
|
rdoc_options: []
|
77
79
|
require_paths:
|
78
80
|
- lib
|
@@ -80,15 +82,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
80
82
|
requirements:
|
81
83
|
- - ">="
|
82
84
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
85
|
+
version: '3.0'
|
84
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
87
|
requirements:
|
86
88
|
- - ">="
|
87
89
|
- !ruby/object:Gem::Version
|
88
90
|
version: '0'
|
89
91
|
requirements: []
|
90
|
-
rubygems_version: 3.
|
91
|
-
signing_key:
|
92
|
+
rubygems_version: 3.2.3
|
93
|
+
signing_key:
|
92
94
|
specification_version: 4
|
93
95
|
summary: Nondestructive file processing with a defined batch
|
94
96
|
test_files: []
|