assembly-objectfile 2.1.1 → 2.1.2
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/Gemfile.lock +7 -7
- data/lib/assembly/object_file/version.rb +1 -1
- data/lib/assembly/object_file.rb +21 -110
- data/spec/assembly/object_file_spec.rb +8 -24
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0931aac97a88ba77ac0cfa8ff018d19fddcfe909c81cd82e9dfc13dca12ed4f4'
|
|
4
|
+
data.tar.gz: 4eb596c2799586b3298cd1019be16606b4a371a175c4630b1ac826296dacb5bb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a252cfc25b6e2a11f50a6eb2976997fdcbf387ba3855fbca03d188a2f7e9572ca1a3ed605da191700551e34a685deb9dec810e63dfbff59bf9bfd09f6a6a9504
|
|
7
|
+
data.tar.gz: db0fdbf6583455bce118aa14bc29692d90fbb35c1e9746f3748548094ff53e0f33fe79c08cf5baace3869a08e4f9e3080d1906b810ce38d64022efa573e8c500
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
assembly-objectfile (2.1.
|
|
4
|
+
assembly-objectfile (2.1.2)
|
|
5
5
|
activesupport (>= 5.2.0)
|
|
6
6
|
mime-types (> 3)
|
|
7
7
|
mini_exiftool
|
|
@@ -28,9 +28,9 @@ GEM
|
|
|
28
28
|
mime-types-data (~> 3.2015)
|
|
29
29
|
mime-types-data (3.2022.0105)
|
|
30
30
|
mini_exiftool (2.10.2)
|
|
31
|
-
minitest (5.16.
|
|
31
|
+
minitest (5.16.3)
|
|
32
32
|
parallel (1.22.1)
|
|
33
|
-
parser (3.1.2.
|
|
33
|
+
parser (3.1.2.1)
|
|
34
34
|
ast (~> 2.4.1)
|
|
35
35
|
pry (0.13.1)
|
|
36
36
|
coderay (~> 1.1)
|
|
@@ -55,17 +55,17 @@ GEM
|
|
|
55
55
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
56
56
|
rspec-support (~> 3.11.0)
|
|
57
57
|
rspec-support (3.11.0)
|
|
58
|
-
rubocop (1.
|
|
58
|
+
rubocop (1.35.0)
|
|
59
59
|
json (~> 2.3)
|
|
60
60
|
parallel (~> 1.10)
|
|
61
|
-
parser (>= 3.1.
|
|
61
|
+
parser (>= 3.1.2.1)
|
|
62
62
|
rainbow (>= 2.2.2, < 4.0)
|
|
63
63
|
regexp_parser (>= 1.8, < 3.0)
|
|
64
64
|
rexml (>= 3.2.5, < 4.0)
|
|
65
|
-
rubocop-ast (>= 1.
|
|
65
|
+
rubocop-ast (>= 1.20.1, < 2.0)
|
|
66
66
|
ruby-progressbar (~> 1.7)
|
|
67
67
|
unicode-display_width (>= 1.4.0, < 3.0)
|
|
68
|
-
rubocop-ast (1.
|
|
68
|
+
rubocop-ast (1.21.0)
|
|
69
69
|
parser (>= 3.1.1.0)
|
|
70
70
|
rubocop-rspec (2.12.1)
|
|
71
71
|
rubocop (~> 1.31)
|
data/lib/assembly/object_file.rb
CHANGED
|
@@ -7,11 +7,8 @@ require 'active_support/core_ext/object/blank'
|
|
|
7
7
|
module Assembly
|
|
8
8
|
# This class contains generic methods to operate on any file.
|
|
9
9
|
class ObjectFile
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
# @param [Array] strings Array of filenames with paths to operate on
|
|
14
|
-
# @return [String] longest common initial part of path of filenames passed in
|
|
10
|
+
# @param [Array] strings Array of filenames with paths
|
|
11
|
+
# @return [String] longest common initial path of filenames passed in
|
|
15
12
|
#
|
|
16
13
|
# Example:
|
|
17
14
|
# puts Assembly::ObjectFile.common_prefix(['/Users/peter/00/test.tif','/Users/peter/05/test.jp2'])
|
|
@@ -52,8 +49,6 @@ module Assembly
|
|
|
52
49
|
# :file (from unix file system command)
|
|
53
50
|
# the default is defined in the private `default_mime_type_order` method
|
|
54
51
|
# but you can override to set your own order
|
|
55
|
-
# @example
|
|
56
|
-
# Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
57
52
|
def initialize(path, params = {})
|
|
58
53
|
@path = path
|
|
59
54
|
@label = params[:label]
|
|
@@ -64,71 +59,41 @@ module Assembly
|
|
|
64
59
|
@mime_type_order = params[:mime_type_order] || default_mime_type_order
|
|
65
60
|
end
|
|
66
61
|
|
|
67
|
-
# @return [String] base filename
|
|
68
|
-
# @example
|
|
69
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
70
|
-
# puts source_file.filename # "path_to_file.tif"
|
|
71
62
|
def filename
|
|
72
63
|
File.basename(path)
|
|
73
64
|
end
|
|
74
65
|
|
|
75
|
-
# @return [String] base directory
|
|
76
|
-
# @example
|
|
77
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
78
|
-
# puts source_file.dirname # "/input"
|
|
79
66
|
def dirname
|
|
80
67
|
File.dirname(path)
|
|
81
68
|
end
|
|
82
69
|
|
|
83
|
-
# @return [String] filename extension
|
|
84
|
-
# @example
|
|
85
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
86
|
-
# puts source_file.ext # ".tif"
|
|
87
70
|
def ext
|
|
88
71
|
File.extname(path)
|
|
89
72
|
end
|
|
90
73
|
|
|
91
|
-
# @return [String] base filename without extension
|
|
92
|
-
# @example
|
|
93
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
94
|
-
# puts source_file.filename # "path_to_file"
|
|
95
74
|
def filename_without_ext
|
|
96
75
|
File.basename(path, ext)
|
|
97
76
|
end
|
|
98
77
|
|
|
99
|
-
# @return [MiniExiftool] exif
|
|
100
|
-
# @example
|
|
101
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
102
|
-
# puts source_file.exif # hash with exif information
|
|
78
|
+
# @return [MiniExiftool] exif mini_exiftool gem object wrapper for exiftool
|
|
103
79
|
def exif
|
|
104
80
|
@exif ||= begin
|
|
105
81
|
check_for_file
|
|
106
82
|
MiniExiftool.new(path, replace_invalid_chars: '?')
|
|
107
83
|
rescue MiniExiftool::Error
|
|
108
|
-
# MiniExiftool
|
|
109
|
-
# but
|
|
110
|
-
|
|
111
|
-
# Note: if the file that causes the problem should NOT use exiftool to determine mimetype, add it to the skipped
|
|
112
|
-
# mimetypes in Assembly::TRUSTED_MIMETYPES to bypass initialization of MiniExiftool for mimetype generation
|
|
113
|
-
raise MiniExiftool::Error, "error initializing MiniExiftool for #{path}"
|
|
84
|
+
# MiniExiftool may raise an error on files it doesn't know how to handle (disk images for example)
|
|
85
|
+
# but we don't want this to prevent an ObjectFile from being created, so just swallow it.
|
|
86
|
+
nil
|
|
114
87
|
end
|
|
115
88
|
end
|
|
116
89
|
|
|
117
|
-
#
|
|
118
|
-
# @return [String] md5 checksum
|
|
119
|
-
# @example
|
|
120
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
121
|
-
# puts source_file.md5 # 'XXX123XXX1243XX1243'
|
|
90
|
+
# @return [String] computed md5 checksum
|
|
122
91
|
def md5
|
|
123
92
|
check_for_file unless @md5
|
|
124
93
|
@md5 ||= Digest::MD5.file(path).hexdigest
|
|
125
94
|
end
|
|
126
95
|
|
|
127
|
-
#
|
|
128
|
-
# @return [String] sha1 checksum
|
|
129
|
-
# @example
|
|
130
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
131
|
-
# puts source_file.sha1 # 'XXX123XXX1243XX1243'
|
|
96
|
+
# @return [String] computed sha1 checksum
|
|
132
97
|
def sha1
|
|
133
98
|
check_for_file unless @sha1
|
|
134
99
|
@sha1 ||= Digest::SHA1.file(path).hexdigest
|
|
@@ -136,10 +101,7 @@ module Assembly
|
|
|
136
101
|
|
|
137
102
|
# Returns mimetype information for the current file based on the ordering set in default_mime_type_order
|
|
138
103
|
# We stop computing mimetypes as soon as we have a method that returns a value
|
|
139
|
-
# @return [String]
|
|
140
|
-
# @example
|
|
141
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
|
|
142
|
-
# puts source_file.mimetype # 'text/plain'
|
|
104
|
+
# @return [String] mimetype of the file
|
|
143
105
|
def mimetype
|
|
144
106
|
@mimetype ||= begin
|
|
145
107
|
check_for_file
|
|
@@ -154,84 +116,55 @@ module Assembly
|
|
|
154
116
|
|
|
155
117
|
# @return [Symbol] the type of object, could be :application (for PDF or Word, etc),
|
|
156
118
|
# :audio, :image, :message, :model, :multipart, :text or :video
|
|
157
|
-
# @example
|
|
158
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
159
|
-
# puts source_file.object_type # :image
|
|
160
119
|
def object_type
|
|
161
120
|
lookup = MIME::Types[mimetype][0]
|
|
162
121
|
lookup.nil? ? :other : lookup.media_type.to_sym
|
|
163
122
|
end
|
|
164
123
|
|
|
165
|
-
# @return [Boolean] if
|
|
166
|
-
# @example
|
|
167
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
168
|
-
# puts source_file.image? # true
|
|
124
|
+
# @return [Boolean] true if the mime-types gem recognizes it as an image (from file extension lookup)
|
|
169
125
|
def image?
|
|
170
126
|
object_type == :image
|
|
171
127
|
end
|
|
172
128
|
|
|
173
|
-
#
|
|
174
|
-
#
|
|
175
|
-
# @return [Boolean] true if image is valid, false if not.
|
|
176
|
-
# @example
|
|
177
|
-
# source_img = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
178
|
-
# puts source_img.valid_image? # true
|
|
129
|
+
# @return [Boolean] true if the mime-types gem recognizes it as an image (from file extension lookup)
|
|
130
|
+
# AND it is a jp2 or jp2able?
|
|
179
131
|
def valid_image?
|
|
180
132
|
return false unless image?
|
|
181
133
|
|
|
182
134
|
mimetype == 'image/jp2' || jp2able?
|
|
183
135
|
end
|
|
184
136
|
|
|
185
|
-
#
|
|
186
|
-
# the existence of a profile description and further restricts mimetypes.
|
|
187
|
-
# It is used by the assembly robots to decide if a jp2 will be created and is also called before
|
|
188
|
-
# you create a jp2 using assembly-image.
|
|
189
|
-
# @return [Boolean] true if image should have a jp2 created, false if not.
|
|
190
|
-
# @example
|
|
191
|
-
# source_img = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
192
|
-
# puts source_img.jp2able? # true
|
|
137
|
+
# @return [Boolean] true if we can create a jp2 from the file
|
|
193
138
|
def jp2able?
|
|
194
139
|
return false unless exif
|
|
195
140
|
|
|
196
141
|
Assembly::VALID_IMAGE_MIMETYPES.include?(mimetype)
|
|
197
142
|
end
|
|
198
143
|
|
|
199
|
-
# Returns file size information for the current file in bytes.
|
|
200
144
|
# @return [Integer] file size in bytes
|
|
201
|
-
# @example
|
|
202
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
203
|
-
# puts source_file.filesize # 1345
|
|
204
145
|
def filesize
|
|
205
146
|
check_for_file
|
|
206
147
|
@filesize ||= File.size(path)
|
|
207
148
|
end
|
|
208
149
|
|
|
209
|
-
#
|
|
210
|
-
# @return [Boolean] file exists
|
|
211
|
-
# @example
|
|
212
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
|
|
213
|
-
# puts source_file.file_exists? # true
|
|
150
|
+
# @return [Boolean] file exists and is not a directory
|
|
214
151
|
def file_exists?
|
|
215
152
|
@file_exists ||= (File.exist?(path) && !File.directory?(path))
|
|
216
153
|
end
|
|
217
154
|
|
|
218
155
|
private
|
|
219
156
|
|
|
220
|
-
#
|
|
157
|
+
# check for file existence before operating on it
|
|
221
158
|
def check_for_file
|
|
222
159
|
raise "input file #{path} does not exist or is a directory" unless file_exists?
|
|
223
160
|
end
|
|
224
161
|
|
|
225
|
-
#
|
|
162
|
+
# defines default preferred ordering of how mimetypes are determined
|
|
226
163
|
def default_mime_type_order
|
|
227
164
|
%i[override exif file extension]
|
|
228
165
|
end
|
|
229
166
|
|
|
230
|
-
#
|
|
231
|
-
# @return [String] mime type for supplied file
|
|
232
|
-
# @example
|
|
233
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
|
|
234
|
-
# puts source_file.extension_mimetype # 'text/plain'
|
|
167
|
+
# @return [String] mime type for supplied file using the mime-types gem (based on a file extension lookup)
|
|
235
168
|
def extension_mimetype
|
|
236
169
|
@extension_mimetype ||= begin
|
|
237
170
|
mtype = MIME::Types.type_for(path).first
|
|
@@ -239,11 +172,7 @@ module Assembly
|
|
|
239
172
|
end
|
|
240
173
|
end
|
|
241
174
|
|
|
242
|
-
#
|
|
243
|
-
# @return [String] mime type for supplied file
|
|
244
|
-
# @example
|
|
245
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
|
|
246
|
-
# puts source_file.file_mimetype # 'text/plain'
|
|
175
|
+
# @return [String] mime type for supplied file based on unix file system command
|
|
247
176
|
def file_mimetype
|
|
248
177
|
@file_mimetype ||= begin
|
|
249
178
|
check_for_file
|
|
@@ -251,12 +180,9 @@ module Assembly
|
|
|
251
180
|
end
|
|
252
181
|
end
|
|
253
182
|
|
|
254
|
-
#
|
|
255
|
-
#
|
|
256
|
-
#
|
|
257
|
-
# @example
|
|
258
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
|
|
259
|
-
# puts source_file.exif_mimetype # 'text/plain'
|
|
183
|
+
# @return [String] mimetype information for the current file based on exif data,
|
|
184
|
+
# unless mimetype is configured as one we'd rather get from the file system command
|
|
185
|
+
# (e.g. exif struggles or we get better info from file system command)
|
|
260
186
|
def exif_mimetype
|
|
261
187
|
@exif_mimetype ||= begin
|
|
262
188
|
check_for_file
|
|
@@ -268,23 +194,8 @@ module Assembly
|
|
|
268
194
|
|
|
269
195
|
# Returns mimetype information using the manual override mapping (based on a file extension lookup)
|
|
270
196
|
# @return [String] mime type for supplied file if a mapping exists for the file's extension
|
|
271
|
-
# @example
|
|
272
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.json')
|
|
273
|
-
# puts source_file.override_mimetype # 'application/json'
|
|
274
197
|
def override_mimetype
|
|
275
198
|
@override_mimetype ||= Assembly::OVERRIDE_MIMETYPES.fetch(ext.to_sym, '')
|
|
276
199
|
end
|
|
277
|
-
|
|
278
|
-
# @note Uses shell call to "file", only expected to work on unix based systems
|
|
279
|
-
# @return [String] encoding for supplied file
|
|
280
|
-
# @example
|
|
281
|
-
# source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
|
|
282
|
-
# puts source_file.encoding # 'us-ascii'
|
|
283
|
-
def encoding
|
|
284
|
-
@encoding ||= begin
|
|
285
|
-
check_for_file
|
|
286
|
-
`file --mime-encoding "#{path}"`.delete("\n").split(':')[1].strip
|
|
287
|
-
end
|
|
288
|
-
end
|
|
289
200
|
end
|
|
290
201
|
end
|
|
@@ -387,33 +387,17 @@ describe Assembly::ObjectFile do
|
|
|
387
387
|
end
|
|
388
388
|
end
|
|
389
389
|
|
|
390
|
-
describe '#
|
|
391
|
-
|
|
392
|
-
it 'binary' do
|
|
393
|
-
object_file = described_class.new(TEST_TIF_INPUT_FILE)
|
|
394
|
-
expect(object_file.send(:encoding)).to eq('binary')
|
|
395
|
-
end
|
|
396
|
-
end
|
|
390
|
+
describe '#exif' do
|
|
391
|
+
subject(:exif) { object_file.exif }
|
|
397
392
|
|
|
398
|
-
|
|
399
|
-
it 'binary' do
|
|
400
|
-
object_file = described_class.new(TEST_RES1_TEXT)
|
|
401
|
-
expect(object_file.send(:encoding)).to eq('us-ascii')
|
|
402
|
-
end
|
|
403
|
-
end
|
|
404
|
-
end
|
|
393
|
+
let(:object_file) { described_class.new(TEST_TIF_INPUT_FILE) }
|
|
405
394
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
expect(object_file.exif.class).to eq MiniExiftool
|
|
411
|
-
end
|
|
395
|
+
it { is_expected.to be_kind_of MiniExiftool }
|
|
396
|
+
|
|
397
|
+
context 'when exiftool raises an error initializing the file' do
|
|
398
|
+
let(:object_file) { described_class.new('spec/test_data/empty.txt') }
|
|
412
399
|
|
|
413
|
-
|
|
414
|
-
object_file = described_class.new('spec/test_data/empty.txt')
|
|
415
|
-
expect { object_file.exif }.to raise_error(MiniExiftool::Error,
|
|
416
|
-
"error initializing MiniExiftool for #{object_file.path}")
|
|
400
|
+
it { is_expected.to be_nil }
|
|
417
401
|
end
|
|
418
402
|
end
|
|
419
403
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: assembly-objectfile
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.1.
|
|
4
|
+
version: 2.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Mangiafico
|
|
@@ -11,7 +11,7 @@ authors:
|
|
|
11
11
|
autorequire:
|
|
12
12
|
bindir: exe
|
|
13
13
|
cert_chain: []
|
|
14
|
-
date: 2022-
|
|
14
|
+
date: 2022-08-18 00:00:00.000000000 Z
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
17
17
|
name: activesupport
|
|
@@ -199,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
199
199
|
- !ruby/object:Gem::Version
|
|
200
200
|
version: '0'
|
|
201
201
|
requirements: []
|
|
202
|
-
rubygems_version: 3.
|
|
202
|
+
rubygems_version: 3.3.7
|
|
203
203
|
signing_key:
|
|
204
204
|
specification_version: 4
|
|
205
205
|
summary: Ruby implementation of file services needed to prepare objects to be accessioned
|