rubydora 1.7.0 → 1.7.1
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/VERSION +1 -1
- data/lib/rubydora/datastream.rb +9 -5
- data/lib/rubydora/digital_object.rb +7 -1
- data/lib/rubydora/fc3_service.rb +1 -1
- data/lib/rubydora/profile_parser.rb +14 -4
- data/lib/rubydora/rest_api_client.rb +10 -8
- data/rubydora.gemspec +1 -1
- data/spec/lib/datastream_spec.rb +27 -6
- data/spec/lib/rest_api_client_spec.rb +48 -5
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 367d66a9cebd58fd4efd62fb00f6e644f9c998a6
|
4
|
+
data.tar.gz: 9303285358a919f262b9e99329c5788ec7136025
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a47dacdf70d4fd80ae03cfb0deac47685fa6fad96e49d018d5ce5da1b8a4694767d11e1e020101c7ffd7602dc0b4618035786ba2c7c9fe7de40ca5bca9cc5f05
|
7
|
+
data.tar.gz: bbfa8466a29af4ac8801e53383a0165839f4162d7e0fe7d862ae885931db73608aadc16c1a99fef6b739cd560a0a18e3647c95299b4659eedd7d1440e5baded0
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.7.
|
1
|
+
1.7.1
|
data/lib/rubydora/datastream.rb
CHANGED
@@ -204,14 +204,18 @@ module Rubydora
|
|
204
204
|
# persisted objects are required to have content
|
205
205
|
return true unless new?
|
206
206
|
|
207
|
-
# type E and R
|
208
|
-
return
|
207
|
+
# type E and R have content if dsLocation is set.
|
208
|
+
return dsLocation.present? if ['E','R'].include? controlGroup
|
209
209
|
|
210
|
-
#
|
210
|
+
# type M has content if dsLocation is not empty
|
211
|
+
return true if controlGroup == 'M' and dsLocation.present?
|
211
212
|
|
212
|
-
#
|
213
|
+
# if we've set content, then we have content
|
214
|
+
behaves_like_io?(@content) || content.present?
|
215
|
+
end
|
213
216
|
|
214
|
-
|
217
|
+
def empty?
|
218
|
+
!has_content?
|
215
219
|
end
|
216
220
|
|
217
221
|
# Returns a streaming response of the datastream. This is ideal for large datasteams because
|
@@ -154,14 +154,20 @@ module Rubydora
|
|
154
154
|
h = Hash.new { |h,k| h[k] = datastream_object_for(k) }
|
155
155
|
|
156
156
|
begin
|
157
|
-
options = { :pid => pid }
|
157
|
+
options = { :pid => pid, :profiles => 'true' }
|
158
158
|
options[:asOfDateTime] = asOfDateTime if asOfDateTime
|
159
159
|
datastreams_xml = repository.datastreams(options)
|
160
|
+
# pre-3.6, the profiles parm will be ignored
|
160
161
|
datastreams_xml.gsub! '<objectDatastreams', '<objectDatastreams xmlns="http://www.fedora.info/definitions/1/0/access/"' unless datastreams_xml =~ /xmlns=/
|
161
162
|
doc = Nokogiri::XML(datastreams_xml)
|
162
163
|
doc.xpath('//access:datastream', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).each do |ds|
|
163
164
|
h[ds['dsid']] = datastream_object_for ds['dsid']
|
164
165
|
end
|
166
|
+
# post-3.6, full ds profiles will be returned
|
167
|
+
doc.xpath('//access:datastreamProfile', {'access' => "http://www.fedora.info/definitions/1/0/access/"}).each do |ds|
|
168
|
+
# n.b. that the dsID attribute has a different name in the profile response
|
169
|
+
h[ds['dsID']] = datastream_object_for(ds['dsID'], {:profile => ProfileParser.hash_datastream_profile_node(ds)})
|
170
|
+
end
|
165
171
|
rescue RestClient::ResourceNotFound
|
166
172
|
end
|
167
173
|
|
data/lib/rubydora/fc3_service.rb
CHANGED
@@ -1,13 +1,23 @@
|
|
1
1
|
module Rubydora
|
2
2
|
module ProfileParser
|
3
3
|
def self.parse_datastream_profile profile_xml
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# since the profile may be in the management or the access namespace, use the CSS selector
|
5
|
+
ndoc = Nokogiri::XML(profile_xml)
|
6
|
+
doc = (ndoc.name == 'datastreamProfile') ? ndoc : ndoc.css('datastreamProfile').first
|
7
|
+
if doc.nil?
|
8
|
+
# the datastream is new
|
9
|
+
{}.with_indifferent_access
|
10
|
+
else
|
11
|
+
hash_datastream_profile_node(doc)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.hash_datastream_profile_node doc
|
16
|
+
h = doc.xpath('./*').inject({}) do |sum, node|
|
7
17
|
sum[node.name] ||= []
|
8
18
|
sum[node.name] << node.text
|
9
19
|
sum
|
10
|
-
end.reject { |key, values| values.empty? }
|
20
|
+
end.reject { |key, values| values.nil? or values.empty? }
|
11
21
|
h.select { |key, values| values.length == 1 }.each do |key, values|
|
12
22
|
h[key] = values.reject { |x| x.empty? }.first
|
13
23
|
end
|
@@ -12,7 +12,7 @@ module Rubydora
|
|
12
12
|
include ActiveSupport::Benchmarkable
|
13
13
|
extend Deprecation
|
14
14
|
|
15
|
-
|
15
|
+
DEFAULT_CONTENT_TYPE = "application/octet-stream"
|
16
16
|
|
17
17
|
VALID_CLIENT_OPTIONS = [:user, :password, :timeout, :open_timeout, :ssl_client_cert, :ssl_client_key]
|
18
18
|
|
@@ -336,9 +336,7 @@ module Rubydora
|
|
336
336
|
pid = query_options.delete(:pid)
|
337
337
|
dsid = query_options.delete(:dsid)
|
338
338
|
file = query_options.delete(:content)
|
339
|
-
|
340
|
-
# When we discontinue ruby 1.8.7 support we can remove the `|| ''` part.
|
341
|
-
content_type = query_options.delete(:content_type) || query_options[:mimeType] || (MIME::Types.type_for(file.path || '').first if file.respond_to? :path) || 'application/octet-stream'
|
339
|
+
content_type = query_options.delete(:content_type) || query_options[:mimeType] || file_content_type(file)
|
342
340
|
run_hook :before_add_datastream, :pid => pid, :dsid => dsid, :file => file, :options => options
|
343
341
|
str = file.respond_to?(:read) ? file.read : file
|
344
342
|
file.rewind if file.respond_to?(:rewind)
|
@@ -357,10 +355,7 @@ module Rubydora
|
|
357
355
|
pid = query_options.delete(:pid)
|
358
356
|
dsid = query_options.delete(:dsid)
|
359
357
|
file = query_options.delete(:content)
|
360
|
-
|
361
|
-
# When we discontinue ruby 1.8.7 support we can remove the `|| ''` part.
|
362
|
-
content_type = query_options.delete(:content_type) || query_options[:mimeType] || (MIME::Types.type_for(file.path || '').first if file.respond_to? :path) || 'application/octet-stream'
|
363
|
-
|
358
|
+
content_type = query_options.delete(:content_type) || query_options[:mimeType] || file_content_type(file)
|
364
359
|
rest_client_options = {}
|
365
360
|
if file
|
366
361
|
rest_client_options[:multipart] = true
|
@@ -465,5 +460,12 @@ module Rubydora
|
|
465
460
|
client.class.new(url, options)
|
466
461
|
end
|
467
462
|
end
|
463
|
+
|
464
|
+
private
|
465
|
+
|
466
|
+
def file_content_type(file)
|
467
|
+
(file.content_type if file.respond_to? :content_type) || (MIME::Types.type_for(file.path).first if file.respond_to? :path) || DEFAULT_CONTENT_TYPE
|
468
|
+
end
|
469
|
+
|
468
470
|
end
|
469
471
|
end
|
data/rubydora.gemspec
CHANGED
@@ -30,6 +30,6 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.add_development_dependency("bundler", ">= 1.0.14")
|
31
31
|
s.add_development_dependency("rspec")
|
32
32
|
s.add_development_dependency("yard")
|
33
|
-
s.add_development_dependency("jettywrapper")
|
33
|
+
s.add_development_dependency("jettywrapper", ">= 1.4.0")
|
34
34
|
s.add_development_dependency("webmock")
|
35
35
|
end
|
data/spec/lib/datastream_spec.rb
CHANGED
@@ -8,6 +8,18 @@ describe Rubydora::Datastream do
|
|
8
8
|
@mock_object.stub(:repository => @mock_repository, :pid => 'pid', :new_record? => false)
|
9
9
|
end
|
10
10
|
|
11
|
+
describe "empty?" do
|
12
|
+
subject { Rubydora::Datastream.new @mock_object, 'dsid' }
|
13
|
+
context "has content" do
|
14
|
+
before { subject.stub(:has_content? => true) }
|
15
|
+
it { should_not be_empty }
|
16
|
+
end
|
17
|
+
context "does not have content" do
|
18
|
+
before { subject.stub(:has_content? => false) }
|
19
|
+
it { should be_empty }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
11
23
|
describe "stream" do
|
12
24
|
subject { Rubydora::Datastream.new @mock_object, 'dsid' }
|
13
25
|
before do
|
@@ -21,7 +33,7 @@ describe Rubydora::Datastream do
|
|
21
33
|
XML
|
22
34
|
subject.profile = Rubydora::ProfileParser.parse_datastream_profile(prof)
|
23
35
|
end
|
24
|
-
it "should send the
|
36
|
+
it "should send the whole thing" do
|
25
37
|
e = subject.stream()
|
26
38
|
result = ''
|
27
39
|
e.each do |blk|
|
@@ -346,11 +358,20 @@ describe Rubydora::Datastream do
|
|
346
358
|
subject.should have_content
|
347
359
|
end
|
348
360
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
361
|
+
context "it has a dsLocation" do
|
362
|
+
before { subject.dsLocation = "urn:abc" }
|
363
|
+
context "controlGroup 'E'" do
|
364
|
+
before { subject.controlGroup = 'E' }
|
365
|
+
it { should have_content }
|
366
|
+
end
|
367
|
+
context "controlGroup 'R'" do
|
368
|
+
before { subject.controlGroup = 'R' }
|
369
|
+
it { should have_content }
|
370
|
+
end
|
371
|
+
context "controlGroup 'M'" do
|
372
|
+
before { subject.controlGroup = 'M' }
|
373
|
+
it { should have_content }
|
374
|
+
end
|
354
375
|
end
|
355
376
|
|
356
377
|
it "should not have content otherwise" do
|
@@ -215,22 +215,43 @@ describe Rubydora::RestApiClient do
|
|
215
215
|
|
216
216
|
describe "add_datastream" do
|
217
217
|
it "should post to the correct url" do
|
218
|
-
|
218
|
+
RestClient::Request.should_receive(:execute).with(hash_including(:url => base_url + "/" + datastream_url('mypid', 'aaa')))
|
219
219
|
@mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa'
|
220
220
|
end
|
221
|
-
|
222
221
|
describe "when a file is passed" do
|
222
|
+
let!(:file) { StringIO.new('test', 'r') } # StringIO is a good stand it for a real File (it has read, rewind and close)
|
223
223
|
it "should rewind the file" do
|
224
224
|
RestClient::Request.any_instance.should_receive(:transmit) #stub transmit so that Request.execute can close the file we pass
|
225
|
-
file = StringIO.new('test', 'r') # StringIO is a good stand it for a real File (it has read, rewind and close)
|
226
225
|
@mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
|
227
226
|
lambda {file.read}.should_not raise_error
|
228
227
|
end
|
228
|
+
describe "and mimeType is not provided" do
|
229
|
+
describe "and file responds to :content_type" do
|
230
|
+
it "should set the mimeType to file.content_type" do
|
231
|
+
file.stub(:content_type).and_return('image/tiff')
|
232
|
+
RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"image/tiff"}))
|
233
|
+
@mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
|
234
|
+
end
|
235
|
+
end
|
236
|
+
describe "and file responds to :path" do
|
237
|
+
it "should should try to discern the mime-type from file.path" do
|
238
|
+
file.stub(:path).and_return('foo.tiff')
|
239
|
+
RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"image/tiff"}))
|
240
|
+
@mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
|
241
|
+
end
|
242
|
+
end
|
243
|
+
describe "otherwise" do
|
244
|
+
it "should set the mimeType to 'application/octet-stream'" do
|
245
|
+
RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"application/octet-stream"}))
|
246
|
+
@mock_repository.add_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
229
250
|
end
|
230
251
|
end
|
231
252
|
|
232
253
|
describe "modify datastream" do
|
233
|
-
it "should not set mime-type when it's not provided" do
|
254
|
+
it "should not set mime-type when it's not provided (and a file is not passed)" do
|
234
255
|
RestClient::Request.should_receive(:execute).with(:url => base_url + "/" + datastream_url('mypid', 'aaa'),:open_timeout=>nil, :payload=>nil, :user=>@fedora_user, :password=>@fedora_password, :method=>:put, :headers=>{})
|
235
256
|
@mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa'
|
236
257
|
end
|
@@ -239,12 +260,34 @@ describe Rubydora::RestApiClient do
|
|
239
260
|
@mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :mimeType=>'application/json'
|
240
261
|
end
|
241
262
|
describe "when a file is passed" do
|
263
|
+
let!(:file) { StringIO.new('test', 'r') } # StringIO is a good stand it for a real File (it has read, rewind and close)
|
242
264
|
it "should rewind the file" do
|
243
265
|
RestClient::Request.any_instance.should_receive(:transmit) #stub transmit so that Request.execute can close the file we pass
|
244
|
-
file = StringIO.new('test', 'r') # StringIO is a good stand it for a real File (it has read, rewind and close)
|
245
266
|
@mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
|
246
267
|
lambda {file.read}.should_not raise_error
|
247
268
|
end
|
269
|
+
describe "and mimeType is not provided" do
|
270
|
+
describe "and file responds to :content_type" do
|
271
|
+
it "should set the mimeType to file.content_type" do
|
272
|
+
file.stub(:content_type).and_return('image/tiff')
|
273
|
+
RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"image/tiff"}))
|
274
|
+
@mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
|
275
|
+
end
|
276
|
+
end
|
277
|
+
describe "and file responds to :path" do
|
278
|
+
it "should should try to discern the mime-type from file.path" do
|
279
|
+
file.stub(:path).and_return('foo.tiff')
|
280
|
+
RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"image/tiff"}))
|
281
|
+
@mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
|
282
|
+
end
|
283
|
+
end
|
284
|
+
describe "otherwise" do
|
285
|
+
it "should set the mimeType to 'application/octet-stream'" do
|
286
|
+
RestClient::Request.should_receive(:execute).with(hash_including(:headers=>{:multipart=>true, :content_type=>"application/octet-stream"}))
|
287
|
+
@mock_repository.modify_datastream :pid => 'mypid', :dsid => 'aaa', :content=>file
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
248
291
|
end
|
249
292
|
end
|
250
293
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubydora
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.7.
|
4
|
+
version: 1.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Beer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fastercsv
|
@@ -198,14 +198,14 @@ dependencies:
|
|
198
198
|
requirements:
|
199
199
|
- - '>='
|
200
200
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
201
|
+
version: 1.4.0
|
202
202
|
type: :development
|
203
203
|
prerelease: false
|
204
204
|
version_requirements: !ruby/object:Gem::Requirement
|
205
205
|
requirements:
|
206
206
|
- - '>='
|
207
207
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
208
|
+
version: 1.4.0
|
209
209
|
- !ruby/object:Gem::Dependency
|
210
210
|
name: webmock
|
211
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -287,7 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
287
287
|
version: '0'
|
288
288
|
requirements: []
|
289
289
|
rubyforge_project:
|
290
|
-
rubygems_version: 2.
|
290
|
+
rubygems_version: 2.0.6
|
291
291
|
signing_key:
|
292
292
|
specification_version: 4
|
293
293
|
summary: Fedora Commons REST API ruby library
|