rubydora 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -4,6 +4,8 @@ gem "fastercsv"
4
4
  gem "rest-client"
5
5
  gem "nokogiri"
6
6
  gem "mime-types"
7
+ gem "activesupport", ">= 3.0"
8
+ gem "activemodel", ">= 3.0"
7
9
 
8
10
  group :soap do
9
11
  gem "soap4r"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.6
1
+ 0.0.7
@@ -3,23 +3,31 @@ module Rubydora
3
3
  # and provides helper methods for creating and manipulating
4
4
  # them.
5
5
  class Datastream
6
- include Rubydora::Callbacks
7
- register_callback :after_initialize
6
+ extend ActiveModel::Callbacks
7
+ define_model_callbacks :initialize, :only => :after
8
+
9
+ include ActiveModel::Dirty
10
+
8
11
  include Rubydora::ExtensionParameters
9
12
 
10
13
  attr_reader :digital_object, :dsid
11
14
 
12
15
  # mapping datastream attributes (and api parameters) to datastream profile names
13
16
  DS_ATTRIBUTES = {:controlGroup => :dsControlGroup, :dsLocation => :dsLocation, :altIDs => nil, :dsLabel => :dsLabel, :versionable => :dsVersionable, :dsState => :dsState, :formatURI => :dsFormatURI, :checksumType => :dsChecksumType, :checksum => :dsChecksum, :mimeType => :dsMIME, :logMessage => nil, :ignoreContent => nil, :lastModifiedDate => nil, :file => nil}
17
+
18
+ define_attribute_methods DS_ATTRIBUTES.keys
14
19
 
15
20
  # accessors for datastream attributes
16
21
  DS_ATTRIBUTES.each do |attribute, profile_name|
