ezid-client 1.3.0 → 1.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 141f157b6169fdedba53b58d11e0b9c1b26c7662
4
- data.tar.gz: ef0923245729d7f20e079f3581d7647bc7cb5581
3
+ metadata.gz: f2baebf2aca4cada19d44f70e2e6614ad9e206ea
4
+ data.tar.gz: 1cbc73e6739a91a88d2cd3a7f5698d8dab1bfa3a
5
5
  SHA512:
6
- metadata.gz: 16b22cbb1ba43ab241036710cfb044f66b365dd434a783a31a1370743e063517a530df12b2f72c24c0f3575dabdb8045e49fa673fc01306621d46fe2a8a88683
7
- data.tar.gz: f329532cc4d162575b0c3c14a76d8b7ca253963486686e73565ec4f31debd1c498f5804034f2713badac901b0875d7a27eba322a488bd6ef48f073b01246ce70
6
+ metadata.gz: 042582d5276928c9444bf60eb1d1ed851795d072145c2e33e13d8a08d25be121bb797992ed941a2e1eba5cae1a9f980d26c24196f4ffa59edbf9a3d1d5a46161
7
+ data.tar.gz: f6be1c6c06c59f8aec88b78664927aa0fbd8c92d090f920ad5c4c9edf99202c397f6a8444b2210da12c1f5c1ebc7240401286dc09fb447b7ef9f9ee65cccc414
data/README.md CHANGED
@@ -27,17 +27,17 @@ Or install it yourself as:
27
27
 
