assembly-objectfile 1.12.0 → 2.1.0

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +14 -0
  3. data/.github/pull_request_template.md +1 -1
  4. data/.gitignore +0 -1
  5. data/.rubocop.yml +117 -12
  6. data/.rubocop_todo.yml +3 -109
  7. data/Gemfile.lock +97 -0
  8. data/README.md +7 -7
  9. data/assembly-objectfile.gemspec +8 -11
  10. data/config/boot.rb +0 -1
  11. data/lib/{assembly-objectfile → assembly/object_file}/version.rb +2 -2
  12. data/lib/{assembly-objectfile/object_fileable.rb → assembly/object_file.rb} +109 -104
  13. data/lib/assembly-objectfile.rb +12 -15
  14. data/spec/assembly/object_file_spec.rb +451 -0
  15. data/spec/spec_helper.rb +2 -31
  16. data/spec/test_data/empty.txt +0 -0
  17. metadata +23 -156
  18. data/.travis.yml +0 -20
  19. data/lib/assembly-objectfile/content_metadata/config.rb +0 -26
  20. data/lib/assembly-objectfile/content_metadata/file.rb +0 -63
  21. data/lib/assembly-objectfile/content_metadata/file_set.rb +0 -73
  22. data/lib/assembly-objectfile/content_metadata/file_set_builder.rb +0 -65
  23. data/lib/assembly-objectfile/content_metadata/nokogiri_builder.rb +0 -57
  24. data/lib/assembly-objectfile/content_metadata.rb +0 -117
  25. data/lib/assembly-objectfile/object_file.rb +0 -29
  26. data/profiles/AdobeRGB1998.icc +0 -0
  27. data/profiles/DotGain20.icc +0 -0
  28. data/profiles/sRGBIEC6196621.icc +0 -0
  29. data/spec/content_metadata_spec.rb +0 -809
  30. data/spec/object_file_spec.rb +0 -217
  31. data/spec/test_data/input/oo000oo0001/00/oo000oo0001_00_001.tif +0 -0
  32. data/spec/test_data/input/oo000oo0001/00/oo000oo0001_00_002.tif +0 -0
  33. data/spec/test_data/input/oo000oo0001/05/oo000oo0001_05_001.jp2 +0 -0
  34. data/spec/test_data/input/oo000oo0001/05/oo000oo0001_05_002.jp2 +0 -0
  35. data/spec/test_data/input/oo000oo0001/15/oo000oo0001_15_001.pdf +0 -1
  36. data/spec/test_data/input/oo000oo0001/15/oo000oo0001_15_002.pdf +0 -1
  37. data/spec/test_data/input/oo000oo0001/31/oo000oo0001_31_001.pdf +0 -1
  38. data/spec/test_data/input/oo000oo0001/50/oo000oo0001_50_001.tif +0 -0
  39. data/spec/test_data/input/oo000oo0001/oo000oo0001_book.pdf +0 -1
  40. data/spec/test_data/input/res1_image1.jp2 +0 -0
  41. data/spec/test_data/input/res1_image2.jp2 +0 -0
  42. data/spec/test_data/input/res1_image2.tif +0 -0
  43. data/spec/test_data/input/res1_teifile.txt +0 -1
  44. data/spec/test_data/input/res2_image1.jp2 +0 -0
  45. data/spec/test_data/input/res2_image1.tif +0 -0
  46. data/spec/test_data/input/res2_image2.jp2 +0 -0
  47. data/spec/test_data/input/res2_image2.tif +0 -0
  48. data/spec/test_data/input/res2_teifile.txt +0 -1
  49. data/spec/test_data/input/res2_textfile.txt +0 -1
  50. data/spec/test_data/input/res3_image1.jp2 +0 -0
  51. data/spec/test_data/input/res3_image1.tif +0 -0
  52. data/spec/test_data/input/res3_teifile.txt +0 -1
  53. data/spec/test_data/input/test.pdf +0 -1
  54. data/spec/test_data/input/test.svg +0 -2
  55. data/spec/test_data/input/test2.jp2 +0 -0
  56. data/spec/test_data/input/test2.tif +0 -0
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: 1.12.0
4
+ version: 2.1.0
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-02-18 00:00:00.000000000 Z
14
+ date: 2022-07-19 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
@@ -27,48 +27,6 @@ dependencies:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
29
  version: 5.2.0
