assembly-objectfile 1.13.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/.rubocop.yml +1 -1
  4. data/.rubocop_todo.yml +14 -80
  5. data/Gemfile.lock +106 -0
  6. data/assembly-objectfile.gemspec +1 -3
  7. data/lib/assembly-objectfile/object_file.rb +253 -3
  8. data/lib/assembly-objectfile/version.rb +1 -1
  9. data/lib/assembly-objectfile.rb +0 -5
  10. data/spec/object_file_spec.rb +411 -172
  11. data/spec/spec_helper.rb +2 -31
  12. metadata +19 -107
  13. data/lib/assembly-objectfile/content_metadata/config.rb +0 -26
  14. data/lib/assembly-objectfile/content_metadata/file.rb +0 -63
  15. data/lib/assembly-objectfile/content_metadata/file_set.rb +0 -73
  16. data/lib/assembly-objectfile/content_metadata/file_set_builder.rb +0 -65
  17. data/lib/assembly-objectfile/content_metadata/nokogiri_builder.rb +0 -57
  18. data/lib/assembly-objectfile/content_metadata.rb +0 -117
  19. data/lib/assembly-objectfile/object_fileable.rb +0 -275
  20. data/spec/content_metadata_spec.rb +0 -809
  21. data/spec/test_data/input/oo000oo0001/00/oo000oo0001_00_001.tif +0 -0
  22. data/spec/test_data/input/oo000oo0001/00/oo000oo0001_00_002.tif +0 -0
  23. data/spec/test_data/input/oo000oo0001/05/oo000oo0001_05_001.jp2 +0 -0
  24. data/spec/test_data/input/oo000oo0001/05/oo000oo0001_05_002.jp2 +0 -0
  25. data/spec/test_data/input/oo000oo0001/15/oo000oo0001_15_001.pdf +0 -1
  26. data/spec/test_data/input/oo000oo0001/15/oo000oo0001_15_002.pdf +0 -1
  27. data/spec/test_data/input/oo000oo0001/31/oo000oo0001_31_001.pdf +0 -1
  28. data/spec/test_data/input/oo000oo0001/50/oo000oo0001_50_001.tif +0 -0
  29. data/spec/test_data/input/oo000oo0001/oo000oo0001_book.pdf +0 -1
  30. data/spec/test_data/input/res1_image1.jp2 +0 -0
  31. data/spec/test_data/input/res1_image2.jp2 +0 -0
  32. data/spec/test_data/input/res1_image2.tif +0 -0
  33. data/spec/test_data/input/res1_teifile.txt +0 -1
  34. data/spec/test_data/input/res2_image1.jp2 +0 -0
  35. data/spec/test_data/input/res2_image1.tif +0 -0
  36. data/spec/test_data/input/res2_image2.jp2 +0 -0
  37. data/spec/test_data/input/res2_image2.tif +0 -0
  38. data/spec/test_data/input/res2_teifile.txt +0 -1
  39. data/spec/test_data/input/res2_textfile.txt +0 -1
  40. data/spec/test_data/input/res3_image1.jp2 +0 -0
  41. data/spec/test_data/input/res3_image1.tif +0 -0
  42. data/spec/test_data/input/res3_teifile.txt +0 -1
  43. data/spec/test_data/input/test.pdf +0 -1
  44. data/spec/test_data/input/test.svg +0 -2
  45. data/spec/test_data/input/test2.jp2 +0 -0
  46. data/spec/test_data/input/test2.tif +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c85bb6c05fe0d46e9b2f37e90710043efce16322c5d58e0b0a9578fd21ece77
4
- data.tar.gz: c7e3ac5e3f0a0aa2124f8ce3d6587de2d02923c733ee94b1c299ae171101f5a5
3
+ metadata.gz: c3c456d372ab0804ebcaad06ac2b8695376f9ffe57ccb8a23b8a57d711df5561
4
+ data.tar.gz: 1797606727f148ee128dedc102ad68480fbd9f55983c318b91c8f5f52a546a9b
5
5
  SHA512:
6
- metadata.gz: fbad307e9a103af61b4a6b05b35bb6b98953774a2c9bd32cb1404f1a9ff6e3404fe78cfc48f9061bfffaa23c3610f2a6f19df5e08975a20c6ee387073cc1010d
7
- data.tar.gz: 717e174ccf88a94880f4a832b2d281b351774299fb1273a96b4a1bb942e360cd20b0ba3ac68b7ad4f113e3bd3c78652c7670efcf7bcf8f9bcf068972ba5cd42d
6
+ metadata.gz: c927cb2cffef41a699c0f2e1f0fa0d8e6d4b1cc92c9fdb26b80ca5c9e851d7de0a9b1204cc4a4290213a9d7a642c2d3233db56396efb3b626cdd4d6e7b3bfdda
7
+ data.tar.gz: 473f2ead345feaf0afd518da399751a86f526f27b19dd0bfd75fb55354bd055d00ccbbb06a96ca905f2e0de6fcdbf25d4e42e8da23fc167225afb8a9958038e3
data/.gitignore CHANGED
@@ -10,4 +10,3 @@ log/*
10
10
  pkg/*
11
11
  tags
12
12
  tmp
13
- Gemfile.lock
data/.rubocop.yml CHANGED
@@ -14,7 +14,7 @@ Metrics/BlockLength:
14
14
  - 'spec/**/*.rb'
15
15
  - '**/*.gemspec'
16
16
 
17
- Gemspec/DateAssignment: # (new in 1.10)
17
+ Gemspec/DeprecatedAttributeAssignment: # (new in 1.10)
18
18
  Enabled: true
19
19
 
20
20
  Layout/SpaceAroundMethodCallOperator:
data/.rubocop_todo.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2022-02-28 21:11:02 UTC using RuboCop version 1.25.1.
3
+ # on 2022-07-07 21:26:21 UTC using RuboCop version 1.31.0.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
@@ -11,41 +11,10 @@ Lint/UselessAssignment:
11
11
  Exclude:
12
12
  - 'config/boot.rb'
13
13
 
14
- # Offense count: 3
15
- # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
16
- Metrics/AbcSize:
17
- Max: 55
18
-
19
- # Offense count: 1
20
- # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
21
- # IgnoredMethods: refine
22
- Metrics/BlockLength:
23
- Max: 27
24
-
25
- # Offense count: 2
26
- # Configuration parameters: IgnoredMethods.
27
- Metrics/CyclomaticComplexity:
28
- Max: 14
29
-
30
- # Offense count: 4
31
- # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
32
- Metrics/MethodLength:
33
- Max: 31
34
-
35
14
  # Offense count: 1
36
15
  # Configuration parameters: CountComments, CountAsOne.
37
- Metrics/ModuleLength:
38
- Max: 120
39
-
40
- # Offense count: 1
41
- # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
42
- Metrics/ParameterLists:
43
- Max: 12
44
-
45
- # Offense count: 2
46
- # Configuration parameters: IgnoredMethods.
47
- Metrics/PerceivedComplexity:
48
- Max: 15
16
+ Metrics/ClassLength:
17
+ Max: 122
49
18
 
50
19
  # Offense count: 1
51
20
  # Configuration parameters: ExpectMatchingDefinition, CheckDefinitionPathHierarchy, CheckDefinitionPathHierarchyRoots, Regex, IgnoreExecutableScripts, AllowedAcronyms.
@@ -64,66 +33,31 @@ Naming/FileName:
64
33
  Naming/PredicateName:
65
34
  Exclude:
66
35
  - 'spec/**/*'
67
- - 'lib/assembly-objectfile/object_fileable.rb'
68
-
69
- # Offense count: 1
70
- # Configuration parameters: Prefixes.
71
- # Prefixes: when, with, without
72
- RSpec/ContextWording:
73
- Exclude:
74
- - 'spec/content_metadata_spec.rb'
36
+ - 'lib/assembly-objectfile/object_file.rb'
75
37
 
76
- # Offense count: 32
38
+ # Offense count: 2
77
39
  # Configuration parameters: CountAsOne.