17
22
  class_eval %Q{
18
- def #{attribute.to_s}
19
- @#{attribute.to_s} || profile['#{profile_name.to_s}']
20
- end
23
+ def #{attribute.to_s}
24
+ (@#{attribute} || profile['#{profile_name.to_s}']).to_s
25
+ end
21
26
 
22
- attr_writer :#{attribute.to_s}
27
+ def #{attribute.to_s}= val
28
+ #{attribute.to_s}_will_change! unless val == @#{attribute.to_s}
29
+ @#{attribute.to_s} = val
30
+ end
23
31
  }
24
32
  end
25
33
 
@@ -31,15 +39,15 @@ module Rubydora
31
39
  #
32
40
  # @param [Rubydora::DigitalObject]
33
41
  # @param [String] Datastream ID
34
- # @param [Hash] default attribute values (used esp. for creating new datastreams
42
+ # @param [Hash] default attribute values (used esp. for creating new datastreams)
35
43
  def initialize digital_object, dsid, options = {}
44
+ _run_initialize_callbacks do
36
45
  @digital_object = digital_object
37
46
  @dsid = dsid
38
47
  options.each do |key, value|
39
48
  self.send(:"#{key}=", value)
40
49
  end
41
-
42
- call_after_initialize
50
+ end
43
51
  end
44
52
 
45
53
  # Helper method to get digital object pid
@@ -98,12 +106,6 @@ module Rubydora
98
106
  end
99
107
  end
100
108
 
101
- # Has this datastream been modified, but not yet saved?
102
- # @return [Boolean]
103
- def dirty?
104
- DS_ATTRIBUTES.any? { |attribute, profile_name| instance_variable_defined?("@#{attribute.to_s}") } || new?
105
- end
106
-
107
109
  # Add datastream to Fedora
108
110
  # @return [Rubydora::Datastream]
109
111
  def create
@@ -152,9 +154,7 @@ module Rubydora
152
154
  # @return [Hash]
153
155
  def reset_profile_attributes
154
156
  @profile = nil
155
- DS_ATTRIBUTES.each do |attribute, profile_name|
156
- instance_variable_set("@#{attribute.to_s}", nil) if instance_variable_defined?("@#{attribute.to_s}")
157
- end
157
+ @changed_attributes = {}
158
158
  end
159
159
 
160
160
  # repository reference from the digital object
@@ -8,8 +8,9 @@ module Rubydora
8
8
  # provide additional functionality to this base
9
9
  # implementation.
10
10
  class DigitalObject
11
- include Rubydora::Callbacks
12
- register_callback :after_initialize
11
+ extend ActiveModel::Callbacks
12
+ define_model_callbacks :initialize, :only => :after
13
+ include ActiveModel::Dirty
13
14
  include Rubydora::ExtensionParameters
14
15
  include Rubydora::ModelsMixin
15
16
  include Rubydora::RelationshipsMixin
@@ -19,15 +20,19 @@ module Rubydora
19
20
 
20
21
  # mapping object parameters to profile elements
21
22
  OBJ_ATTRIBUTES = {:state => :objState, :ownerId => :objOwnerId, :label => :objLabel, :logMessage => nil, :lastModifiedDate => :objLastModDate }
23
+
24
+ define_attribute_methods OBJ_ATTRIBUTES.keys
22
25
 
23
26
  OBJ_ATTRIBUTES.each do |attribute, profile_name|
24
27
  class_eval <<-RUBY
25
28
  def #{attribute.to_s}
26
29
  @#{attribute.to_s} || profile['#{profile_name.to_s}']
27
30
  end
28
-
29
- attr_writer :#{attribute.to_s}
30
31
 
32
+ def #{attribute.to_s}= val
33
+ #{attribute.to_s}_will_change! unless val == @#{attribute.to_s}
34
+ @#{attribute.to_s} = val
35
+ end
31
36
  RUBY
32
37
  end
33
38
 
@@ -59,14 +64,14 @@ module Rubydora
59
64
  # @param [Rubydora::Repository] repository context
60
65
  # @param [Hash] options default attribute values (used esp. for creating new datastreams
61
66
  def initialize pid, repository = nil, options = {}
62
- self.pid = pid
63
- @repository = repository
67
+ _run_initialize_callbacks do
68
+ self.pid = pid
69
+ @repository = repository
64
70
 
65
- options.each do |key, value|
66
- self.send(:"#{key}=", value)
71
+ options.each do |key, value|
72
+ self.send(:"#{key}=", value)
73
+ end
67
74
  end
68
-
69
- call_after_initialize
70
75
  end
71
76
 
72
77
  ##
@@ -148,7 +153,7 @@ module Rubydora
148
153
  repository.modify_object p.merge(:pid => pid) unless p.empty?
149
154
  end
150
155
 
151
- self.datastreams.select { |dsid, ds| ds.dirty? }.reject {|dsid, ds| ds.new? }.each { |dsid, ds| ds.save }
156
+ self.datastreams.select { |dsid, ds| ds.changed? }.reject {|dsid, ds| ds.new? }.each { |dsid, ds| ds.save }
152
157
  reset
153
158
  self
154
159
  end
@@ -196,9 +201,7 @@ module Rubydora
196
201
  # @return [Hash]
197
202
  def reset_profile_attributes
198
203
  @profile = nil
199
- OBJ_ATTRIBUTES.each do |attribute, profile_name|
200
- instance_variable_set("@#{attribute.to_s}", nil) if instance_variable_defined?("@#{attribute.to_s}")
201
- end
204
+ @changed_attributes = {}
202
205
  end
203
206
 
204
207
  # reset the datastreams cache
@@ -25,7 +25,7 @@ module Rubydora::Ext
25
25
  begin
26
26
  mod = self.string_to_constant [ns, model].compact.map { |x| x.to_s }.join("/")
27
27
  document.send(:extend, mod)
28
- rescue NameError
28
+ rescue NameError, LoadError
29
29
  end
30
30
  end
31
31
  end
@@ -9,23 +9,23 @@ module Rubydora
9
9
  # Map Rubydora accessors to Fedora RELS-EXT predicates
10
10
  RELS_EXT = {"annotations"=>"info:fedora/fedora-system:def/relations-external#hasAnnotation",
11
11
  "has_metadata"=>"info:fedora/fedora-system:def/relations-external#hasMetadata",
12
- "description_of"=>"info:fedora/fedora-system:def/relations-external#isDescription_of",
13
- "part_of"=>"info:fedora/fedora-system:def/relations-external#isPart_of",
12
+ "description_of"=>"info:fedora/fedora-system:def/relations-external#isDescriptionOf",
13
+ "part_of"=>"info:fedora/fedora-system:def/relations-external#isPartOf",
14
14
  "descriptions"=>"info:fedora/fedora-system:def/relations-external#hasDescription",
15
- "dependent_of"=>"info:fedora/fedora-system:def/relations-external#isDependent_of",
15
+ "dependent_of"=>"info:fedora/fedora-system:def/relations-external#isDependentOf",
16
16
  "constituents"=>"info:fedora/fedora-system:def/relations-external#hasConstituent",
17
17
  "parts"=>"info:fedora/fedora-system:def/relations-external#hasPart",
18
18
  "memberOfCollection"=>"info:fedora/fedora-system:def/relations-external#isMemberOfCollection",
19
- "member_of"=>"info:fedora/fedora-system:def/relations-external#isMember_of",
19
+ "member_of"=>"info:fedora/fedora-system:def/relations-external#isMemberOf",
20
20
  "equivalents"=>"info:fedora/fedora-system:def/relations-external#hasEquivalent",
21
21
  "derivations"=>"info:fedora/fedora-system:def/relations-external#hasDerivation",
22
- "derivation_of"=>"info:fedora/fedora-system:def/relations-external#isDerivation_of",
22
+ "derivation_of"=>"info:fedora/fedora-system:def/relations-external#isDerivationOf",
23
23
  "subsets"=>"info:fedora/fedora-system:def/relations-external#hasSubset",
24
- "annotation_of"=>"info:fedora/fedora-system:def/relations-external#isAnnotation_of",
24
+ "annotation_of"=>"info:fedora/fedora-system:def/relations-external#isAnnotationOf",
25
25
  "metadata_for"=>"info:fedora/fedora-system:def/relations-external#isMetadataFor",
26
26
  "dependents"=>"info:fedora/fedora-system:def/relations-external#hasDependent",
27
- "subset_of"=>"info:fedora/fedora-system:def/relations-external#isSubset_of",
28
- "constituent_of"=>"info:fedora/fedora-system:def/relations-external#isConstituent_of",
27
+ "subset_of"=>"info:fedora/fedora-system:def/relations-external#isSubsetOf",
28
+ "constituent_of"=>"info:fedora/fedora-system:def/relations-external#isConstituentOf",
29
29
  "collection_members"=>"info:fedora/fedora-system:def/relations-external#hasCollectionMember",
30
30
  "members"=>"info:fedora/fedora-system:def/relations-external#hasMember"}
31
31
 
data/lib/rubydora.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # Fedora Commons REST API module
2
+ require 'active_model'
3
+
2
4
  module Rubydora
3
5
  autoload :Datastream, "rubydora/datastream"
4
6
  autoload :Repository, "rubydora/repository"
data/rubydora.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rubydora}
8
- s.version = "0.0.6"
8
+ s.version = "0.0.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Chris Beer"]
12
- s.date = %q{2011-04-22}
12
+ s.date = %q{2011-05-12}
13
13
  s.description = %q{Fedora Commons REST API ruby library : REQUIRES FCREPO 3.4+}
