derivative-rodeo 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +6 -0
  3. data/LICENSE +15 -0
  4. data/README.md +251 -0
  5. data/Rakefile +42 -0
  6. data/derivative_rodeo.gemspec +54 -0
  7. data/lib/derivative/rodeo.rb +3 -0
  8. data/lib/derivative-rodeo.rb +3 -0
  9. data/lib/derivative_rodeo/configuration.rb +95 -0
  10. data/lib/derivative_rodeo/errors.rb +56 -0
  11. data/lib/derivative_rodeo/generators/base_generator.rb +200 -0
  12. data/lib/derivative_rodeo/generators/concerns/copy_file_concern.rb +28 -0
  13. data/lib/derivative_rodeo/generators/copy_generator.rb +14 -0
  14. data/lib/derivative_rodeo/generators/hocr_generator.rb +112 -0
  15. data/lib/derivative_rodeo/generators/monochrome_generator.rb +39 -0
  16. data/lib/derivative_rodeo/generators/pdf_split_generator.rb +61 -0
  17. data/lib/derivative_rodeo/generators/thumbnail_generator.rb +38 -0
  18. data/lib/derivative_rodeo/generators/word_coordinates_generator.rb +39 -0
  19. data/lib/derivative_rodeo/services/base_service.rb +15 -0
  20. data/lib/derivative_rodeo/services/convert_uri_via_template_service.rb +87 -0
  21. data/lib/derivative_rodeo/services/extract_word_coordinates_from_hocr_sgml_service.rb +218 -0
  22. data/lib/derivative_rodeo/services/image_identify_service.rb +89 -0
  23. data/lib/derivative_rodeo/services/image_jp2_service.rb +112 -0
  24. data/lib/derivative_rodeo/services/image_service.rb +73 -0
  25. data/lib/derivative_rodeo/services/pdf_splitter/base.rb +177 -0
  26. data/lib/derivative_rodeo/services/pdf_splitter/jpg_page.rb +14 -0
  27. data/lib/derivative_rodeo/services/pdf_splitter/pages_summary.rb +130 -0
  28. data/lib/derivative_rodeo/services/pdf_splitter/png_page.rb +26 -0
  29. data/lib/derivative_rodeo/services/pdf_splitter/tiff_page.rb +52 -0
  30. data/lib/derivative_rodeo/services/pdf_splitter_service.rb +19 -0
  31. data/lib/derivative_rodeo/services/url_service.rb +42 -0
  32. data/lib/derivative_rodeo/storage_locations/base_location.rb +251 -0
  33. data/lib/derivative_rodeo/storage_locations/concerns/download_concern.rb +67 -0
  34. data/lib/derivative_rodeo/storage_locations/file_location.rb +39 -0
  35. data/lib/derivative_rodeo/storage_locations/http_location.rb +13 -0
  36. data/lib/derivative_rodeo/storage_locations/https_location.rb +13 -0
  37. data/lib/derivative_rodeo/storage_locations/s3_location.rb +103 -0
  38. data/lib/derivative_rodeo/storage_locations/sqs_location.rb +187 -0
  39. data/lib/derivative_rodeo/technical_metadata.rb +23 -0
  40. data/lib/derivative_rodeo/version.rb +5 -0
  41. data/lib/derivative_rodeo.rb +36 -0
  42. metadata +339 -0
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-s3'
4
+
5
+ module DerivativeRodeo
6
+ module StorageLocations
7
+ ##
8
+ # Location to download and upload files to S3
9
+ #
10
+ class S3Location < BaseLocation
11
+ attr_writer :bucket
12
+ ##
13
+ # Create a new uri of the classes type. Parts argument should have a default in
14
+ # implementing classes. Must support a number or the symbol :all
15
+ #
16
+ # @api public
17
+ #
18
+ # @param path [String]
19
+ # @param parts [Integer, :all], defaults to 2 for S3 which is parent_dir/file_name.ext
20
+ # @return [String]
21
+ def self.create_uri(path:, parts: 2)
22
+ file_path = file_path_from_parts(path: path, parts: parts)
23
+ File.join("#{adapter_prefix}/#{file_path}")
24
+ end
25
+
26
+ ##
27
+ # @param config [DerivativeRodeo::Configuration]
28
+ # @return [String]
29
+ def self.adapter_prefix(config: DerivativeRodeo.config)
30
+ "#{scheme}://#{config.aws_s3_bucket}.s3.#{config.aws_s3_region}.amazonaws.com"
31
+ end
32
+
33
+ ##
34
+ # @api public
35
+ # download or copy the file to a tmp path
36
+ # deletes the tmp file after the block is executed
37
+ #
38
+ # @return [String] the path to the tmp file
39
+ def with_existing_tmp_path(&block)
40
+ with_tmp_path(lambda { |file_path, tmp_file_path, exist|
41
+ raise Errors::FileMissingError unless exist
42
+ obj = bucket.object(file_path)
43
+ obj.download_file(tmp_file_path)
44
+ }, &block)
45
+ end
46
+
47
+ ##
48
+ # @api public
49
+ #
50
+ # Existance is futile
51
+ # @return [Boolean]
52
+ def exist?
53
+ bucket.objects(prefix: file_path).count.positive?
54
+ end
55
+
56
+ ##
57
+ # @api public
58
+ # write the tmp file to the file_uri
59
+ #
60
+ # @return [String] the file_uri
61
+ def write
62
+ raise Errors::FileMissingError("Use write within a with__new_tmp_path block and fill the tmp file with data before writing") unless File.exist?(tmp_file_path)
63
+
64
+ obj = bucket.object(file_path)
65
+ obj.upload_file(tmp_file_path)
66
+ file_uri
67
+ end
68
+
69
+ ##
70
+ # @api private
71
+ #
72
+ # @return [Aws::S3::Resource]
73
+ def resource
74
+ @resource ||= if DerivativeRodeo.config.aws_s3_access_key_id
75
+ Aws::S3::Resource.new(region: DerivativeRodeo.config.aws_s3_region,
76
+ credentials: Aws::Credentials.new(
77
+ DerivativeRodeo.config.aws_s3_access_key_id,
78
+ DerivativeRodeo.config.aws_s3_secret_access_key
79
+ ))
80
+ else
81
+ Aws::S3::Resource.new
82
+ end
83
+ end
84
+
85
+ ##
86
+ # @api private
87
+ # https://long-term-video-storage.s3.eu-west-1.amazonaws.com/path1/path2/file.tld
88
+ def bucket_name
89
+ @bucket_name ||= file_uri.match(%r{s3://(.+)\.s3})&.[](1)
90
+ rescue StandardError
91
+ raise Errors::BucketMissingError
92
+ end
93
+
94
+ def bucket
95
+ @bucket ||= resource.bucket(bucket_name)
96
+ end
97
+
98
+ def file_path
99
+ @file_path ||= @file_uri.sub(%r{.+://.+?/}, '')
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aws-sdk-sqs'
4
+ require 'cgi'
5
+
6
+ ActiveSupport::Inflector.inflections(:en) do |inflect|
7
+ inflect.uncountable 'sqs'
8
+ end
9
+
10
+ module DerivativeRodeo
11
+ module StorageLocations
12
+ ##
13
+ # Location to download and upload files to Sqs
14
+ # It uploads a file_uri to the queue, not the contents of that file
15
+ # reading from the queue is not currently implemented
16
+ class SqsLocation < BaseLocation
17
+ class_attribute :batch_size, default: 10
18
+
19
+ attr_writer :client
20
+
21
+ ##
22
+ # Create a new uri of the classes type. Parts argument should have a default in
23
+ # implementing classes. Must support a number or the symbol :all
24
+ #
25
+ # @api public
26
+ #
27
+ # @param path [String]
28
+ # @param parts [Integer, :all], defaults to 1 for Sqs which is file_name.ext. We use 1 because it helps with tmp files, but the actual sqs queue does not have a file path
29
+ # @return [String]
30
+ def self.create_uri(path:, parts: 1)
31
+ file_path = file_path_from_parts(path: path, parts: parts)
32
+ "#{adapter_prefix}#{file_path}"
33
+ end
34
+
35
+ def self.adapter_prefix(config: DerivativeRodeo.config)
36
+ "#{scheme}://#{config.aws_sqs_region}.amazonaws.com/#{config.aws_sqs_account_id}/#{config.aws_sqs_queue}/"
37
+ end
38
+
39
+ # TODO: implement read
40
+ # ##
41
+ # # @api public
42
+ # # download or copy the file to a tmp path
43
+ # # deletes the tmp file after the block is executed
44
+ # #
45
+ # # @return [String] the path to the tmp file
46
+ # def with_existing_tmp_path(&block)
47
+ # with_tmp_path(lambda { |_file_path, tmp_file_path, exist|
48
+ # raise Errors::FileMissingError unless exist
49
+ # File.open(tmp_file_path, 'w') do |file|
50
+ # read_batch.each do |message|
51
+ # file.write(message)
52
+ # end
53
+ # end
54
+ # }, &block)
55
+ # end
56
+
57
+ ##
58
+ # @api public
59
+ #
60
+ # Existance is futile. And there's not way to check if a specific item is in an sqs queue
61
+ # @return [Boolean]
62
+ def exist?
63
+ false
64
+ end
65
+
66
+ ##
67
+ # @api public
68
+ # write the tmp file to the file_uri
69
+ #
70
+ # @return [String] the file_uri
71
+ def write
72
+ raise Errors::FileMissingError("Use write within a with__new_tmp_path block and fille the mp file with data before writing") unless File.exist?(tmp_file_path)
73
+ raise Errors::MaxQqueueSize(batch_size: batch_size) if batch_size > config.aws_sqs_max_batch_size
74
+ batch = []
75
+ Dir.glob("#{File.dirname(tmp_file_path)}/**/**").each.with_index do |fp, i|
76
+ batch << { id: SecureRandom.uuid, message_body: output_json("file://#{fp}") }
77
+ if (i % batch_size).zero?
78
+ add_batch(messages: batch)
79
+ batch = []
80
+ end
81
+ end
82
+ file_uri
83
+ end
84
+
85
+ def client
86
+ @client ||= if config.aws_sqs_access_key_id && config.aws_sqs_secret_access_key
87
+ Aws::SQS::Client.new(
88
+ region: config.aws_sqs_region,
89
+ credentials: Aws::Credentials.new(
90
+ config.aws_sqs_access_key_id,
91
+ config.aws_sqs_secret_access_key
92
+ )
93
+ )
94
+ else
95
+ Aws::SQS::Client.new(region: config.aws_sqs_region)
96
+ end
97
+ end
98
+
99
+ def add(message:)
100
+ client.send_message({
101
+ queue_url: queue_url,
102
+ message_body: message
103
+ })
104
+ end
105
+
106
+ def add_batch(messages:)
107
+ client.send_message_batch({
108
+ queue_url: queue_url,
109
+ entries: messages
110
+ })
111
+ end
112
+
113
+ # def read_batch
114
+ # raise Errors::MaxQqueueSize(batch_size: batch_size) if batch_size > DerivativeRodeo.config.aws_sqs_max_batch_size
115
+
116
+ # response = client.receive_message({
117
+ # queue_url: queue_url,
118
+ # max_number_of_messages: batch_size
119
+ # })
120
+ # response.messages.map do |message|
121
+ # JSON.parse(message.body)
122
+ # end
123
+ # end
124
+
125
+ def queue_url
126
+ @queue_url ||= client.get_queue_url(queue_name: queue_name).queue_url
127
+ end
128
+
129
+ ##
130
+ # @api private
131
+ def queue_name
132
+ @queue_name ||= file_uri_parts[:queue_name]
133
+ rescue StandardError
134
+ raise Errors::QueueMissingError
135
+ end
136
+
137
+ ##
138
+ # @api private
139
+ def file_path
140
+ @file_path ||= [file_dir, file_name].join('/')
141
+ end
142
+
143
+ def file_dir
144
+ @file_dir ||= file_uri_parts[:file_dir]
145
+ end
146
+
147
+ ##
148
+ # @api private
149
+ def file_name
150
+ @file_name ||= file_uri_parts[:file_name]
151
+ end
152
+
153
+ def template
154
+ params&.[]('template')&.first
155
+ end
156
+
157
+ def scheme
158
+ file_uri_parts&.[](:scheme)
159
+ end
160
+
161
+ def params
162
+ @params ||= CGI.parse(file_uri_parts[:query]) if file_uri_parts[:query]
163
+ end
164
+
165
+ def output_json(uri)
166
+ key = DerivativeRodeo::Services::ConvertUriViaTemplateService.call(from_uri: uri, template: template, adapter: self)
167
+ { key => [template] }.to_json
168
+ end
169
+
170
+ def file_uri_parts
171
+ return @file_uri_parts if @file_uri_parts
172
+ uri = URI.parse(file_uri)
173
+ @file_uri_parts = uri&.component&.inject({}) do |hash, component|
174
+ hash[component] = uri.send(component)
175
+ hash
176
+ end
177
+ @file_uri_parts[:region] = @file_uri_parts[:host]&.split('.')&.[](0)
178
+ path_parts = @file_uri_parts[:path]&.split('/')
179
+ @file_uri_parts[:account_id] = path_parts&.[](1)
180
+ @file_uri_parts[:queue_name] = path_parts&.[](2)
181
+ @file_uri_parts[:file_name] = path_parts&.[](-1)
182
+ @file_uri_parts[:file_dir] = path_parts&.[](3..-2)&.join('/')
183
+ @file_uri_parts
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DerivativeRodeo
4
+ TechnicalMetadata = Struct.new(:color, :num_components, :bits_per_component, :width, :height, :content_type,
5
+ keyword_init: true) do
6
+ alias_method :number_of_components, :num_components
7
+
8
+ def to_hash
9
+ {
10
+ color: color,
11
+ num_components: num_components,
12
+ bits_per_component: bits_per_component,
13
+ width: width,
14
+ height: height,
15
+ content_type: content_type
16
+ }
17
+ end
18
+
19
+ def monochrome?
20
+ color.to_s.casecmp('monochrome').zero?
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DerivativeRodeo
4
+ VERSION = '0.2.0'
5
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support'
4
+ require 'active_support/core_ext'
5
+
6
+ require 'byebug' if ENV['DEBUG']
7
+
8
+ require 'derivative_rodeo/errors'
9
+
10
+ require 'derivative_rodeo/configuration'
11
+ require 'derivative_rodeo/technical_metadata'
12
+ require 'derivative_rodeo/version'
13
+ # Base Location loads the other adapters
14
+ require 'derivative_rodeo/storage_locations/base_location'
15
+ require 'derivative_rodeo/generators/base_generator'
16
+ require 'derivative_rodeo/services/base_service'
17
+
18
+ ##
19
+ # DerivativeRodeo is a gem that allows you to generate derivative files from source files
20
+ # It is storage location agnostic, relying on {StorageLocations}. Files can be stored locally or in the cloud.
21
+ # {Generators} are designed to be simple to create and to short circut logic if a
22
+ # pre processed version exists
23
+ module DerivativeRodeo
24
+ ##
25
+ # The {Configuration} that the various processes in your implementation will use.
26
+ #
27
+ # @api public
28
+ #
29
+ # @yieldparam [Derivative::Rodeo::Configuration]
30
+ # @return [Derivative::Rodeo::Configuration]
31
+ def self.config
32
+ @config ||= Configuration.new
33
+ yield(@config) if block_given?
34
+ @config
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,339 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: derivative-rodeo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Rob Kaufman
8
+ - Jeremy Friesen
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2023-05-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: '5'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: '5'
28
+ - !ruby/object:Gem::Dependency
29
+ name: aws-sdk-s3
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: aws-sdk-sqs
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: httparty
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: marcel
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: mime-types
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: mini_magick
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: nokogiri
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: bixby
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: byebug
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: rspec
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - "~>"
159
+ - !ruby/object:Gem::Version
160
+ version: '3.0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - "~>"
166
+ - !ruby/object:Gem::Version
167
+ version: '3.0'
168
+ - !ruby/object:Gem::Dependency
169
+ name: rake
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - "~>"
173
+ - !ruby/object:Gem::Version
174
+ version: '13.0'
175
+ type: :development
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - "~>"
180
+ - !ruby/object:Gem::Version
181
+ version: '13.0'
182
+ - !ruby/object:Gem::Dependency
183
+ name: simplecov
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ type: :development
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ - !ruby/object:Gem::Dependency
197
+ name: yard-activerecord
198
+ requirement: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ type: :development
204
+ prerelease: false
205
+ version_requirements: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - ">="
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
210
+ - !ruby/object:Gem::Dependency
211
+ name: rspec-its
212
+ requirement: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ type: :development
218
+ prerelease: false
219
+ version_requirements: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ - !ruby/object:Gem::Dependency
225
+ name: shoulda-matchers
226
+ requirement: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - ">="
229
+ - !ruby/object:Gem::Version
230
+ version: '0'
231
+ type: :development
232
+ prerelease: false
233
+ version_requirements: !ruby/object:Gem::Requirement
234
+ requirements:
235
+ - - ">="
236
+ - !ruby/object:Gem::Version
237
+ version: '0'
238
+ - !ruby/object:Gem::Dependency
239
+ name: solargraph
240
+ requirement: !ruby/object:Gem::Requirement
241
+ requirements:
242
+ - - ">="
243
+ - !ruby/object:Gem::Version
244
+ version: '0'
245
+ type: :development
246
+ prerelease: false
247
+ version_requirements: !ruby/object:Gem::Requirement
248
+ requirements:
249
+ - - ">="
250
+ - !ruby/object:Gem::Version
251
+ version: '0'
252
+ - !ruby/object:Gem::Dependency
253
+ name: yard
254
+ requirement: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - ">="
257
+ - !ruby/object:Gem::Version
258
+ version: '0'
259
+ type: :development
260
+ prerelease: false
261
+ version_requirements: !ruby/object:Gem::Requirement
262
+ requirements:
263
+ - - ">="
264
+ - !ruby/object:Gem::Version
265
+ version: '0'
266
+ description: An ETL Ecosystem for Derivative Processing.
267
+ email:
268
+ - rob@notch8.com
269
+ - jeremy.n.friesen@gmail.com
270
+ executables: []
271
+ extensions: []
272
+ extra_rdoc_files: []
273
+ files:
274
+ - Gemfile
275
+ - LICENSE
276
+ - README.md
277
+ - Rakefile
278
+ - derivative_rodeo.gemspec
279
+ - lib/derivative-rodeo.rb
280
+ - lib/derivative/rodeo.rb
281
+ - lib/derivative_rodeo.rb
282
+ - lib/derivative_rodeo/configuration.rb
283
+ - lib/derivative_rodeo/errors.rb
284
+ - lib/derivative_rodeo/generators/base_generator.rb
285
+ - lib/derivative_rodeo/generators/concerns/copy_file_concern.rb
286
+ - lib/derivative_rodeo/generators/copy_generator.rb
287
+ - lib/derivative_rodeo/generators/hocr_generator.rb
288
+ - lib/derivative_rodeo/generators/monochrome_generator.rb
289
+ - lib/derivative_rodeo/generators/pdf_split_generator.rb
290
+ - lib/derivative_rodeo/generators/thumbnail_generator.rb
291
+ - lib/derivative_rodeo/generators/word_coordinates_generator.rb
292
+ - lib/derivative_rodeo/services/base_service.rb
293
+ - lib/derivative_rodeo/services/convert_uri_via_template_service.rb
294
+ - lib/derivative_rodeo/services/extract_word_coordinates_from_hocr_sgml_service.rb
295
+ - lib/derivative_rodeo/services/image_identify_service.rb
296
+ - lib/derivative_rodeo/services/image_jp2_service.rb
297
+ - lib/derivative_rodeo/services/image_service.rb
298
+ - lib/derivative_rodeo/services/pdf_splitter/base.rb
299
+ - lib/derivative_rodeo/services/pdf_splitter/jpg_page.rb
300
+ - lib/derivative_rodeo/services/pdf_splitter/pages_summary.rb
301
+ - lib/derivative_rodeo/services/pdf_splitter/png_page.rb
302
+ - lib/derivative_rodeo/services/pdf_splitter/tiff_page.rb
303
+ - lib/derivative_rodeo/services/pdf_splitter_service.rb
304
+ - lib/derivative_rodeo/services/url_service.rb
305
+ - lib/derivative_rodeo/storage_locations/base_location.rb
306
+ - lib/derivative_rodeo/storage_locations/concerns/download_concern.rb
307
+ - lib/derivative_rodeo/storage_locations/file_location.rb
308
+ - lib/derivative_rodeo/storage_locations/http_location.rb
309
+ - lib/derivative_rodeo/storage_locations/https_location.rb
310
+ - lib/derivative_rodeo/storage_locations/s3_location.rb
311
+ - lib/derivative_rodeo/storage_locations/sqs_location.rb
312
+ - lib/derivative_rodeo/technical_metadata.rb
313
+ - lib/derivative_rodeo/version.rb
314
+ homepage: https://github.com/scientist-softserv/derivative_rodeo
315
+ licenses:
316
+ - APACHE-2.0
317
+ metadata:
318
+ homepage_uri: https://github.com/scientist-softserv/derivative_rodeo
319
+ source_code_uri: https://github.com/scientist-softserv/derivative_rodeo
320
+ post_install_message:
321
+ rdoc_options: []
322
+ require_paths:
323
+ - lib
324
+ required_ruby_version: !ruby/object:Gem::Requirement
325
+ requirements:
326
+ - - ">="
327
+ - !ruby/object:Gem::Version
328
+ version: 2.7.0
329
+ required_rubygems_version: !ruby/object:Gem::Requirement
330
+ requirements:
331
+ - - ">="
332
+ - !ruby/object:Gem::Version
333
+ version: '0'
334
+ requirements: []
335
+ rubygems_version: 3.3.7
336
+ signing_key:
337
+ specification_version: 4
338
+ summary: An ETL Ecosystem for Derivative Processing.
339
+ test_files: []