30
- - !ruby/object:Gem::Dependency
31
- name: deprecation
32
- requirement: !ruby/object:Gem::Requirement
33
- requirements:
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: '0'
37
- type: :runtime
38
- prerelease: false
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: '0'
44
- - !ruby/object:Gem::Dependency
45
- name: dry-struct
46
- requirement: !ruby/object:Gem::Requirement
47
- requirements:
48
- - - "~>"
49
- - !ruby/object:Gem::Version
50
- version: '1.0'
51
- type: :runtime
52
- prerelease: false
53
- version_requirements: !ruby/object:Gem::Requirement
54
- requirements:
55
- - - "~>"
56
- - !ruby/object:Gem::Version
57
- version: '1.0'
58
- - !ruby/object:Gem::Dependency
59
- name: dry-types
60
- requirement: !ruby/object:Gem::Requirement
61
- requirements:
62
- - - "~>"
63
- - !ruby/object:Gem::Version
64
- version: '1.1'
65
- type: :runtime
66
- prerelease: false
67
- version_requirements: !ruby/object:Gem::Requirement
68
- requirements:
69
- - - "~>"
70
- - !ruby/object:Gem::Version
71
- version: '1.1'
72
30
  - !ruby/object:Gem::Dependency
73
31
  name: mime-types
74
32
  requirement: !ruby/object:Gem::Requirement
@@ -98,21 +56,7 @@ dependencies:
98
56
  - !ruby/object:Gem::Version
99
57
  version: '0'
100
58
  - !ruby/object:Gem::Dependency
101
- name: nokogiri
102
- requirement: !ruby/object:Gem::Requirement
103
- requirements:
104
- - - ">="
105
- - !ruby/object:Gem::Version
106
- version: '0'
107
- type: :runtime
108
- prerelease: false
109
- version_requirements: !ruby/object:Gem::Requirement
110
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- version: '0'
114
- - !ruby/object:Gem::Dependency
115
- name: json
59
+ name: pry-byebug
116
60
  requirement: !ruby/object:Gem::Requirement
117
61
  requirements:
118
62
  - - ">="
@@ -157,16 +101,16 @@ dependencies:
157
101
  name: rubocop
158
102
  requirement: !ruby/object:Gem::Requirement
159
103
  requirements:
160
- - - ">="
104
+ - - "~>"
161
105
  - !ruby/object:Gem::Version
162
- version: '0'
106
+ version: '1.25'
163
107
  type: :development
164
108
  prerelease: false
165
109
  version_requirements: !ruby/object:Gem::Requirement
166
110
  requirements:
167
- - - ">="
111
+ - - "~>"
168
112
  - !ruby/object:Gem::Version
169
- version: '0'
113
+ version: '1.25'
170
114
  - !ruby/object:Gem::Dependency
171
115
  name: rubocop-rspec
172
116
  requirement: !ruby/object:Gem::Requirement
@@ -185,16 +129,16 @@ dependencies:
185
129
  name: simplecov
186
130
  requirement: !ruby/object:Gem::Requirement
187
131
  requirements:
188
- - - "~>"
132
+ - - ">="
189
133
  - !ruby/object:Gem::Version
190
- version: 0.17.0
134
+ version: '0'
191
135
  type: :development
192
136
  prerelease: false
193
137
  version_requirements: !ruby/object:Gem::Requirement
194
138
  requirements:
195
- - - "~>"
139
+ - - ">="
196
140
  - !ruby/object:Gem::Version
197
- version: 0.17.0
141
+ version: '0'
198
142
  description: Get exif data, file sizes and more.
199
143
  email:
200
144
  - pmangiafico@stanford.edu
@@ -202,14 +146,15 @@ executables: []
202
146
  extensions: []
203
147
  extra_rdoc_files: []
204
148
  files:
149
+ - ".circleci/config.yml"
205
150
  - ".github/ISSUE_TEMPLATE/bug_report.md"
206
151
  - ".github/pull_request_template.md"
207
152
  - ".gitignore"
208
153
  - ".rubocop.yml"
209
154
  - ".rubocop_todo.yml"