78
40
  RSpec/ExampleLength:
79
- Max: 34
41
+ Max: 7
80
42
 
81
- # Offense count: 2
43
+ # Offense count: 1
82
44
  # Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly.
83
45
  # Include: **/*_spec*rb*, **/spec/**/*
84
46
  RSpec/FilePath:
85
47
  Exclude:
86
- - 'spec/content_metadata_spec.rb'
87
48
  - 'spec/object_file_spec.rb'
88
49
 
89
- # Offense count: 74
90
- # Configuration parameters: AssignmentOnly.
91
- RSpec/InstanceVariable:
92
- Exclude:
93
- - 'spec/object_file_spec.rb'
94
-
95
- # Offense count: 41
50
+ # Offense count: 8
96
51
  RSpec/MultipleExpectations:
97
- Max: 29
52
+ Max: 6
98
53
 
99
- # Offense count: 20
54
+ # Offense count: 3
100
55
  RSpec/NestedGroups:
101
56
  Max: 4
102
57
 
103
- # Offense count: 2
104
- RSpec/RepeatedDescription:
105
- Exclude:
106
- - 'spec/object_file_spec.rb'
107
-
108
- # Offense count: 2
109
- RSpec/RepeatedExample:
110
- Exclude:
111
- - 'spec/object_file_spec.rb'
112
-
113
- # Offense count: 5
114
- RSpec/RepeatedExampleGroupDescription:
115
- Exclude:
116
- - 'spec/content_metadata_spec.rb'
117
-
118
- # Offense count: 2
119
- # Cop supports --auto-correct.
120
- Style/CommentedKeyword:
121
- Exclude:
122
- - 'lib/assembly-objectfile/content_metadata.rb'
123
-
124
- # Offense count: 123
125
- # Cop supports --auto-correct.
126
- # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
58
+ # Offense count: 24
59
+ # This cop supports safe autocorrection (--autocorrect).
60
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, IgnoredPatterns.
127
61
  # URISchemes: http, https
128
62
  Layout/LineLength:
129
- Max: 277
63
+ Max: 187
data/Gemfile.lock ADDED
@@ -0,0 +1,106 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ assembly-objectfile (2.0.0)
5
+ activesupport (>= 5.2.0)
6
+ deprecation
7
+ mime-types (> 3)
8
+ mini_exiftool
9
+ nokogiri
10
+
11
+ GEM
12
+ remote: http://rubygems.org/
13
+ specs:
14
+ activesupport (7.0.3)
15
+ concurrent-ruby (~> 1.0, >= 1.0.2)
16
+ i18n (>= 1.6, < 2)
17
+ minitest (>= 5.1)
18
+ tzinfo (~> 2.0)
19
+ ast (2.4.2)
20
+ byebug (11.1.3)
21
+ coderay (1.1.3)
22
+ concurrent-ruby (1.1.10)
23
+ deprecation (1.1.0)
24
+ activesupport
25
+ diff-lcs (1.5.0)
26
+ docile (1.4.0)
27
+ i18n (1.10.0)
28
+ concurrent-ruby (~> 1.0)
29
+ json (2.6.2)
30
+ method_source (1.0.0)
31
+ mime-types (3.4.1)
32
+ mime-types-data (~> 3.2015)
33
+ mime-types-data (3.2022.0105)
34
+ mini_exiftool (2.10.2)
35
+ mini_portile2 (2.8.0)
36
+ minitest (5.16.2)
37
+ nokogiri (1.13.6)
38
+ mini_portile2 (~> 2.8.0)
39
+ racc (~> 1.4)
40
+ parallel (1.22.1)
41
+ parser (3.1.2.0)
42
+ ast (~> 2.4.1)
43
+ pry (0.13.1)
44
+ coderay (~> 1.1)
45
+ method_source (~> 1.0)
46
+ pry-byebug (3.9.0)
47
+ byebug (~> 11.0)
48
+ pry (~> 0.13.0)
49
+ racc (1.6.0)
50
+ rainbow (3.1.1)
51
+ rake (13.0.6)
52
+ regexp_parser (2.5.0)
53
+ rexml (3.2.5)
54
+ rspec (3.11.0)
55
+ rspec-core (~> 3.11.0)
56
+ rspec-expectations (~> 3.11.0)
57
+ rspec-mocks (~> 3.11.0)
58
+ rspec-core (3.11.0)
59
+ rspec-support (~> 3.11.0)
60
+ rspec-expectations (3.11.0)
61
+ diff-lcs (>= 1.2.0, < 2.0)
62
+ rspec-support (~> 3.11.0)
63
+ rspec-mocks (3.11.1)
64
+ diff-lcs (>= 1.2.0, < 2.0)
65
+ rspec-support (~> 3.11.0)
66
+ rspec-support (3.11.0)
67
+ rubocop (1.31.0)
68
+ parallel (~> 1.10)
69
+ parser (>= 3.1.0.0)
70
+ rainbow (>= 2.2.2, < 4.0)
71
+ regexp_parser (>= 1.8, < 3.0)
72
+ rexml (>= 3.2.5, < 4.0)
73
+ rubocop-ast (>= 1.18.0, < 2.0)
74
+ ruby-progressbar (~> 1.7)
75
+ unicode-display_width (>= 1.4.0, < 3.0)
76
+ rubocop-ast (1.18.0)
77
+ parser (>= 3.1.1.0)
78
+ rubocop-rspec (2.11.1)
79
+ rubocop (~> 1.19)
80
+ ruby-progressbar (1.11.0)
81
+ simplecov (0.21.2)
82
+ docile (~> 1.1)
83
+ simplecov-html (~> 0.11)
84
+ simplecov_json_formatter (~> 0.1)
85
+ simplecov-html (0.12.3)
86
+ simplecov_json_formatter (0.1.4)
87
+ tzinfo (2.0.4)
88
+ concurrent-ruby (~> 1.0)
89
+ unicode-display_width (2.2.0)
90
+
91
+ PLATFORMS
92
+ ruby
93
+
94
+ DEPENDENCIES
95
+ assembly-objectfile!
96
+ byebug
97
+ json
98
+ pry-byebug
99
+ rake
100
+ rspec (~> 3.0)
101
+ rubocop (~> 1.25)
102
+ rubocop-rspec
103
+ simplecov
104
+
105
+ BUNDLED WITH
106
+ 2.3.4
@@ -16,7 +16,6 @@ Gem::Specification.new do |s|
16
16
  s.metadata['rubygems_mfa_required'] = 'true'
17
17
 
18
18
  s.files = `git ls-files`.split("\n")
19
- s.test_files = `git ls-files -- spec/*`.split("\n")
20
19
  s.bindir = 'exe'
21
20
  s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
21
  s.require_paths = ['lib']
@@ -25,13 +24,12 @@ Gem::Specification.new do |s|
25
24
 
26
25
  s.add_dependency 'activesupport', '>= 5.2.0'
27
26
  s.add_dependency 'deprecation'
28
- s.add_dependency 'dry-struct', '~> 1.0'
29
- s.add_dependency 'dry-types', '~> 1.1'
30
27
  s.add_dependency 'mime-types', '> 3'
31
28
  s.add_dependency 'mini_exiftool'
32
29
  s.add_dependency 'nokogiri'
33
30
 
34
31
  s.add_development_dependency 'json'
32
+ s.add_development_dependency 'pry-byebug'
35
33
  s.add_development_dependency 'rake'
36
34
  s.add_development_dependency 'rspec', '~> 3.0'
37
35
  s.add_development_dependency 'rubocop', '~> 1.25'
@@ -1,14 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'mini_exiftool'
4
+ require 'mime/types'
5
+ require 'active_support/core_ext/object/blank'
6
+
3
7
  module Assembly
4
8
  # This class contains generic methods to operate on any file.
5
9
  class ObjectFile
6
- include Assembly::ObjectFileable
7
-
8
10
  # Class level method that given an array of strings, return the longest common initial path. Useful for removing a common path from a set of filenames when producing content metadata
9
11
  #
