riiif 1.5.1 → 1.6.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.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/app/controllers/riiif/images_controller.rb +2 -2
- data/app/models/riiif/file.rb +2 -0
- data/app/models/riiif/image.rb +23 -10
- data/lib/riiif/abstract_file_system_resolver.rb +15 -4
- data/lib/riiif/version.rb +1 -1
- data/riiif.gemspec +1 -0
- data/spec/models/riiif/file_system_file_resolver_spec.rb +5 -3
- data/spec/models/riiif/image_spec.rb +201 -70
- data/spec/spec_helper.rb +10 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0bb1c35a0544e1cf55ab8af94b47ba48edcb6de
|
4
|
+
data.tar.gz: a591cfb9fe134db6b9ab8e68ca20b4d6008e859d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69e0af123b2b0d0bf47f7c8c156bb58f88fa48f8534ce3b15a3b30c24b214acbfc832d238fbf7bf7afbd71b3df6898d91d0756ecb462f45d7cc6e032c28e0a5a
|
7
|
+
data.tar.gz: 9fe0ca382348abcb23fc7f5b684a125b14116d96a98fdfc62e13b11644c7907f69e1035c90ef2735c1c9ef8a8bc79fc0f81c95a4349a2bc56d6935c0c14eb039
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Riiif
|
2
2
|
[](http://badge.fury.io/rb/riiif)
|
3
|
+
[](https://coveralls.io/github/curationexperts/riiif?branch=master)
|
3
4
|
|
4
5
|
A Ruby IIIF image server as a rails engine
|
5
6
|
|
@@ -77,9 +77,9 @@ module Riiif
|
|
77
77
|
##
|
78
78
|
# @return [ActiveSupport::HashWithIndifferentAccess]
|
79
79
|
def image_request_params
|
80
|
-
result = params.permit(:region, :size, :rotation, :quality, :format).to_h
|
80
|
+
result = params.permit(:region, :size, :rotation, :quality, :format, :model, :id).to_h
|
81
81
|
return result.with_indifferent_access if Rails.version < '5'
|
82
|
-
result
|
82
|
+
result.except(:model, :id)
|
83
83
|
end
|
84
84
|
|
85
85
|
def authorization_service
|
data/app/models/riiif/file.rb
CHANGED
@@ -18,6 +18,7 @@ module Riiif
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
+
deprecation_deprecate read: 'Riiif::File.read is deprecated and will be removed in version 2.0'
|
21
22
|
|
22
23
|
def self.create(ext = nil, _validate = true, &block)
|
23
24
|
tempfile = Tempfile.new(['mini_magick', ext.to_s.downcase])
|
@@ -28,6 +29,7 @@ module Riiif
|
|
28
29
|
ensure
|
29
30
|
tempfile.close if tempfile
|
30
31
|
end
|
32
|
+
deprecation_deprecate create: 'Riiif::File.create is deprecated and will be removed in version 2.0'
|
31
33
|
|
32
34
|
# @param [Transformation] transformation
|
33
35
|
def extract(transformation)
|
data/app/models/riiif/image.rb
CHANGED
@@ -17,9 +17,12 @@ require_dependency 'riiif/size/imagemagick/percent_decoder'
|
|
17
17
|
require_dependency 'riiif/size/imagemagick/width_decoder'
|
18
18
|
|
19
19
|
module Riiif
|
20
|
+
# rubocop:disable Metrics/ClassLength
|
20
21
|
class Image
|
22
|
+
extend Deprecation
|
23
|
+
|
21
24
|
class_attribute :file_resolver, :info_service, :authorization_service, :cache
|
22
|
-
self.file_resolver = FileSystemFileResolver.new
|
25
|
+
self.file_resolver = FileSystemFileResolver.new(base_path: File.join(Rails.root, 'tmp'))
|
23
26
|
self.authorization_service = NilAuthorizationService
|
24
27
|
self.cache = Rails.cache
|
25
28
|
|
@@ -40,27 +43,32 @@ module Riiif
|
|
40
43
|
|
41
44
|
# @param [String] id The identifier of the file to be looked up.
|
42
45
|
# @param [Riiif::File] file Optional: The Riiif::File to use instead of looking one up.
|
43
|
-
def initialize(id,
|
46
|
+
def initialize(id, passed_file = nil)
|
44
47
|
@id = id
|
45
|
-
@
|
48
|
+
@file = passed_file if passed_file.present?
|
46
49
|
end
|
47
50
|
|
48
|
-
def
|
49
|
-
@
|
51
|
+
def file
|
52
|
+
@file ||= file_resolver.find(id)
|
50
53
|
end
|
51
54
|
|
55
|
+
alias image file
|
56
|
+
deprecation_deprecate image: 'Use Image#file instead. This will be removed in riiif 2.0'
|
57
|
+
|
52
58
|
##
|
53
59
|
# @param [ActiveSupport::HashWithIndifferentAccess] args
|
54
60
|
def render(args)
|
55
|
-
|
56
|
-
|
57
|
-
|
61
|
+
cache_opts = args.select { |a| %w(region size quality rotation format).include? a.to_s }
|
62
|
+
key = Image.cache_key(id, cache_opts)
|
63
|
+
|
64
|
+
cache.fetch(key, compress: true, expires_in: Image.expires_in) do
|
65
|
+
file.extract(decode_options!(args))
|
58
66
|
end
|
59
67
|
end
|
60
68
|
|
61
69
|
def info
|
62
70
|
@info ||= begin
|
63
|
-
result = info_service.call(id,
|
71
|
+
result = info_service.call(id, file)
|
64
72
|
ImageInformation.new(result[:width], result[:height])
|
65
73
|
end
|
66
74
|
end
|
@@ -71,7 +79,11 @@ module Riiif
|
|
71
79
|
end
|
72
80
|
|
73
81
|
def cache_key(id, options)
|
74
|
-
str = options.to_h.merge(id: id)
|
82
|
+
str = options.to_h.merge(id: id)
|
83
|
+
.delete_if { |_, v| v.nil? }
|
84
|
+
.sort_by { |k, _v| k.to_s }
|
85
|
+
.to_s
|
86
|
+
|
75
87
|
# Use a MD5 digest to ensure the keys aren't too long, and a prefix
|
76
88
|
# to avoid collisions with other components in shared cache.
|
77
89
|
'riiif:' + Digest::MD5.hexdigest(str)
|
@@ -147,4 +159,5 @@ module Riiif
|
|
147
159
|
end
|
148
160
|
# rubocop:enable Metrics/PerceivedComplexity
|
149
161
|
end
|
162
|
+
# rubocop:enable Metrics/ClassLength
|
150
163
|
end
|
@@ -1,12 +1,23 @@
|
|
1
|
+
require 'deprecation'
|
1
2
|
module Riiif
|
2
3
|
class AbstractFileSystemResolver
|
3
|
-
|
4
|
+
extend Deprecation
|
5
|
+
attr_accessor :base_path
|
4
6
|
|
5
|
-
def initialize
|
6
|
-
@
|
7
|
-
@base_path = ::File.join(root, 'spec/samples')
|
7
|
+
def initialize(base_path: nil)
|
8
|
+
@base_path = base_path || default_base_path
|
8
9
|
end
|
9
10
|
|
11
|
+
def default_base_path
|
12
|
+
Deprecation.warn(self, 'Initializing a file resolver without setting the base path ' \
|
13
|
+
'is deprecated and will be removed in Riiif 2.0', caller(2))
|
14
|
+
@root ||= ::File.expand_path(::File.join(::File.dirname(__FILE__), '../..'))
|
15
|
+
::File.join(@root, 'spec/samples')
|
16
|
+
end
|
17
|
+
|
18
|
+
attr_reader :root
|
19
|
+
deprecation_deprecate :root
|
20
|
+
|
10
21
|
def find(id)
|
11
22
|
Riiif::File.new(path(id))
|
12
23
|
end
|
data/lib/riiif/version.rb
CHANGED
data/riiif.gemspec
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Riiif::FileSystemFileResolver do
|
4
|
-
let(:
|
4
|
+
let(:root) { File.expand_path(::File.join(::File.dirname(__FILE__), '../../..')) }
|
5
|
+
let(:base_path) { ::File.join(root, 'spec/samples') }
|
6
|
+
let(:resolver) { described_class.new(base_path: base_path) }
|
5
7
|
|
6
8
|
describe '#find' do
|
7
9
|
subject { resolver.find(id) }
|
@@ -16,13 +18,13 @@ describe Riiif::FileSystemFileResolver do
|
|
16
18
|
context 'when a jpeg2000 file is found' do
|
17
19
|
let(:id) { 'world' }
|
18
20
|
it 'returns the jpeg2000 file' do
|
19
|
-
expect(subject.path).to eq
|
21
|
+
expect(subject.path).to eq base_path + '/world.jp2'
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
26
|
describe '#input_types' do
|
25
|
-
subject {
|
27
|
+
subject { resolver.send(:input_types) }
|
26
28
|
|
27
29
|
it 'includes jp2 extension' do
|
28
30
|
expect(subject).to include 'jp2'
|
@@ -1,12 +1,21 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Riiif::Image do
|
4
|
-
|
4
|
+
subject(:image) { described_class.new('world') }
|
5
|
+
|
6
|
+
let(:root) { File.expand_path(::File.join(::File.dirname(__FILE__), '../../..')) }
|
7
|
+
let(:base_path) { ::File.join(root, 'spec/samples') }
|
8
|
+
let(:resolver) { Riiif::FileSystemFileResolver.new(base_path: base_path) }
|
5
9
|
let(:filename) { File.expand_path('spec/samples/world.jp2') }
|
6
|
-
|
10
|
+
|
11
|
+
before do
|
12
|
+
described_class.file_resolver = resolver
|
13
|
+
Riiif::Image.cache.clear
|
14
|
+
end
|
15
|
+
|
7
16
|
describe 'happy path' do
|
8
17
|
before do
|
9
|
-
expect(subject.
|
18
|
+
expect(subject.file).to receive(:execute)
|
10
19
|
.with("convert -quality 85 -sampling-factor 4:2:0 -strip #{filename} jpg:-")
|
11
20
|
.and_return('imagedata')
|
12
21
|
end
|
@@ -41,7 +50,7 @@ RSpec.describe Riiif::Image do
|
|
41
50
|
end
|
42
51
|
end
|
43
52
|
after do
|
44
|
-
described_class.file_resolver =
|
53
|
+
described_class.file_resolver = resolver
|
45
54
|
end
|
46
55
|
|
47
56
|
describe 'get info' do
|
@@ -62,104 +71,226 @@ RSpec.describe Riiif::Image do
|
|
62
71
|
end
|
63
72
|
end
|
64
73
|
|
65
|
-
describe '
|
74
|
+
describe '#render' do
|
66
75
|
describe 'region' do
|
67
|
-
|
68
|
-
|
69
|
-
|
76
|
+
subject(:render) { image.render(region: region, format: 'png') }
|
77
|
+
|
78
|
+
before do
|
79
|
+
allow(Riiif::CommandRunner).to receive(:execute)
|
80
|
+
.with("identify -format %hx%w #{filename}[0]").and_return('131x175')
|
70
81
|
end
|
71
|
-
|
72
|
-
|
73
|
-
|
82
|
+
|
83
|
+
context 'when specifing full size' do
|
84
|
+
let(:region) { 'full' }
|
85
|
+
|
86
|
+
it 'returns the original' do
|
87
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
88
|
+
.with("convert -strip #{filename} png:-")
|
89
|
+
render
|
90
|
+
end
|
74
91
|
end
|
75
92
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
93
|
+
context 'when specifing absolute geometry' do
|
94
|
+
let(:region) { '80,15,60,75' }
|
95
|
+
|
96
|
+
it 'runs the correct imagemagick command' do
|
97
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
98
|
+
.with("convert -crop 60x75+80+15 -strip #{filename} png:-")
|
99
|
+
render
|
100
|
+
end
|
81
101
|
end
|
82
102
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
103
|
+
context 'when specifing percent geometry' do
|
104
|
+
let(:region) { 'pct:10,10,80,70' }
|
105
|
+
|
106
|
+
it 'runs the correct imagemagick command' do
|
107
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
108
|
+
.with("convert -crop 80%x70+18+13 -strip #{filename} png:-")
|
109
|
+
render
|
110
|
+
end
|
88
111
|
end
|
89
|
-
|
90
|
-
|
112
|
+
|
113
|
+
context 'when specifing square geometry' do
|
114
|
+
let(:region) { 'square' }
|
115
|
+
|
116
|
+
it 'runs the correct imagemagick command' do
|
117
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
118
|
+
.with("convert -crop 131x131+22+0 -strip #{filename} png:-")
|
119
|
+
render
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
context 'when the geometry is invalid' do
|
124
|
+
let(:region) { '150x75' }
|
125
|
+
|
126
|
+
it 'raises an error' do
|
127
|
+
expect { render }.to raise_error Riiif::InvalidAttributeError
|
128
|
+
end
|
91
129
|
end
|
92
130
|
end
|
93
131
|
|
94
132
|
describe 'resize' do
|
95
|
-
|
96
|
-
|
97
|
-
|
133
|
+
subject(:render) { image.render(size: size, format: 'png') }
|
134
|
+
|
135
|
+
context 'when specifing full size' do
|
136
|
+
let(:size) { 'full' }
|
137
|
+
|
138
|
+
it 'returns the original' do
|
139
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
140
|
+
.with("convert -strip #{filename} png:-")
|
141
|
+
render
|
142
|
+
end
|
98
143
|
end
|
99
|
-
|
100
|
-
|
101
|
-
|
144
|
+
|
145
|
+
context 'when specifing percent size' do
|
146
|
+
let(:size) { 'pct:50' }
|
147
|
+
|
148
|
+
it 'runs the correct imagemagick command' do
|
149
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
150
|
+
.with("convert -resize 50% -strip #{filename} png:-")
|
151
|
+
render
|
152
|
+
end
|
102
153
|
end
|
103
|
-
|
104
|
-
|
105
|
-
|
154
|
+
|
155
|
+
context 'when specifing float percent size' do
|
156
|
+
let(:size) { 'pct:12.5' }
|
157
|
+
|
158
|
+
it 'runs the correct imagemagick command' do
|
159
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
160
|
+
.with("convert -resize 12.5% -strip #{filename} png:-")
|
161
|
+
render
|
162
|
+
end
|
106
163
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
164
|
+
|
165
|
+
context 'when specifing w, size' do
|
166
|
+
let(:size) { '50,' }
|
167
|
+
|
168
|
+
it 'runs the correct imagemagick command' do
|
169
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
170
|
+
.with("convert -resize 50 -strip #{filename} png:-")
|
171
|
+
render
|
172
|
+
end
|
110
173
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
174
|
+
|
175
|
+
context 'when specifing ,h size' do
|
176
|
+
let(:size) { ',50' }
|
177
|
+
|
178
|
+
it 'runs the correct imagemagick command' do
|
179
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
180
|
+
.with("convert -resize x50 -strip #{filename} png:-")
|
181
|
+
render
|
182
|
+
end
|
114
183
|
end
|
115
|
-
|
116
|
-
|
117
|
-
|
184
|
+
|
185
|
+
context 'when specifing w,h size' do
|
186
|
+
let(:size) { '150,75' }
|
187
|
+
|
188
|
+
it 'runs the correct imagemagick command' do
|
189
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
190
|
+
.with("convert -resize 150x75! -strip #{filename} png:-")
|
191
|
+
render
|
192
|
+
end
|
118
193
|
end
|
119
|
-
|
120
|
-
|
121
|
-
|
194
|
+
context 'when specifing bestfit (!w,h) size' do
|
195
|
+
let(:size) { '!150,75' }
|
196
|
+
|
197
|
+
it 'runs the correct imagemagick command' do
|
198
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
199
|
+
.with("convert -resize 150x75 -strip #{filename} png:-")
|
200
|
+
render
|
201
|
+
end
|
122
202
|
end
|
123
|
-
|
124
|
-
|
203
|
+
|
204
|
+
context 'when the geometry is invalid' do
|
205
|
+
let(:size) { '150x75' }
|
206
|
+
|
207
|
+
it 'raises an error' do
|
208
|
+
expect { render }.to raise_error Riiif::InvalidAttributeError
|
209
|
+
end
|
125
210
|
end
|
126
211
|
end
|
127
212
|
|
128
213
|
describe 'rotate' do
|
129
|
-
|
130
|
-
|
131
|
-
|
214
|
+
subject(:render) { image.render(rotation: rotation, format: 'png') }
|
215
|
+
|
216
|
+
context 'without rotating' do
|
217
|
+
let(:rotation) { '0' }
|
218
|
+
|
219
|
+
it 'returns the original' do
|
220
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
221
|
+
.with("convert -strip #{filename} png:-")
|
222
|
+
render
|
223
|
+
end
|
132
224
|
end
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
225
|
+
|
226
|
+
context 'with a float value' do
|
227
|
+
let(:rotation) { '22.5' }
|
228
|
+
|
229
|
+
it 'handles floats' do
|
230
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
231
|
+
.with("convert -virtual-pixel white +distort srt 22.5 -strip #{filename} png:-")
|
232
|
+
render
|
233
|
+
end
|
137
234
|
end
|
138
|
-
|
139
|
-
|
235
|
+
|
236
|
+
context 'with an invalid value' do
|
237
|
+
let(:rotation) { '150x' }
|
238
|
+
|
239
|
+
it 'raises an error for invalid angle' do
|
240
|
+
expect { render }.to raise_error Riiif::InvalidAttributeError
|
241
|
+
end
|
140
242
|
end
|
141
243
|
end
|
142
244
|
|
143
245
|
describe 'quality' do
|
144
|
-
|
145
|
-
|
146
|
-
|
246
|
+
subject(:render) { image.render(quality: quality, format: 'png') }
|
247
|
+
|
248
|
+
context 'when default is specified' do
|
249
|
+
let(:quality) { 'default' }
|
250
|
+
|
251
|
+
it 'returns the original when specifing default' do
|
252
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
253
|
+
.with("convert -strip #{filename} png:-")
|
254
|
+
render
|
255
|
+
end
|
147
256
|
end
|
148
|
-
|
149
|
-
|
150
|
-
|
257
|
+
|
258
|
+
context 'when color is specified' do
|
259
|
+
let(:quality) { 'color' }
|
260
|
+
|
261
|
+
it 'returns the original when specifing color' do
|
262
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
263
|
+
.with("convert -strip #{filename} png:-")
|
264
|
+
render
|
265
|
+
end
|
151
266
|
end
|
152
|
-
|
153
|
-
|
154
|
-
|
267
|
+
|
268
|
+
context 'when grey is specified' do
|
269
|
+
let(:quality) { 'grey' }
|
270
|
+
|
271
|
+
it 'converts to grayscale' do
|
272
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
273
|
+
.with("convert -colorspace Gray -strip #{filename} png:-")
|
274
|
+
render
|
275
|
+
end
|
155
276
|
end
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
277
|
+
|
278
|
+
context 'when bitonal is specified' do
|
279
|
+
let(:quality) { 'bitonal' }
|
280
|
+
|
281
|
+
it 'converts to bitonal' do
|
282
|
+
expect(Riiif::CommandRunner).to receive(:execute)
|
283
|
+
.with("convert -colorspace Gray -type Bilevel -strip #{filename} png:-")
|
284
|
+
render
|
285
|
+
end
|
160
286
|
end
|
161
|
-
|
162
|
-
|
287
|
+
|
288
|
+
context 'when an invalid quality is specified' do
|
289
|
+
let(:quality) { 'best' }
|
290
|
+
|
291
|
+
it 'raises an error' do
|
292
|
+
expect { render }.to raise_error Riiif::InvalidAttributeError
|
293
|
+
end
|
163
294
|
end
|
164
295
|
end
|
165
296
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
require 'coveralls'
|
2
|
+
require 'simplecov'
|
3
|
+
|
4
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
|
5
|
+
SimpleCov::Formatter::HTMLFormatter,
|
6
|
+
Coveralls::SimpleCov::Formatter
|
7
|
+
])
|
8
|
+
|
9
|
+
SimpleCov.start('rails')
|
10
|
+
|
1
11
|
require 'engine_cart'
|
2
12
|
ENV['RAILS_ENV'] ||= 'test'
|
3
13
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: riiif
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -142,6 +142,20 @@ dependencies:
|
|
142
142
|
- - "~>"
|
143
143
|
- !ruby/object:Gem::Version
|
144
144
|
version: '1.13'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: coveralls
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
145
159
|
description: A IIIF image server
|
146
160
|
email:
|
147
161
|
- justin@curationexperts.com
|
@@ -220,7 +234,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
220
234
|
version: '0'
|
221
235
|
requirements: []
|
222
236
|
rubyforge_project:
|
223
|
-
rubygems_version: 2.6.
|
237
|
+
rubygems_version: 2.6.13
|
224
238
|
signing_key:
|
225
239
|
specification_version: 4
|
226
240
|
summary: A rails engine that support IIIF requests
|