28
28
  [Mint an identifier on a shoulder](http://ezid.cdlib.org/doc/apidoc.html#operation-mint-identifier)
29
29
 
30
+ *Added in v1.4.0:* `Ezid::Identifier.mint` class method.
31
+
30
32
  ```
31
- >> identifier = Ezid::Identifier.create(shoulder: "ark:/99999/fk4")
32
- I, [2014-12-04T15:06:02.428445 #86655] INFO -- : EZID MintIdentifier -- success: ark:/99999/fk4rx9d523
33
- I, [2014-12-04T15:06:03.249793 #86655] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk4rx9d523
34
- => #<Ezid::Identifier id="ark:/99999/fk4rx9d523" status="public" target="http://ezid.cdlib.org/id/ark:/99999/fk4rx9d523" created="2014-12-04 20:06:02 UTC">
35
- >> identifier.id
36
- => "ark:/99999/fk4rx9d523"
33
+ >> identifier = Ezid::Identifier.mint("ark:/99999/fk4")
34
+ I, [2016-03-01T22:20:08.505323 #35148] INFO -- : EZID MintIdentifier -- success: ark:/99999/fk4tq65d6k
35
+ => #<Ezid::Identifier id=ark:/99999/fk4tq65d6k>
37
36
  >> identifier.status
37
+ I, [2016-03-01T22:20:22.323650 #35148] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk4tq65d6k
38
38
  => "public"
39
39
  >> identifier.target
40
- => "http://ezid.cdlib.org/id/ark:/99999/fk4rx9d523"
40
+ => "http://ezid.cdlib.org/id/ark:/99999/fk4tq65d6k"
41
41
  ```
42
42
 
43
43
  A default shoulder can be configured:
@@ -59,19 +59,19 @@ end
59
59
  New identifiers will then be minted on the default shoulder when a shoulder is not specified:
60
60
 
61
61
  ```
62
- >> identifier = Ezid::Identifier.create
62
+ >> identifier = Ezid::Identifier.mint
63
63
  I, [2014-12-09T11:22:34.499860 #32279] INFO -- : EZID MintIdentifier -- success: ark:/99999/fk43f4wd4v
64
- I, [2014-12-09T11:22:35.317181 #32279] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk43f4wd4v
65
- => #<Ezid::Identifier id="ark:/99999/fk43f4wd4v" status="public" target="http://ezid.cdlib.org/id/ark:/99999/fk43f4wd4v" created="2014-12-09 16:22:35 UTC">
64
+ => #<Ezid::Identifier id="ark:/99999/fk43f4wd4v">
66
65
  ```
67
66
 
68
67
  [Create a specific identifier](http://ezid.cdlib.org/doc/apidoc.html#operation-create-identifier)
69
68
 
69
+ *Changed in v1.4.0:* `Ezid::Identifier.create` now expects the first argument to be the identifier (String) to create; the second optional argument is a hash of metadata elements. Passing the identifier in an `:id` hash option is deprecated and will be removed in v2.0. The `:shoulder` hash option is likewise deprecated; use `Ezid::Identifier.mint(shoulder, metadata)` instead.
70
+
70
71
  ```
71
- >> identifier = Ezid::Identifier.create(id: "ark:/99999/fk4rx9d523/12345")
72
+ >> identifier = Ezid::Identifier.create("ark:/99999/fk4rx9d523/12345")
72
73
  I, [2014-12-09T11:21:42.077297 #32279] INFO -- : EZID CreateIdentifier -- success: ark:/99999/fk4rx9d523/12345
73
- I, [2014-12-09T11:21:42.808534 #32279] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk4rx9d523/12345
74
- => #<Ezid::Identifier id="ark:/99999/fk4rx9d523/12345" status="public" target="http://ezid.cdlib.org/id/ark:/99999/fk4rx9d523/12345" created="2014-12-09 16:21:42 UTC">
74
+ => #<Ezid::Identifier id="ark:/99999/fk4rx9d523/12345">
75
75
  ```
76
76
 
77
77
  **Retrieve** (Get Metadata)
@@ -91,30 +91,34 @@ I, [2014-12-04T15:07:00.648676 #86655] INFO -- : EZID GetIdentifierMetadata --
91
91
  => "http://example.com"
92
92
  >> identifier.save
93
93
  I, [2014-12-09T11:24:26.321801 #32279] INFO -- : EZID ModifyIdentifier -- success: ark:/99999/fk43f4wd4v
94
- I, [2014-12-09T11:24:27.039288 #32279] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk43f4wd4v
95
- => #<Ezid::Identifier id="ark:/99999/fk43f4wd4v" status="public" target="http://example.com" created="2014-12-09 16:22:35 UTC">
94
+ => #<Ezid::Identifier id="ark:/99999/fk43f4wd4v">
96
95
  >> identifier.target
96
+ I, [2014-12-09T11:24:27.039288 #32279] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk43f4wd4v
97
97
  => "http://example.com"
98
98
  ```
99
99
 
100
+ *Added in v1.4.0:* `Ezid::Identifier.modify(id, metadata)` class method. In support of more efficient updating of known identifiers, this method skips the GetIdentifierMetadata request used by `.find`. The operation will raise the `Ezid::IdentifierNotFoundError` if the EZID identifier does not exist.
101
+
100
102
  **Delete**
101
103
 
102
104
  *Identifier status must be "reserved" to delete.* http://ezid.cdlib.org/doc/apidoc.html#operation-delete-identifier
103
105
 
104
106
  ```
105
- >> identifier = Ezid::Identifier.create(shoulder: "ark:/99999/fk4", status: "reserved")
106
- I, [2014-12-04T15:12:39.976930 #86734] INFO -- : EZID MintIdentifier -- success: ark:/99999/fk4n58pc0r
107
- I, [2014-12-04T15:12:40.693256 #86734] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk4n58pc0r
108
- => #<Ezid::Identifier id="ark:/99999/fk4n58pc0r" status="reserved" target="http://ezid.cdlib.org/id/ark:/99999/fk4n58pc0r" created="2014-12-04 20:12:39 UTC">
107
+ >> identifier = Ezid::Identifier.mint("ark:/99999/fk4", status: "reserved")
108
+ I, [2016-03-01T22:26:08.645858 #36701] INFO -- : EZID MintIdentifier -- success: ark:/99999/fk4pz5fm1b
109
+ => #<Ezid::Identifier id=ark:/99999/fk4pz5fm1b>
109
110
  >> identifier.delete
110
- I, [2014-12-04T15:12:48.853964 #86734] INFO -- : EZID DeleteIdentifier -- success: ark:/99999/fk4n58pc0r
111
- => #<Ezid::Identifier id="ark:/99999/fk4n58pc0r" DELETED>
111
+ I, [2016-03-01T22:26:14.829731 #36701] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk4pz5fm1b
112
+ I, [2016-03-01T22:26:15.711390 #36701] INFO -- : EZID DeleteIdentifier -- success: ark:/99999/fk4pz5fm1b
113
+ => #<Ezid::Identifier id=ark:/99999/fk4pz5fm1b [DELETED]>
112
114
  ```
113
115
 
114
116
  ## Batch Download
115
117
 
116
118
  See http://ezid.cdlib.org/doc/apidoc.html#parameters. Repeated values should be given as an array value for the parameter key.
117
119
 
120
+ *Added in v1.3.0:* `Ezid::BatchDownload` class.
121
+
118
122
  ```
119
123
  >> batch = Ezid::BatchDownload.new(:csv)
120
124
  => #<Ezid::BatchDownload format=:csv>
@@ -161,33 +165,6 @@ Notes:
161
165
 
162
166
  Accessors are also implemented for the `crossref`, `datacite`, and `erc` elements as described in the EZID API documentation.
163
167
 
164
- **Setting default metadata values**
165
-
166
- Default metadata values can be set:
167
-
168
- ```ruby
169
- Ezid::Client.configure do |config|
170
- # set multiple defaults with a hash
171
- config.identifier.defaults = {status: "reserved", profile: "dc"}
172
- # or set individual elements
173
- config.identifier.defaults[:status] = "reserved"
174
- config.identifier.defaults[:profile] = "dc"
175
- end
176
- ```
177
-
178
- Then new identifiers will receive the defaults:
179
-
180
- ```
181
- >> identifier = Ezid::Identifier.create(shoulder: "ark:/99999/fk4")
182
- I, [2014-12-09T11:38:37.335136 #32279] INFO -- : EZID MintIdentifier -- success: ark:/99999/fk4zs2w500
183
- I, [2014-12-09T11:38:38.153546 #32279] INFO -- : EZID GetIdentifierMetadata -- success: ark:/99999/fk4zs2w500
184
- => #<Ezid::Identifier id="ark:/99999/fk4zs2w500" status="reserved" target="http://ezid.cdlib.org/id/ark:/99999/fk4zs2w500" created="2014-12-09 16:38:38 UTC">
185
- >> identifier.profile
186
- => "dc"
187
- >> identifier.status
188
- => "reserved"
189
- ```
190
-
191
168
  ## Authentication
192
169
 
193
170
  Credentials can be provided in any -- or a combination -- of these ways:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.0
1
+ 1.4.0
data/ezid-client.gemspec CHANGED
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "bundler", "~> 1.7"
25
25
  spec.add_development_dependency "rake"
26
26
  spec.add_development_dependency "rspec", "~> 3.1"
27
+ spec.add_development_dependency "rspec-its"
27
28
  end
@@ -1,7 +1,6 @@
1
1
  require "hashie"
2
2
  require "net/http"
3
3
  require "uri"
4
- require_relative "reserved_metadata"
5
4
 
6
5
  module Ezid
7
6
  class BatchDownloadError < Error; end
data/lib/ezid/client.rb CHANGED
@@ -6,7 +6,6 @@ require_relative "configuration"
6
6
  require_relative "session"
7
7
  require_relative "metadata"
8
8
  require_relative "identifier"
9
- require_relative "proxy_identifier"
10
9
  require_relative "batch_download"
11
10
 
12
11
  Dir[File.expand_path("../responses/*.rb", __FILE__)].each { |m| require m }
data/lib/ezid/error.rb CHANGED
@@ -1,3 +1,11 @@
1
1
  module Ezid
2
2
  class Error < ::RuntimeError; end
3
+
4
+ # The requested identifier was not found
5
+ class IdentifierNotFoundError < Error; end
6
+
7
+ # The requested action is not allowed
8
+ class NotAllowedError < Error; end
9
+
10
+ class DeletionError < Error; end
3
11
  end
@@ -6,53 +6,111 @@ module Ezid
6
6
  #
7
7
  class Identifier
8
8
 
9
- attr_reader :client
10
- attr_accessor :id, :shoulder, :metadata, :state
11
-
12
- private :state, :state=, :id=
13
-
14
- # Attributes to display on inspect
15
- INSPECT_ATTRS = %w( id status target created ).freeze
9
+ attr_accessor :id, :shoulder, :persisted, :deleted
10
+ private :persisted=, :persisted, :deleted=, :deleted
16
11
 
17
12
  class << self
18
13
  attr_accessor :defaults
19
14
 
20
15
  # Creates or mints an identifier (depending on arguments)
21
16
  # @see #save
17
+ # @overload create(id, metadata=nil)
18
+ # Creates an identifier
19
+ # @param id [String] the identifier to create
20
+ # @param metadata [Hash] the metadata to set on the identifier
21
+ # @overload create(metadata=nil)
22
+ # Mints an identifier
23
+ # @deprecated Use {.mint} instead
24
+ # @param metadata [Hash] the metadata to set on the identifier
25
+ # @return [Ezid::Identifier] the new identifier
26
+ # @raise [Ezid::Error]
27
+ def create(*args)
28
+ raise ArgumentError, "`mint` receives 0-2 arguments." if args.size > 2
29
+ if args.first.is_a?(Hash)
30
+ warn "[DEPRECATION] Sending a hash as the first argument to `create` is deprecated and will raise an exception in 2.0. Use `create(id, metadata)` or `mint(metadata)` instead. (called from #{caller.first})"
31
+ metadata = args.first
32
+ id = metadata.delete(:id)
33
+ else
34
+ id, metadata = args
35
+ end
36
+ if id.nil?
37
+ warn "[DEPRECATION] Calling `create` without an id will raise an exception in 2.0. Use `mint` instead. (called from #{caller.first})"
38
+ shoulder = metadata.delete(:shoulder)
39
+ mint(shoulder, metadata)
40
+ else
41
+ new(id, metadata) { |i| i.save }
42
+ end
43
+ end
44
+
45
+ # Mints a new identifier
46
+ # @overload mint(shoulder, metadata=nil)
47
+ # @param shoulder [String] the EZID shoulder on which to mint
48
+ # @param metadata [Hash] the metadata to set on the identifier
49
+ # @overload mint(metadata=nil)
50
+ # @param metadata [Hash] the metadata to set on the identifier
22
51
  # @return [Ezid::Identifier] the new identifier
23
52
  # @raise [Ezid::Error]
24
- def create(attrs = {})
25
- identifier = new(attrs)
26
- identifier.save
53
+ def mint(*args)
54
+ raise ArgumentError, "`mint` receives 0-2 arguments." if args.size > 2
55
+ metadata = args.last.is_a?(Hash) ? args.pop : nil
56
+ new(metadata) do |i|
57
+ i.shoulder = args.first
58
+ i.save
59
+ end
60
+ end
61
+
62
+ # Modifies the metadata of an existing identifier.
63
+ # @param id [String] the EZID identifier
64
+ # @param metadata [Hash] the metadata to update on the identifier
65
+ # @return [Ezid::Identifier] the identifier
66
+ # @raise [Ezid::IdentifierNotFoundError]
67
+ def modify(id, metadata)
68
+ i = allocate
69
+ i.id = id
70
+ i.update_metadata(metadata)
71
+ i.modify!
27
72
  end
28
73
 
29
74
  # Retrieves an identifier
75
+ # @param id [String] the EZID identifier to find
30
76
  # @return [Ezid::Identifier] the identifier
31
- # @raise [Ezid::Error] if the identifier does not exist in EZID
77
+ # @raise [Ezid::IdentifierNotFoundError] if the identifier does not exist in EZID
32
78
  def find(id)
33
- identifier = new(id: id)
34
- identifier.load_metadata
79
+ i = allocate
80
+ i.id = id
81
+ i.load_metadata
35
82
  end
36
83
  end
37
84
 
38
85
  self.defaults = {}
39
86
 
40
- def initialize(args={})
41
- @client = args.delete(:client) || Client.new
42
- @id = args.delete(:id)
43
- @shoulder = args.delete(:shoulder)
44
- @state = :new
45
- self.metadata = Metadata.new args.delete(:metadata)
46
- update_metadata self.class.defaults.merge(args) # deprecate?
87
+ def initialize(*args)
88
+ raise ArgumentError, "`new` receives 0-2 arguments." if args.size > 2
89
+ data = args.last.is_a?(Hash) ? args.pop : nil
90
+ @id = args.first
91
+ apply_default_metadata
92
+ if data
93
+ if shoulder = data.delete(:shoulder)
94
+ warn "[DEPRECATION] The `:shoulder` hash option is deprecated and will raise an exception in 2.0. Use `Ezid::Identifier.mint(shoulder, metadata)` to mint an identifier. (called by #{caller.first})"
95
+ @shoulder = shoulder
96
+ end
97
+ if anvl = data.delete(:metadata)
98
+ update_metadata(anvl)
99
+ end
100
+ update_metadata(data)
101
+ end
102
+ yield self if block_given?
47
103
  end
48
104
 
49
105
  def inspect
50
- attrs = if deleted?
51
- "id=\"#{id}\" DELETED"
52
- else
53
- INSPECT_ATTRS.map { |attr| "#{attr}=#{send(attr).inspect}" }.join(", ")
54
- end
55
- "#<#{self.class.name} #{attrs}>"
106
+ id_val = if id.nil?
107
+ "NEW"
108
+ elsif deleted?
109
+ "#{id} [DELETED]"
110
+ else
111
+ id
112
+ end
113
+ "#<#{self.class.name} id=#{id_val}>"
56
114
  end
57
115
 
58
116
  def to_s
@@ -60,11 +118,16 @@ module Ezid
60
118
  end
61
119
 
62
120
  # Returns the identifier metadata
63
- # @param load [Boolean] - flag to load the metadata from EZID if stale (default: `true`)
64
121
  # @return [Ezid::Metadata] the metadata
65
- def metadata(load = true)
66
- load_metadata if load && stale?
67
- @metadata
122
+ def metadata(_=nil)
123
+ if !_.nil?
124
+ warn "[DEPRECATION] The parameter of `metadata` is deprecated and will be removed in 2.0. (called from #{caller.first})"
125
+ end
126
+ @metadata ||= Metadata.new
127
+ end
128
+
129
+ def remote_metadata
130
+ @remote_metadata ||= Metadata.new
68
131
  end
69
132
 
70
133
  # Persist the identifer and/or metadata to EZID.
@@ -77,27 +140,41 @@ module Ezid
77
140
  def save
78
141
  raise Error, "Cannot save a deleted identifier." if deleted?
79
142
  persist
80
- reset
143
+ reset_metadata
144
+ self
145
+ end
146
+
147
+ # Force a modification of the EZID identifier -- i.e.,
148
+ # assumes previously persisted without confirmation.
149
+ # @return [Ezid::Identifier] the identifier
150
+ # @raise [Ezid::Error] if `id` is nil
151
+ # @raise [Ezid::IdentifierNotFoundError] if EZID identifier does not exist.
152
+ def modify!
153
+ raise Error, "Cannot modify an identifier without and id." if id.nil?
154
+ modify
155
+ persists!
156
+ reset_metadata
157
+ self
81
158
  end
82
159
 
83
160
  # Updates the metadata
84
161
  # @param attrs [Hash] the metadata
85
162
  # @return [Ezid::Identifier] the identifier
86
163
  def update_metadata(attrs={})
87
- attrs.each { |k, v| send("#{k}=", v) }
164
+ metadata.update(attrs)
88
165
  self
89
166
  end
90
167
 
91
168
  # Is the identifier persisted?
92
169
  # @return [Boolean]
93
170
  def persisted?
94
- state == :persisted
171
+ !!persisted
95
172
  end
96
173
 
97
174
  # Has the identifier been deleted?
98
175
  # @return [Boolean]
99
176
  def deleted?
100
- state == :deleted
177
+ !!deleted
101
178
  end
102
179
 
103
180
  # Updates the metadata and saves the identifier
@@ -111,24 +188,26 @@ module Ezid
111
188
 
112
189
  # @deprecated Use {#load_metadata} instead.
113
190
  def reload
114
- warn "[DEPRECATION] `reload` is deprecated and will be removed in version 2.0. Use `load_metadata` instead."
191
+ warn "[DEPRECATION] `reload` is deprecated and will be removed in version 2.0. Use `load_metadata` instead. (called from #{caller.first})"
115
192
  load_metadata
116
193
  end
117
194
 
118
- # Loads the metadata from EZID (local changes will be lost!)
195
+ # Loads the metadata from EZID
119
196
  # @return [Ezid::Identifier] the identifier
120
197
  # @raise [Ezid::Error]
121
198
  def load_metadata
122
199
  response = client.get_identifier_metadata(id)
123
- self.metadata = Metadata.new(response.metadata)
124
- self.state = :persisted
200
+ # self.remote_metadata = Metadata.new(response.metadata)
201
+ remote_metadata.replace(response.metadata)
202
+ persists!
125
203
  self
126
204
  end
127
205
 
128
206
  # Empties the (local) metadata (changes will be lost!)
129
207
  # @return [Ezid::Identifier] the identifier
130
208
  def reset
131
- clear_metadata
209
+ warn "[DEPRECATION] `reset` is deprecated and will be removed in 2.0. Use `reset_metadata` instead. (called from #{caller.first})"
210
+ reset_metadata
132
211
  self
133
212
  end
134
213
 
@@ -139,8 +218,10 @@ module Ezid
139
218
  def delete
140
219
  raise Error, "Only persisted, reserved identifiers may be deleted: #{inspect}." unless deletable?
141
220
  client.delete_identifier(id)
142
- self.state = :deleted
143
- reset
221
+ reset_metadata
222
+ self.deleted = true
223
+ self.persisted = false
224
+ self
144
225
  end
145
226
 
146
227
  # Is the identifier reserved?
@@ -190,22 +271,32 @@ module Ezid
190
271
  self.status = Status::PUBLIC
191
272
  end
192
273
 
274
+ def client
275
+ @client ||= Client.new
276
+ end
277
+
278
+ def reset_metadata
279
+ metadata.clear unless metadata.empty?
280
+ remote_metadata.clear unless remote_metadata.empty?
281
+ end
282
+
193
283
  protected
194
284
 
195
- def method_missing(method, *args)
196
- metadata.send(method, *args)
285
+ def method_missing(*args)
286
+ local_or_remote_metadata(*args)
197
287
  rescue NoMethodError
198
288
  super
199
289
  end
200
290
 
201
291
  private
202
292
 
203
- def stale?
204
- persisted? && metadata(false).empty?
205
- end
206
-
207
- def clear_metadata
208
- metadata(false).clear
293
+ def local_or_remote_metadata(*args)
294
+ value = metadata.send(*args)
295
+ if value.nil? && persisted?
296
+ load_metadata if remote_metadata.empty?
297
+ value = remote_metadata.send(*args)
298
+ end
299
+ value
209
300
  end
210
301
 
211
302
  def modify
@@ -227,7 +318,15 @@ module Ezid
227
318
 
228
319
  def persist
229
320
  persisted? ? modify : create_or_mint
230
- self.state = :persisted
321
+ persists!
322
+ end
323
+
324
+ def persists!
325
+ self.persisted = true
326
+ end
327
+
328
+ def apply_default_metadata
329
+ update_metadata(self.class.defaults)
231
330
  end
232
331
 
233
332
  end