10
12
  # @param [Array] strings Array of filenames with paths to operate on
11
- # @return [String] Common part of path of filenames passed in
13
+ # @return [String] longest common initial part of path of filenames passed in
12
14
  #
13
15
  # Example:
14
16
  # puts Assembly::ObjectFile.common_prefix(['/Users/peter/00/test.tif','/Users/peter/05/test.jp2']) # '/Users/peter/0'
@@ -25,5 +27,253 @@ module Assembly
25
27
  "#{common_prefix.split('/')[0..-2].join('/')}/" # if it was, then return the common prefix directly
26
28
  end
27
29
  end
30
+
31
+ attr_accessor :file_attributes, :label, :path, :provider_md5, :provider_sha1, :relative_path, :mime_type_order
32
+
33
+ VALID_MIMETYPE_METHODS = %i[override exif file extension].freeze
34
+
35
+ # @param [String] path full path to the file to be worked with
36
+ # @param [Hash<Symbol => Object>] params options used during content metadata generation
37
+ # @option params [Hash<Symbol => ['yes', 'no']>] :file_attributes e.g. {:preserve=>'yes',:shelve=>'no',:publish=>'no'}, defaults pulled from mimetype
38
+ # @option params [String] :label a resource label (files bundlded together will just get the first file's label attribute if set)
39
+ # @option params [String] :provider_md5 pre-computed MD5 checksum
40
+ # @option params [String] :provider_sha1 pre-computed SHA1 checksum
41
+ # @option params [String] :relative_path if you want the file ids in the content metadata it can be set, otherwise content metadata will get the full path
42
+ # @option params [Array] :mime_type_order can be set to the order in which you want mimetypes to be determined
43
+ # options are :override (from manual overide mapping if exists), :exif (from exif if exists),
44
+ # :extension (from file extension), and :file (from unix file system command)
45
+ # the default is defined in the private `default_mime_type_order` method but you can override to set your own order
46
+ # @example
47
+ # Assembly::ObjectFile.new('/input/path_to_file.tif')
48
+ def initialize(path, params = {})
49
+ @path = path
50
+ @label = params[:label]
51
+ @file_attributes = params[:file_attributes]
52
+ @relative_path = params[:relative_path]
53
+ @provider_md5 = params[:provider_md5]
54
+ @provider_sha1 = params[:provider_sha1]
55
+ @mime_type_order = params[:mime_type_order] || default_mime_type_order
56
+ end
57
+
58
+ # @return [String] base filename
59
+ # @example
60
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
61
+ # puts source_file.filename # "path_to_file.tif"
62
+ def filename
63
+ File.basename(path)
64
+ end
65
+
66
+ # @return [String] base directory
67
+ # @example
68
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
69
+ # puts source_file.dirname # "/input"
70
+ def dirname
71
+ File.dirname(path)
72
+ end
73
+
74
+ # @return [String] filename extension
75
+ # @example
76
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
77
+ # puts source_file.ext # ".tif"
78
+ def ext
79
+ File.extname(path)
80
+ end
81
+
82
+ # @return [String] base filename without extension
83
+ # @example
84
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
85
+ # puts source_file.filename # "path_to_file"
86
+ def filename_without_ext
87
+ File.basename(path, ext)
88
+ end
89
+
90
+ # @return [MiniExiftool] exif information stored as a hash and an object
91
+ # @example
92
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
93
+ # puts source_file.exif # hash with exif information
94
+ def exif
95
+ @exif ||= begin
96
+ check_for_file
97
+ MiniExiftool.new(path, replace_invalid_chars: '?')
98
+ end
99
+ end
100
+
101
+ # Computes md5 checksum or returns cached value
102
+ # @return [String] md5 checksum
103
+ # @example
104
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
105
+ # puts source_file.md5 # 'XXX123XXX1243XX1243'
106
+ def md5
107
+ check_for_file unless @md5
108
+ @md5 ||= Digest::MD5.file(path).hexdigest
109
+ end
110
+
111
+ # Computes sha1 checksum or return cached value
112
+ # @return [String] sha1 checksum
113
+ # @example
114
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
115
+ # puts source_file.sha1 # 'XXX123XXX1243XX1243'
116
+ def sha1
117
+ check_for_file unless @sha1
118
+ @sha1 ||= Digest::SHA1.file(path).hexdigest
119
+ end
120
+
121
+ # Returns mimetype information for the current file based on the ordering set in default_mime_type_order
122
+ # We stop computing mimetypes as soon as we have a method that returns a value
123
+ # @return [String] mime type
124
+ # @example
125
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
126
+ # puts source_file.mimetype # 'text/plain'
127
+ def mimetype
128
+ @mimetype ||= begin
129
+ check_for_file
130
+ mimetype = ''
131
+ mime_type_order.each do |mime_type_method|
132
+ mimetype = send("#{mime_type_method}_mimetype") if VALID_MIMETYPE_METHODS.include?(mime_type_method)
133
+ break if mimetype.present?
134
+ end
135
+ mimetype
136
+ end
137
+ end
138
+
139
+ # @return [Symbol] the type of object, could be :application (for PDF or Word, etc), :audio, :image, :message, :model, :multipart, :text or :video
140
+ # @example
141
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
142
+ # puts source_file.object_type # :image
143
+ def object_type
144
+ lookup = MIME::Types[mimetype][0]
145
+ lookup.nil? ? :other : lookup.media_type.to_sym
146
+ end
147
+
148
+ # @return [Boolean] if object is an image
149
+ # @example
150
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
151
+ # puts source_file.image? # true
152
+ def image?
153
+ object_type == :image
154
+ end
155
+
156
+ # Examines the input image for validity. Used to determine if image is a valid and useful image.
157
+ # If image is not a jp2, also checks if it is jp2able?
158
+ # @return [Boolean] true if image is valid, false if not.
159
+ # @example
160
+ # source_img = Assembly::ObjectFile.new('/input/path_to_file.tif')
161
+ # puts source_img.valid_image? # true
162
+ def valid_image?
163
+ return false unless image?
164
+
165
+ mimetype == 'image/jp2' || jp2able?
166
+ end
167
+
168
+ # @return [Boolean] true if image has a color profile, false if not.
169
+ # @example
170
+ # source_img = Assembly::ObjectFile.new('/input/path_to_file.tif')
171
+ # puts source_img.has_color_profile? # true
172
+ def has_color_profile?
173
+ return false unless exif
174
+
175
+ exif['profiledescription'] || exif['colorspace'] ? true : false
176
+ end
177
+
178
+ # Examines the input image for validity to create a jp2. Same as valid_image? but also confirms the existence of a profile description and further restricts mimetypes.
179
+ # It is used by the assembly robots to decide if a jp2 will be created and is also called before you create a jp2 using assembly-image.
180
+ # @return [Boolean] true if image should have a jp2 created, false if not.
181
+ # @example
182
+ # source_img = Assembly::ObjectFile.new('/input/path_to_file.tif')
183
+ # puts source_img.jp2able? # true
184
+ def jp2able?
185
+ return false unless exif
186
+
187
+ Assembly::VALID_IMAGE_MIMETYPES.include?(mimetype)
188
+ end
189
+
190
+ # Returns file size information for the current file in bytes.
191
+ # @return [Integer] file size in bytes
192
+ # @example
193
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
194
+ # puts source_file.filesize # 1345
195
+ def filesize
196
+ check_for_file
197
+ @filesize ||= File.size(path)
198
+ end
199
+
200
+ # Determines if the file exists (and is not a directory)
201
+ # @return [Boolean] file exists
202
+ # @example
203
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.tif')
204
+ # puts source_file.file_exists? # true
205
+ def file_exists?
206
+ @file_exists ||= (File.exist?(path) && !File.directory?(path))
207
+ end
208
+
209
+ private
210
+
211
+ # private method to check for file existence before operating on it
212
+ def check_for_file
213
+ raise "input file #{path} does not exist or is a directory" unless file_exists?
214
+ end
215
+
216
+ # prive method defining default preferred ordering of how mimetypes are determined
217
+ def default_mime_type_order
218
+ %i[override exif file extension]
219
+ end
220
+
221
+ # Returns mimetype information using the mime-types gem (based on a file extension lookup)
222
+ # @return [String] mime type for supplied file
223
+ # @example
224
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
225
+ # puts source_file.extension_mimetype # 'text/plain'
226
+ def extension_mimetype
227
+ @extension_mimetype ||= begin
228
+ mtype = MIME::Types.type_for(path).first
229
+ mtype ? mtype.content_type : ''
230
+ end
231
+ end
232
+
233
+ # Returns mimetype information for the current file based on unix file system command.
234
+ # @return [String] mime type for supplied file
235
+ # @example
236
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
237
+ # puts source_file.file_mimetype # 'text/plain'
238
+ def file_mimetype
239
+ @file_mimetype ||= begin
240
+ check_for_file
241
+ `file --mime-type "#{path}"`.delete("\n").split(':')[1].strip # first try and get the mimetype from the unix file command
242
+ end
243
+ end
244
+
245
+ # Returns mimetype information for the current file based on exif data (if available and not a trusted source that we'd rather get from the file system command)
246
+ # @return [String] mime type for supplied file
247
+ # @example
248
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
249
+ # puts source_file.exif_mimetype # 'text/plain'
250
+ def exif_mimetype
251
+ @exif_mimetype ||= begin
252
+ check_for_file
253
+ prefer_exif = !Assembly::TRUSTED_MIMETYPES.include?(file_mimetype) # if it's not a "trusted" mimetype and there is exif data; get the mimetype from the exif
254
+ exif.mimetype if exif&.mimetype && prefer_exif
255
+ end
256
+ end
257
+
258
+ # Returns mimetype information using the manual override mapping (based on a file extension lookup)
259
+ # @return [String] mime type for supplied file if a mapping exists for the file's extension
260
+ # @example
261
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.json')
262
+ # puts source_file.override_mimetype # 'application/json'
263
+ def override_mimetype
264
+ @override_mimetype ||= Assembly::OVERRIDE_MIMETYPES.fetch(ext.to_sym, '')
265
+ end
266
+
267
+ # @note Uses shell call to "file", only expected to work on unix based systems
268
+ # @return [String] encoding for supplied file
269
+ # @example
270
+ # source_file = Assembly::ObjectFile.new('/input/path_to_file.txt')
271
+ # puts source_file.encoding # 'us-ascii'
272
+ def encoding
273
+ @encoding ||= begin
274
+ check_for_file
275
+ `file --mime-encoding "#{path}"`.delete("\n").split(':')[1].strip
276
+ end
277
+ end
28
278
  end