210
155
  - ".rvmrc.example"
211
- - ".travis.yml"
212
156
  - Gemfile
157
+ - Gemfile.lock
213
158
  - LICENSE
214
159
  - README.md
215
160
  - Rakefile
@@ -218,62 +163,27 @@ files:
218
163
  - bin/run_all_tests
219
164
  - config/boot.rb
220
165
  - lib/assembly-objectfile.rb
221
- - lib/assembly-objectfile/content_metadata.rb
222
- - lib/assembly-objectfile/content_metadata/config.rb
223
- - lib/assembly-objectfile/content_metadata/file.rb
224
- - lib/assembly-objectfile/content_metadata/file_set.rb
225
- - lib/assembly-objectfile/content_metadata/file_set_builder.rb
226
- - lib/assembly-objectfile/content_metadata/nokogiri_builder.rb
227
- - lib/assembly-objectfile/object_file.rb
228
- - lib/assembly-objectfile/object_fileable.rb
229
- - lib/assembly-objectfile/version.rb
230
- - profiles/AdobeRGB1998.icc
231
- - profiles/DotGain20.icc
232
- - profiles/sRGBIEC6196621.icc
233
- - spec/content_metadata_spec.rb
234
- - spec/object_file_spec.rb
166
+ - lib/assembly/object_file.rb
167
+ - lib/assembly/object_file/version.rb
168
+ - spec/assembly/object_file_spec.rb
235
169
  - spec/spec_helper.rb
170
+ - spec/test_data/empty.txt
236
171
  - spec/test_data/input/.empty
237
172
  - spec/test_data/input/file_with_no_exif.xml
238
- - spec/test_data/input/oo000oo0001/00/oo000oo0001_00_001.tif
239
- - spec/test_data/input/oo000oo0001/00/oo000oo0001_00_002.tif
240
- - spec/test_data/input/oo000oo0001/05/oo000oo0001_05_001.jp2
241
- - spec/test_data/input/oo000oo0001/05/oo000oo0001_05_002.jp2
242
- - spec/test_data/input/oo000oo0001/15/oo000oo0001_15_001.pdf
243
- - spec/test_data/input/oo000oo0001/15/oo000oo0001_15_002.pdf
244
- - spec/test_data/input/oo000oo0001/31/oo000oo0001_31_001.pdf
245
- - spec/test_data/input/oo000oo0001/50/oo000oo0001_50_001.tif
246
- - spec/test_data/input/oo000oo0001/oo000oo0001_book.pdf
247
- - spec/test_data/input/res1_image1.jp2
248
173
  - spec/test_data/input/res1_image1.tif
249
- - spec/test_data/input/res1_image2.jp2
250
- - spec/test_data/input/res1_image2.tif
251
- - spec/test_data/input/res1_teifile.txt
252
174
  - spec/test_data/input/res1_textfile.txt
253
175
  - spec/test_data/input/res1_transcript.pdf
254
- - spec/test_data/input/res2_image1.jp2
255
- - spec/test_data/input/res2_image1.tif
256
- - spec/test_data/input/res2_image2.jp2
257
- - spec/test_data/input/res2_image2.tif
258
- - spec/test_data/input/res2_teifile.txt
259
- - spec/test_data/input/res2_textfile.txt
260
- - spec/test_data/input/res3_image1.jp2
261
- - spec/test_data/input/res3_image1.tif
262
- - spec/test_data/input/res3_teifile.txt
263
176
  - spec/test_data/input/someobject.obj
264
177
  - spec/test_data/input/someobject.ply
265
178
  - spec/test_data/input/test.jp2
266
179
  - spec/test_data/input/test.json
267
- - spec/test_data/input/test.pdf
268
- - spec/test_data/input/test.svg
269
180
  - spec/test_data/input/test.tif
270
- - spec/test_data/input/test2.jp2
271
- - spec/test_data/input/test2.tif
272
181
  - spec/test_data/input/test_no_color_profile.tif
273
182
  homepage: https://github.com/sul-dlss/assembly-objectfile
274
183
  licenses:
275
184
  - ALv2
276
- metadata: {}
185
+ metadata:
186
+ rubygems_mfa_required: 'true'
277
187
  post_install_message:
278
188
  rdoc_options: []