14
14
  s.email = %q{chris@cbeer.info}
15
15
  s.extra_rdoc_files = [
@@ -54,7 +54,7 @@ Gem::Specification.new do |s|
54
54
  s.homepage = %q{http://github.com/cbeer/rubydora}
55
55
  s.licenses = ["MIT"]
56
56
  s.require_paths = ["lib"]
57
- s.rubygems_version = %q{1.5.3}
57
+ s.rubygems_version = %q{1.3.7}
58
58
  s.summary = %q{Fedora Commons REST API ruby library}
59
59
  s.test_files = [
60
60
  "spec/datastream_spec.rb",
@@ -71,6 +71,7 @@ Gem::Specification.new do |s|
71
71
  ]
72
72
 
73
73
  if s.respond_to? :specification_version then
74
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
74
75
  s.specification_version = 3
75
76
 
76
77
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
@@ -78,6 +79,8 @@ Gem::Specification.new do |s|
78
79
  s.add_runtime_dependency(%q<rest-client>, [">= 0"])
79
80
  s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
80
81
  s.add_runtime_dependency(%q<mime-types>, [">= 0"])
82
+ s.add_runtime_dependency(%q<activesupport>, [">= 3.0"])
83
+ s.add_runtime_dependency(%q<activemodel>, [">= 3.0"])
81
84
  s.add_development_dependency(%q<shoulda>, [">= 0"])
82
85
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
83
86
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
@@ -89,6 +92,8 @@ Gem::Specification.new do |s|
89
92
  s.add_dependency(%q<rest-client>, [">= 0"])
90
93
  s.add_dependency(%q<nokogiri>, [">= 0"])
91
94
  s.add_dependency(%q<mime-types>, [">= 0"])
95
+ s.add_dependency(%q<activesupport>, [">= 3.0"])
96
+ s.add_dependency(%q<activemodel>, [">= 3.0"])
92
97
  s.add_dependency(%q<shoulda>, [">= 0"])
93
98
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
94
99
  s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
@@ -101,6 +106,8 @@ Gem::Specification.new do |s|
101
106
  s.add_dependency(%q<rest-client>, [">= 0"])
102
107
  s.add_dependency(%q<nokogiri>, [">= 0"])
103
108
  s.add_dependency(%q<mime-types>, [">= 0"])
109
+ s.add_dependency(%q<activesupport>, [">= 3.0"])
110
+ s.add_dependency(%q<activemodel>, [">= 3.0"])
104
111
  s.add_dependency(%q<shoulda>, [">= 0"])
105
112
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
106
113
  s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
@@ -16,8 +16,7 @@ describe Rubydora::Datastream do
16
16
  end
17
17
 
18
18
  it "should be dirty" do
19
- @mock_repository.should_receive(:datastream).and_raise("")
20
- @datastream.dirty?.should == true
19
+ @datastream.changed?.should == false
21
20
  end
22
21
 
23
22
  it "should call the appropriate api on save" do
@@ -51,7 +50,7 @@ describe Rubydora::Datastream do
51
50
 
52
51
  it "should not be new" do
53
52
  @datastream.new?.should == false
54
- @datastream.dirty?.should == false
53
+ @datastream.changed?.should == false
55
54
  end
56
55
 
57
56
  it "should provide attribute defaults from dsProfile" do
@@ -117,16 +117,16 @@ describe Rubydora::DigitalObject do
117
117
  @object = Rubydora::DigitalObject.new 'pid', @mock_repository
118
118
  end
119
119
 
120
- it "should save all dirty datastreams" do
120
+ it "should save all changed datastreams" do
121
121
  @ds1 = mock()
122
- @ds1.should_receive(:dirty?).and_return(false)
122
+ @ds1.should_receive(:changed?).and_return(false)
123
123
  @ds1.should_not_receive(:save)
124
124
  @ds2 = mock()
125
- @ds2.should_receive(:dirty?).and_return(true)
125
+ @ds2.should_receive(:changed?).and_return(true)
126
126
  @ds2.should_receive(:new?).and_return(true)
127
127
  @ds2.should_not_receive(:save)
128
128
  @ds3 = mock()
129
- @ds3.should_receive(:dirty?).and_return(true)
129
+ @ds3.should_receive(:changed?).and_return(true)
130
130
  @ds3.should_receive(:new?).and_return(false)
131
131
  @ds3.should_receive(:save)
132
132
 
@@ -135,7 +135,7 @@ describe Rubydora::DigitalObject do
135
135
  @object.save
136
136
  end
137
137
 
138
- it "should save all dirty attributes" do
138
+ it "should save all changed attributes" do
139
139
  @object.label = "asdf"
140
140
  @object.should_receive(:datastreams).and_return({})
141
141
  @mock_repository.should_receive(:modify_object).with(hash_including(:pid => 'pid'))
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubydora
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
5
- prerelease:
4
+ hash: 17
5
+ prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 6
10
- version: 0.0.6
9
+ - 7
10
+ version: 0.0.7
11
11
  platform: ruby
12
12
  authors:
13
13
  - Chris Beer
@@ -15,12 +15,14 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-04-22 00:00:00 -04:00
18
+ date: 2011-05-12 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
22
  type: :runtime
23
- requirement: &id001 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ name: fastercsv
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
24
26
  none: false
25
27
  requirements:
26
28
  - - ">="
@@ -29,12 +31,12 @@ dependencies:
29
31
  segments:
30
32
  - 0
31
33
  version: "0"
32
- name: fastercsv
33
- version_requirements: *id001
34
- prerelease: false
34
+ requirement: *id001
35
35
  - !ruby/object:Gem::Dependency
36
36
  type: :runtime
37
- requirement: &id002 !ruby/object:Gem::Requirement
37
+ prerelease: false
38
+ name: rest-client
39
+ version_requirements: &id002 !ruby/object:Gem::Requirement
38
40
  none: false
39
41
  requirements:
40
42
  - - ">="
@@ -43,12 +45,12 @@ dependencies:
43
45
  segments:
44
46
  - 0
45
47
  version: "0"
46
- name: rest-client
47
- version_requirements: *id002
48
- prerelease: false
48
+ requirement: *id002
49
49
  - !ruby/object:Gem::Dependency
50
50
  type: :runtime
51
- requirement: &id003 !ruby/object:Gem::Requirement
51
+ prerelease: false
52
+ name: nokogiri
53
+ version_requirements: &id003 !ruby/object:Gem::Requirement
52
54
  none: false
53
55
  requirements:
54
56
  - - ">="
@@ -57,12 +59,12 @@ dependencies:
57
59
  segments:
58
60
  - 0
59
61
  version: "0"
60
- name: nokogiri
61
- version_requirements: *id003
62
- prerelease: false
62
+ requirement: *id003
63
63
  - !ruby/object:Gem::Dependency
64
64
  type: :runtime
65
- requirement: &id004 !ruby/object:Gem::Requirement
65
+ prerelease: false
66
+ name: mime-types
67
+ version_requirements: &id004 !ruby/object:Gem::Requirement
66
68
  none: false
67
69
  requirements:
68
70
  - - ">="
@@ -71,12 +73,42 @@ dependencies:
71
73
  segments:
72
74
  - 0
73
75
  version: "0"
74
- name: mime-types
75
- version_requirements: *id004
76
+ requirement: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ type: :runtime
76
79
  prerelease: false
80
+ name: activesupport
81
+ version_requirements: &id005 !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ hash: 7
87
+ segments:
88
+ - 3
89
+ - 0
90
+ version: "3.0"
91
+ requirement: *id005
92
+ - !ruby/object:Gem::Dependency
93
+ type: :runtime
94
+ prerelease: false
95
+ name: activemodel
96
+ version_requirements: &id006 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 7
102
+ segments:
103
+ - 3
104
+ - 0
105
+ version: "3.0"
106
+ requirement: *id006
77
107
  - !ruby/object:Gem::Dependency
78
108
  type: :development
79
- requirement: &id005 !ruby/object:Gem::Requirement
109
+ prerelease: false
110
+ name: shoulda
111
+ version_requirements: &id007 !ruby/object:Gem::Requirement
80
112
  none: false
81
113
  requirements:
82
114
  - - ">="
@@ -85,12 +117,12 @@ dependencies:
85
117
  segments:
86
118
  - 0
87
119
  version: "0"
88
- name: shoulda
89
- version_requirements: *id005
90
- prerelease: false
120
+ requirement: *id007
91
121
  - !ruby/object:Gem::Dependency
92
122
  type: :development
93
- requirement: &id006 !ruby/object:Gem::Requirement
123
+ prerelease: false
124
+ name: bundler
125
+ version_requirements: &id008 !ruby/object:Gem::Requirement
94
126
  none: false
95
127
  requirements:
96
128
  - - ~>
@@ -101,12 +133,12 @@ dependencies:
101
133
  - 0
102
134
  - 0
103
135
  version: 1.0.0
104
- name: bundler
105
- version_requirements: *id006
106
- prerelease: false
136
+ requirement: *id008
107
137
  - !ruby/object:Gem::Dependency
108
138
  type: :development
109
- requirement: &id007 !ruby/object:Gem::Requirement
139
+ prerelease: false
140
+ name: jeweler
141
+ version_requirements: &id009 !ruby/object:Gem::Requirement
110
142
  none: false
111
143
  requirements:
112
144
  - - ~>
@@ -117,12 +149,12 @@ dependencies:
117
149
  - 5
118
150
  - 1
119
151
  version: 1.5.1
120
- name: jeweler
121
- version_requirements: *id007
122
- prerelease: false
152
+ requirement: *id009
123
153
  - !ruby/object:Gem::Dependency
124
154
  type: :development
125
- requirement: &id008 !ruby/object:Gem::Requirement
155
+ prerelease: false
156
+ name: rcov
157
+ version_requirements: &id010 !ruby/object:Gem::Requirement
126
158
  none: false
127
159
  requirements:
128
160
  - - ">="
@@ -131,12 +163,12 @@ dependencies:
131
163
  segments:
132
164
  - 0
133
165
  version: "0"
134
- name: rcov
135
- version_requirements: *id008
136
- prerelease: false
166
+ requirement: *id010
137
167
  - !ruby/object:Gem::Dependency
138
168
  type: :development
139
- requirement: &id009 !ruby/object:Gem::Requirement
169
+ prerelease: false
170
+ name: rspec
171
+ version_requirements: &id011 !ruby/object:Gem::Requirement
140
172
  none: false
141
173
  requirements:
142
174
  - - ">="
@@ -145,12 +177,12 @@ dependencies:
145
177
  segments:
146
178
  - 0
147
179
  version: "0"
148
- name: rspec
149
- version_requirements: *id009
150
- prerelease: false
180
+ requirement: *id011
151
181
  - !ruby/object:Gem::Dependency
152
182
  type: :development
153
- requirement: &id010 !ruby/object:Gem::Requirement
183
+ prerelease: false
184
+ name: yard
185
+ version_requirements: &id012 !ruby/object:Gem::Requirement
154
186
  none: false
155
187
  requirements:
156
188
  - - ">="
@@ -159,9 +191,7 @@ dependencies:
159
191
  segments:
160
192
  - 0
161
193
  version: "0"
162
- name: yard
163
- version_requirements: *id010
164
- prerelease: false
194
+ requirement: *id012
165
195
  description: "Fedora Commons REST API ruby library : REQUIRES FCREPO 3.4+"
166
196
  email: chris@cbeer.info
167
197
  executables: []
@@ -235,7 +265,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
235
265
  requirements: []
236
266
 
237
267
  rubyforge_project:
238
- rubygems_version: 1.5.3
268
+ rubygems_version: 1.3.7
239
269
  signing_key:
240
270
  specification_version: 3
241
271
  summary: Fedora Commons REST API ruby library