29
279
  end
@@ -4,6 +4,6 @@
4
4
  module Assembly
5
5
  class ObjectFile
6
6
  # Gem version
7
- VERSION = '1.13.0'
7
+ VERSION = '2.0.0'
8
8
  end
9
9
  end
@@ -7,9 +7,6 @@ module Assembly
7
7
  # if input image is not one of these mime types, it will not be regarded as a valid image for the purpose of generating a JP2 derivative
8
8
  VALID_IMAGE_MIMETYPES = ['image/jpeg', 'image/tiff', 'image/tif', 'image/png'].freeze
9
9
 
10
- # if input file has one of these extensions in a 3D object, it will get the 3d resource type
11
- VALID_THREE_DIMENSION_EXTENTIONS = ['.obj'].freeze
12
-
13
10
  # the list of mimetypes that will be "trusted" by the unix file command; if a mimetype other than one of these is returned
14
11
  # by the file command, then a check will be made to see if exif data exists...if so, the mimetype returned by the exif data will be used
15
12
  # if no exif data exists, then the mimetype returned by the unix file command will be used
@@ -24,7 +21,5 @@ module Assembly
24
21
  }.freeze
25
22
  end
26
23
 
27
- require 'assembly-objectfile/content_metadata'
28
- require 'assembly-objectfile/object_fileable'
29
24
  require 'assembly-objectfile/object_file'
30
25
  require 'assembly-objectfile/version'