279
189
  require_paths:
@@ -282,10 +192,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
282
192
  requirements:
283
193
  - - ">="
284
194
  - !ruby/object:Gem::Version
285
- version: '2.5'
286
- - - "<"
287
- - !ruby/object:Gem::Version
288
- version: '4'
195
+ version: '3.0'
289
196
  required_rubygems_version: !ruby/object:Gem::Requirement
290
197
  requirements:
291
198
  - - ">="
@@ -295,46 +202,6 @@ requirements: []
295
202
  rubygems_version: 3.2.32
296
203
  signing_key:
297
204
  specification_version: 4
298
- summary: Ruby immplementation of file services needed to prepare objects to be accessioned
299
- in SULAIR digital library
300
- test_files:
301
- - spec/content_metadata_spec.rb
302
- - spec/object_file_spec.rb
303
- - spec/spec_helper.rb
304
- - spec/test_data/input/.empty
305
- - spec/test_data/input/file_with_no_exif.xml
306
- - spec/test_data/input/oo000oo0001/00/oo000oo0001_00_001.tif
307
- - spec/test_data/input/oo000oo0001/00/oo000oo0001_00_002.tif
308
- - spec/test_data/input/oo000oo0001/05/oo000oo0001_05_001.jp2
309
- - spec/test_data/input/oo000oo0001/05/oo000oo0001_05_002.jp2
310
- - spec/test_data/input/oo000oo0001/15/oo000oo0001_15_001.pdf
311
- - spec/test_data/input/oo000oo0001/15/oo000oo0001_15_002.pdf
312
- - spec/test_data/input/oo000oo0001/31/oo000oo0001_31_001.pdf
313
- - spec/test_data/input/oo000oo0001/50/oo000oo0001_50_001.tif
314
- - spec/test_data/input/oo000oo0001/oo000oo0001_book.pdf
315
- - spec/test_data/input/res1_image1.jp2
316
- - spec/test_data/input/res1_image1.tif
317
- - spec/test_data/input/res1_image2.jp2
318
- - spec/test_data/input/res1_image2.tif
319
- - spec/test_data/input/res1_teifile.txt
320
- - spec/test_data/input/res1_textfile.txt
321
- - spec/test_data/input/res1_transcript.pdf
322
- - spec/test_data/input/res2_image1.jp2
323
- - spec/test_data/input/res2_image1.tif
324
- - spec/test_data/input/res2_image2.jp2
325
- - spec/test_data/input/res2_image2.tif
326
- - spec/test_data/input/res2_teifile.txt
327
- - spec/test_data/input/res2_textfile.txt
328
- - spec/test_data/input/res3_image1.jp2
329
- - spec/test_data/input/res3_image1.tif
330
- - spec/test_data/input/res3_teifile.txt
331
- - spec/test_data/input/someobject.obj
332
- - spec/test_data/input/someobject.ply
333
- - spec/test_data/input/test.jp2
334
- - spec/test_data/input/test.json
335
- - spec/test_data/input/test.pdf
336
- - spec/test_data/input/test.svg
337
- - spec/test_data/input/test.tif
338
- - spec/test_data/input/test2.jp2
339
- - spec/test_data/input/test2.tif
340
- - spec/test_data/input/test_no_color_profile.tif
205
+ summary: Ruby implementation of file services needed to prepare objects to be accessioned
206
+ into the Stanford Digital Repository
207
+ test_files: []
data/.travis.yml DELETED
@@ -1,20 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.5.7
4
- - 2.6.5
5
- addons:
6
- apt:
7
- packages:
8
- - libimage-exiftool-perl
9
- before_script:
10
- - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
11
- - chmod +x ./cc-test-reporter
12
- - ./cc-test-reporter before-build
13
- script:
14
- - bundle exec rubocop
15
- - bundle exec rake
16
- after_script:
17
- - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
18
-
19
- notifications:
20
- email: false
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'dry-struct'
4
- require 'dry-types'
5
-
6
- module Assembly
7
- class ContentMetadata
8
- # Types for the configuration
9
- module Types
10
- include Dry.Types()
11
- end
12
-
13
- # Represents a configuration for generating the content metadata
14
- class Config < Dry::Struct
15
- STYLES = %w[image file book map 3d document webarchive-seed].freeze
16
- READING_ORDERS = %w[ltr rtl].freeze
17
- attribute :auto_labels, Types::Strict::Bool.default(true)
18
- attribute :flatten_folder_structure, Types::Strict::Bool.default(false)
19
- attribute :add_file_attributes, Types::Strict::Bool.default(false)
20
- attribute :add_exif, Types::Strict::Bool.default(false)
21
- attribute :file_attributes, Types::Strict::Hash.default({}.freeze)
22
- attribute :type, Types::Strict::String.enum(*STYLES)
23
- attribute :reading_order, Types::Strict::String.default('ltr').enum(*READING_ORDERS)
24
- end
25
- end
26
- end
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/module/delegation'
4
-
5
- module Assembly
6
- class ContentMetadata
7
- # Represents a single File
8
- class File
9
- # default publish/preserve/shelve attributes used in content metadata
10
- # if no mimetype specific attributes are specified for a given file, define some defaults, and override for specific mimetypes below
11
- ATTRIBUTES_FOR_TYPE = {
12
- 'default' => { preserve: 'yes', shelve: 'no', publish: 'no' },
13
- 'image/tif' => { preserve: 'yes', shelve: 'no', publish: 'no' },
14
- 'image/tiff' => { preserve: 'yes', shelve: 'no', publish: 'no' },
15
- 'image/jp2' => { preserve: 'no', shelve: 'yes', publish: 'yes' },
16
- 'image/jpeg' => { preserve: 'yes', shelve: 'no', publish: 'no' },
17
- 'audio/wav' => { preserve: 'yes', shelve: 'no', publish: 'no' },
18
- 'audio/x-wav' => { preserve: 'yes', shelve: 'no', publish: 'no' },
19
- 'audio/mp3' => { preserve: 'no', shelve: 'yes', publish: 'yes' },
20
- 'audio/mpeg' => { preserve: 'no', shelve: 'yes', publish: 'yes' },
21
- 'application/pdf' => { preserve: 'yes', shelve: 'yes', publish: 'yes' },
22
- 'plain/text' => { preserve: 'yes', shelve: 'yes', publish: 'yes' },
23
- 'text/plain' => { preserve: 'yes', shelve: 'yes', publish: 'yes' },
24
- 'image/png' => { preserve: 'yes', shelve: 'yes', publish: 'no' },
25
- 'application/zip' => { preserve: 'yes', shelve: 'no', publish: 'no' },
26
- 'application/json' => { preserve: 'yes', shelve: 'yes', publish: 'yes' }
27
- }.freeze
28
-
29
- # @param [Symbol] bundle
30
- # @param [Assembly::ObjectFile] file
31
- # @param style
32
- def initialize(file:, bundle: nil, style: nil)
33
- @bundle = bundle
34
- @file = file
35
- @style = style
36
- end
37
-
38
- delegate :sha1, :md5, :provider_md5, :provider_sha1, :mimetype, :filesize, :image?, :valid_image?, to: :file
39
-
40
- def file_id(common_path:, flatten_folder_structure:)
41
- # set file id attribute, first check the relative_path parameter on the object, and if it is set, just use that
42
- return file.relative_path if file.relative_path
43
-
44
- # if the relative_path attribute is not set, then use the path attribute and check to see if we need to remove the common part of the path
45
- file_id = common_path ? file.path.gsub(common_path, '') : file.path
46
- file_id = ::File.basename(file_id) if flatten_folder_structure
47
- file_id
48
- end
49
-
50
- def file_attributes(provided_file_attributes)
51
- file.file_attributes || provided_file_attributes[mimetype] || provided_file_attributes['default'] || ATTRIBUTES_FOR_TYPE[mimetype] || ATTRIBUTES_FOR_TYPE['default']
52
- end
53
-
54
- def image_data
55
- { height: file.exif.imageheight, width: file.exif.imagewidth }
56
- end
57
-
58
- private
59
-
60
- attr_reader :file
61
- end
62
- end
63
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/object/blank'
4
-
5
- module Assembly
6
- class ContentMetadata
7
- # Represents a groups of related Files, such as a single master file and the derivatives
8
- class FileSet
9
- # @param [Boolean] dpg (false) is it a dpg bundle?
10
- # @param [Array<Assembly::ObjectFile>] resource_files
11
- # @param style
12
- def initialize(resource_files:, style:, dpg: false)
13
- @dpg = dpg
14
- @resource_files = resource_files
15
- @style = style
16
- end
17
-
18
- # objects in the special DPG folders are always type=object when we using :bundle=>:dpg
19
- # otherwise look at the style to determine the resource_type_description
20
- def resource_type_description
21
- @resource_type_description ||= special_dpg_resource? ? 'object' : resource_type_descriptions
22
- end
23
-
24
- def label_from_file(default:)
25
- resource_files.find { |obj| obj.label.present? }&.label || default
26
- end
27
-
28
- def files
29
- resource_files.map { |file| File.new(file: file) }
30
- end
31
-
32
- private
33
-
34
- attr_reader :dpg, :resource_files, :style
35
-
36
- def special_dpg_resource?
37
- return false unless dpg
38
-
39
- resource_files.collect { |obj| ContentMetadata.special_dpg_folder?(obj.dpg_folder) }.include?(true)
40
- end
41
-
42
- # rubocop:disable Metrics/CyclomaticComplexity
43
- def resource_type_descriptions
44
- # grab all of the file types within a resource into an array so we can decide what the resource type should be
45
- resource_file_types = resource_files.collect(&:object_type)
46
- resource_has_non_images = !(resource_file_types - [:image]).empty?
47
-
48
- case style
49
- when :simple_image, :map, :'webarchive-seed'
50
- 'image'
51
- when :file
52
- 'file'
53
- when :simple_book # in a simple book project, all resources are pages unless they are *all* non-images -- if so, switch the type to object
54
- resource_has_non_images && resource_file_types.include?(:image) == false ? 'object' : 'page'
55
- when :book_as_image # same as simple book, but all resources are images instead of pages, unless we need to switch them to object type
56
- resource_has_non_images && resource_file_types.include?(:image) == false ? 'object' : 'image'
57
- when :book_with_pdf # in book with PDF type, if we find a resource with *any* non images, switch it's type from book to object
58
- resource_has_non_images ? 'object' : 'page'
59
- when :document
60
- 'document'
61
- when :'3d'
62
- resource_extensions = resource_files.collect(&:ext)
63
- if (resource_extensions & VALID_THREE_DIMENSION_EXTENTIONS).empty? # if this resource contains no known 3D file extensions, the resource type is file
64
- 'file'
65
- else # otherwise the resource type is 3d
66
- '3d'
67
- end
68
- end
69
- end
70
- # rubocop:enable Metrics/CyclomaticComplexity
71
- end
72
- end
73
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Assembly
4
- class ContentMetadata
5
- # Builds a groups of related Files, based on bundle
6
- class FileSetBuilder
7
- # @param [Symbol] bundle one of: :default, :filename, :dpg or :prebundled
8
- # @param [Array<Assembly::ObjectFile>] objects
9
- # @param [Symbol] style one of: :simple_image, :file, :simple_book, :book_as_image, :book_with_pdf, :map, or :'3d'
10
- def self.build(bundle:, objects:, style:)
11
- new(bundle: bundle, objects: objects, style: style).build
12
- end
13
-
14
- def initialize(bundle:, objects:, style:)
15
- @bundle = bundle
16
- @objects = objects
17
- @style = style
18
- end
19
-
20
- # @return [Array<FileSet>] a list of filesets in the object
21
- def build
22
- case bundle
23
- when :default # one resource per object
24
- objects.collect { |obj| FileSet.new(resource_files: [obj], style: style) }
25
- when :filename # one resource per distinct filename (excluding extension)
26
- build_for_filename
27
- when :dpg # group by DPG filename
28
- build_for_dpg
29
- when :prebundled
30
- # if the user specifies this method, they will pass in an array of arrays, indicating resources, so we don't need to bundle in the gem
31
- # This is used by the assemblyWF if you have stubContentMetadata.xml
32
- objects.map { |inner| FileSet.new(resource_files: inner, style: style) }
33
- else
34
- raise 'Invalid bundle method'
35
- end
36
- end
37
-
38
- private
39
-
40
- attr_reader :bundle, :objects, :style
41
-
42
- def build_for_filename
43
- # loop over distinct filenames, this determines how many resources we will have and
44
- # create one resource node per distinct filename, collecting the relevant objects with the distinct filename into that resource
45
- distinct_filenames = objects.collect(&:filename_without_ext).uniq # find all the unique filenames in the set of objects, leaving off extensions and base paths
46
- distinct_filenames.map do |distinct_filename|
47
- FileSet.new(resource_files: objects.collect { |obj| obj if obj.filename_without_ext == distinct_filename }.compact,
48
- style: style)
49
- end
50
- end
51
-
52
- def build_for_dpg
53
- # loop over distinct dpg base names, this determines how many resources we will have and
54
- # create one resource node per distinct dpg base name, collecting the relevant objects with the distinct names into that resource
55
-
56
- distinct_filenames = objects.collect(&:dpg_basename).uniq # find all the unique DPG filenames in the set of objects
57
- resources = distinct_filenames.map do |distinct_filename|
58
- FileSet.new(dpg: true, resource_files: objects.collect { |obj| obj if obj.dpg_basename == distinct_filename && !ContentMetadata.special_dpg_folder?(obj.dpg_folder) }.compact, style: style)
59
- end
60
- objects.each { |obj| resources << FileSet.new(dpg: true, resource_files: [obj], style: style) if ContentMetadata.special_dpg_folder?(obj.dpg_folder) } # certain subfolders require individual resources for files within them regardless of file-naming convention
61
- resources
62
- end
63
- end
64
- end
65
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Assembly
4
- class ContentMetadata
5
- # Builds a nokogiri representation of the content metadata
6
- class NokogiriBuilder
7
- # @param [Array<Fileset>] filesets
8
- # @param [String] druid
9
- # @param [String] common_path
10
- # @param [Config] config
11
- def self.build(filesets:, druid:, common_path:, config:)
12
- # a counter to use when creating auto-labels for resources, with incremenets for each type
13
- resource_type_counters = Hash.new(0)
14
- pid = druid.gsub('druid:', '') # remove druid prefix when creating IDs
15
-
16
- Nokogiri::XML::Builder.new do |xml|
17
- xml.contentMetadata(objectId: druid.to_s, type: config.type) do
18
- xml.bookData(readingOrder: config.reading_order) if config.type == 'book'
19
-
20
- filesets.each_with_index do |fileset, index| # iterate over all the resources
21
- # start a new resource element
22
- sequence = index + 1
23
-
24
- resource_type_counters[fileset.resource_type_description] += 1 # each resource type description gets its own incrementing counter
25
-
26
- xml.resource(id: "#{pid}_#{sequence}", sequence: sequence, type: fileset.resource_type_description) do
27
- # create a generic resource label if needed
28
- default_label = config.auto_labels ? "#{fileset.resource_type_description.capitalize} #{resource_type_counters[fileset.resource_type_description]}" : ''
29
-
30
- # but if one of the files has a label, use it instead
31
- resource_label = fileset.label_from_file(default: default_label)
32
-
33
- xml.label(resource_label) unless resource_label.empty?
34
- fileset.files.each do |cm_file| # iterate over all the files in a resource
35
- xml_file_params = { id: cm_file.file_id(common_path: common_path, flatten_folder_structure: config.flatten_folder_structure) }
36
- xml_file_params.merge!(cm_file.file_attributes(config.file_attributes)) if config.add_file_attributes
37
- xml_file_params.merge!(mimetype: cm_file.mimetype, size: cm_file.filesize) if config.add_exif
38
-
39
- xml.file(xml_file_params) do
40
- if config.add_exif # add exif info if the user requested it
41
- xml.checksum(cm_file.sha1, type: 'sha1')
42
- xml.checksum(cm_file.md5, type: 'md5')
43
- xml.imageData(cm_file.image_data) if cm_file.valid_image? # add image data for an image
44
- elsif cm_file.provider_md5 || cm_file.provider_sha1 # if we did not add exif info, see if there are user supplied checksums to add
45
- xml.checksum(cm_file.provider_sha1, type: 'sha1') if cm_file.provider_sha1
46
- xml.checksum(cm_file.provider_md5, type: 'md5') if cm_file.provider_md5
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end
55
- end
56
- end
57
- end